Merge 'aosp/idea133' into 'aosp/master'

Get stabilization fixes into the refactoring branch.

Change-Id: I7b6896c342f0a1127627e754c77b8f22b56d7953
diff --git a/INSTALL b/INSTALL
index c9d178a..88e0f2c 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,119 +1,3 @@
 This package contains the sources to the Android emulator program.
 
-Supported Development Platforms:
---------------------------------
-
-The Android emulator can be built on the following platforms:
-
-    - Linux 32-bits
-    - Linux 64-bits (*only* generates 32-bit emulator binary)
-    - Darwin x86
-    - Darwin ppc  (experimental only)
-    - Windows x86  (through Cygwin only)
-
-Note that development on 64-bit versions of Darwin and Windows is
-not supported. The 32-bit emulator binary should run normally on
-these platforms though.
-
-The Windows emulator binary is built using the -no-cygwin option
-and thus doesn't depend on CYGWIN.DLL being installed on your system.
-
-It is possible to hack the android-configure.sh script to build
-a 64-bit emulator binary on Linux. Unfortunately the resulting
-program will crash pretty soon during emulation. This problem is
-due to the way the emulator works and cannot be easily fixed at
-the moment.
-
-Supported Compilers:
---------------------
-
-The Android emulator is a heavy fork of QEMU 0.8.2, and as such,
-can only be built properly with a small number of compilers. Moreover,
-which compiler can be used depends on your platform.
-
-The following table sums up the compilers that are *known* to produce
-correct output:
-
-  Linux x86:              gcc-3.4.6
-  Linux x86 and x86_64:   gcc-4.2.3
-  Darwin x86:             gcc-4.0.1 (build 5341)
-  Darwin ppc:             gcc-3.3   (build 1819)
-
-Use any other compiler at your own risks ! A 'bad binary' usually
-results in the VM crashing either immediately or after a few seconds.
-
-Note that on Darwin, the *build* number of your compiler *is* important.
-Some builds of gcc-4.0.1 are known to generate bad binaries on Darwin x86,
-so your own fails to build an executable that works correctly.
-You can find the sources to the required gcc here:
-
-
-We distribute a file named distrib/build_gcc_qemu_darwin.sh which can be
-used as a replacement for the Apple-provided build_gcc.sh that comes with
-their gcc distribution.
-
-
-Building the emulator with the Android build system:
-----------------------------------------------------
-
-Ensure that you have properly configured your build by running the
-envsetup.sh script and using the appropriate 'lunch' command.
-
-Then type: 
-
-     m emulator
-
-This will rebuild the emulator and place it in an adequate location.
-Simply type 'emulator' to start it with the currently built system
-image.
-
-
-Building the emulator without the Android build system:
--------------------------------------------------------
-
-You can also build the emulator as a stand-alone program, by following
-these simple steps:
-
-  1/ First, build Android's patched libSDL as a static library,
-     this can be done as:
-
-        cd $TOP/external/qemu/distrib/sdl-1.2.15
-        ./android-configure --prefix=<PATH>
-        make
-        make install
-
-    Where $TOP is the path of your open-source Android source tree, and
-    where <PATH> is any path of your chosing where the library will
-    be copied to by the 'make install' command. For example, you
-    can use $HOME/android-sdl
-
-  2/ Configure the emulator with android-configure.sh, as in:
-
-        cd $TOP/external/qemu
-        ./android-configure.sh --sdl-config=<PATH>/bin/sdl-config
-        make
-
-     Where <PATH> is the same path you used with the --prefix option
-     when building the SDL library
-
-The emulator binary is located into objs/emulator, you can strip it and
-copy it to any location of your choosing.
-
-
-Creating an emulator source distribution package:
--------------------------------------------------
-
-We provide a script to build a tar.gz package file that contains all the
-sources required to rebuild the emulator (i.e. it includes the patched SDL
-sources as well) plus a handy script to automate the rebuild.
-
-Simply invoke:
-
-    cd $TOP/tools/qemu
-    distrib/make-distrib.sh
-
-This script will create a tar.gz file under /tmp/android-package and will
-print its location when it completes.
-
-To rebuild the corresponding emulator, un-tar-gz the package, and run
-the 'rebuild.sh' script.
+See docs/DEVELOPMENT.TXT for building instructions.
diff --git a/Makefile.android b/Makefile.android
index a166ccb..7af2b48 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -147,6 +147,10 @@
 
 MY_CFLAGS += -I$(LOCAL_PATH)/include
 
+# Need to include "qapi-types.h" and other auto-generated files from
+# android-configure.sh
+MY_CFLAGS += -I$(LOCAL_PATH)/qapi-auto-generated
+
 # A useful function that can be used to start the declaration of a host
 # module. Avoids repeating the same stuff again and again.
 # Usage:
diff --git a/Makefile.common b/Makefile.common
index 7d49b49..a58bfc0 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -405,16 +405,6 @@
 
 common_LOCAL_CFLAGS += $(GCC_W_NO_MISSING_FIELD_INITIALIZERS)
 
-# migration sources
-#
-ifeq ($(HOST_OS),windows)
-  common_LOCAL_SRC_FILES += migration-dummy-android.c
-else
-  common_LOCAL_SRC_FILES += migration.c \
-                     migration-exec.c \
-                     migration-tcp-android.c
-endif
-
 # misc. sources
 #
 CORE_MISC_SOURCES = \
@@ -422,16 +412,16 @@
     async.c \
     bt-host.c \
     bt-vhci.c \
-    buffered_file.c \
     iohandler.c \
     ioport.c \
+    migration-dummy-android.c \
     qemu-char.c \
-    readline.c \
+    qemu-log.c \
     savevm.c \
     android/boot-properties.c \
     android/cbuffer.c \
     android/charpipe.c \
-    android/config.c \
+    android/config-file.c \
     android/core-init-utils.c   \
     android/gps.c \
     android/hw-kmsg.c \
@@ -461,13 +451,19 @@
     android/utils/jpeg-compress.c \
     net/net-android.c \
     qobject/qerror.c \
+    qom/container.c \
+    qom/object.c \
+    qom/qom-qobject.c \
     ui/console.c \
     ui/d3des.c \
     ui/input.c \
     ui/vnc-android.c \
-    util/acl.c \
     util/aes.c \
+    util/compatfd.c \
     util/cutils.c \
+    util/error.c \
+    util/hexdump.c \
+    util/iov.c \
     util/module.c \
     util/notify.c \
     util/osdep.c \
@@ -476,6 +472,8 @@
     util/qemu-error.c \
     util/qemu-option.c \
     util/qemu-sockets-android.c \
+    util/unicode.c \
+    util/yield-android.c \
 
 ifeq ($(HOST_ARCH),x86)
     CORE_MISC_SOURCES += disas/i386.c
@@ -490,7 +488,7 @@
 
 ifeq ($(HOST_OS),linux)
     CORE_MISC_SOURCES += hw/usb/usb-linux.c \
-                         util/qemu-thread.c \
+                         util/qemu-thread-posix.c \
                          android/camera/camera-capture-linux.c
 else
     CORE_MISC_SOURCES += hw/usb/usb-dummy-android.c
@@ -498,14 +496,16 @@
 
 ifeq ($(HOST_OS),windows)
   CORE_MISC_SOURCES   += tap-win32.c \
-                         android/camera/camera-capture-windows.c
+                         android/camera/camera-capture-windows.c \
+                         util/qemu-thread-win32.c
 
 else
   CORE_MISC_SOURCES   += posix-aio-compat.c
 endif
 
 ifeq ($(HOST_OS),darwin)
-  CORE_MISC_SOURCES   += android/camera/camera-capture-mac.m
+  CORE_MISC_SOURCES   += android/camera/camera-capture-mac.m \
+                         util/qemu-thread-posix.c
 endif
 
 common_LOCAL_SRC_FILES += $(CORE_MISC_SOURCES)
@@ -642,9 +642,6 @@
     block/qcow2-refcount.c \
     block/qcow2-snapshot.c \
     block/qcow2-cluster.c \
-    block/cloop.c \
-    block/dmg.c \
-    block/vvfat.c \
     block/raw.c
 
 ifeq ($(HOST_OS),windows)
diff --git a/Makefile.target b/Makefile.target
index ad7a936..43e0d9c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -167,9 +167,11 @@
 common_LOCAL_SRC_FILES += \
     backends/msmouse.c \
     cpu-exec.c  \
+    cputlb.c \
     exec.c \
+    main-loop.c \
+    monitor-android.c \
     translate-all.c \
-    android/trace.c \
     android/varint.c \
     softmmu_outside_jit.c
 
@@ -325,9 +327,8 @@
     disas.c \
     dma-helpers.c \
     gdbstub.c \
-    monitor.c \
     qemu-timer.c \
-    qemu-timer-common.c \
+    log-rotate-android.c \
     vl-android.c \
     android/cmdline-option.c \
     android/console.c \
@@ -342,6 +343,8 @@
     android/user-events-qemu.c \
     hw/core/loader.c \
     ui/keymaps.c \
+    util/qemu-timer-common.c \
+    util/iov.c \
 
 
 # The following files cannot be in static libraries because they contain
@@ -375,7 +378,6 @@
 LOCAL_LDLIBS += $(common_LOCAL_LDLIBS)
 LOCAL_CFLAGS += $(common_LOCAL_CFLAGS)
 LOCAL_SRC_FILES += $(common_LOCAL_SRC_FILES)
-$(call gen-hx-header,qemu-monitor.hx,qemu-monitor.h,monitor.c)
 $(call gen-hx-header,qemu-options.hx,qemu-options.def,vl-android.c qemu-options.h)
 $(call gen-hw-config-defs)
 
@@ -400,7 +402,6 @@
   LOCAL_LDLIBS += $(common_LOCAL_LDLIBS) -m64
   LOCAL_CFLAGS += $(common_LOCAL_CFLAGS) -m64
   LOCAL_SRC_FILES += $(common_LOCAL_SRC_FILES)
-  $(call gen-hx-header,qemu-monitor.hx,qemu-monitor.h,monitor.c)
   $(call gen-hx-header,qemu-options.hx,qemu-options.def,vl-android.c qemu-options.h)
   $(call gen-hw-config-defs)
   $(call end-emulator-program)
diff --git a/README b/README
index dfd56f2..951380e 100644
--- a/README
+++ b/README
@@ -1,3 +1,8 @@
-Read the documentation in qemu-doc.html.
+This directory contains the sources of the Android emulator,
+a QEMU-based program to emulate virtual devices running various
+releases of the Android platform image.
 
-Fabrice Bellard.
+See the docs/ directory for more documentation about this
+code base and the platforms it emulates.
+
+If you plan to contribute patches, please read docs/DEVELOPMENT.TXT
\ No newline at end of file
diff --git a/android-configure.sh b/android-configure.sh
index ad77bd2..ecfe86a 100755
--- a/android-configure.sh
+++ b/android-configure.sh
@@ -599,7 +599,7 @@
     echo "HOST_OS   := windows" >> $config_mk
 fi
 
-if [ "$GLES_INCLUDE" -a "$GLES_LIBS" ]; then
+if [ "$GLES_SUPPORT" = "yes" -a "$GLES_INCLUDE" -a "$GLES_LIBS" ]; then
     echo "QEMU_OPENGLES_INCLUDE    := $GLES_INCLUDE" >> $config_mk
     echo "QEMU_OPENGLES_LIBS       := $GLES_LIBS"    >> $config_mk
 fi
@@ -723,12 +723,29 @@
     echo "#define MAP_ANONYMOUS    MAP_ANON" >> $config_h
 fi
 
+case "$TARGET_OS" in
+    linux-*)
+        echo "#define CONFIG_SIGNALFD       1" >> $config_h
+        ;;
+esac
+
 echo "#define CONFIG_ANDROID       1" >> $config_h
 
-if [ "$GLES_INCLUDE" -a "$GLES_LIBS" ]; then
+if [ "$GLES_SUPPORT" = "yes" ]; then
     echo "#define CONFIG_ANDROID_OPENGLES 1" >> $config_h
 fi
 
 log "Generate   : $config_h"
 
+# Generate the QAPI headers and sources from qapi-schema.json
+# Ideally, this would be done in our Makefiles, but as far as I
+# understand, the platform build doesn't support a single tool
+# that generates several sources files, nor the standalone one.
+export PYTHONDONTWRITEBYTECODE=1
+AUTOGENERATED_DIR=qapi-auto-generated
+python scripts/qapi-types.py qapi.types --output-dir=$AUTOGENERATED_DIR -b < qapi-schema.json
+python scripts/qapi-visit.py --output-dir=$AUTOGENERATED_DIR -b < qapi-schema.json
+python scripts/qapi-commands.py --output-dir=$AUTOGENERATED_DIR -m < qapi-schema.json
+log "Generate   : $AUTOGENERATED_DIR"
+
 echo "Ready to go. Type 'make' to build emulator"
diff --git a/android/boot-properties.c b/android/boot-properties.c
index acdeed9..c2b30b8 100644
--- a/android/boot-properties.c
+++ b/android/boot-properties.c
@@ -175,7 +175,7 @@
     if (split == NULL) {
         D("%s: save failed: illegal key/value pair \"%s\" (missing '=')\n",
           __FUNCTION__, p->property);
-        qemu_file_set_error(f);
+        qemu_file_set_error(f, -EINVAL);
         return -1;
     }
 
diff --git a/android/config.c b/android/config-file.c
similarity index 99%
rename from android/config.c
rename to android/config-file.c
index 4f4da46..8e55f4e 100644
--- a/android/config.c
+++ b/android/config-file.c
@@ -16,7 +16,7 @@
 #include <unistd.h>
 #include <errno.h>
 
-#include "android/config.h"
+#include "android/config-file.h"
 #include "android/utils/eintr_wrapper.h"
 #include "android/utils/path.h"
 
diff --git a/android/config.h b/android/config-file.h
similarity index 95%
rename from android/config.h
rename to android/config-file.h
index 5e8b048..0dad046 100644
--- a/android/config.h
+++ b/android/config-file.h
@@ -9,8 +9,8 @@
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 */
-#ifndef ANDROID_CONFIG_H
-#define ANDROID_CONFIG_H
+#ifndef ANDROID_CONFIG_FILE_H
+#define ANDROID_CONFIG_FILE_H
 
 /** ANDROID CONFIGURATION FILE SUPPORT
  **
@@ -54,4 +54,4 @@
 extern int          aconfig_int     (AConfig *root, const char *name, int _default);
 extern const char*  aconfig_str     (AConfig *root, const char *name, const char *_default);
 
-#endif /* ANDROID_CONFIG_H */
+#endif /* ANDROID_CONFIG_FILE_H */
diff --git a/android/config/config.h b/android/config/config.h
index 35cc9da..8d34bb1 100644
--- a/android/config/config.h
+++ b/android/config/config.h
@@ -7,7 +7,6 @@
 #include "config-host.h"
 
 #define TARGET_PHYS_ADDR_BITS  32
-#define CONFIG_TRACE 1
 #define CONFIG_NAND 1
 #define CONFIG_SHAPER 1
 #define CONFIG_SOFTMMU 1
diff --git a/android/config/darwin-x86/config-host.h b/android/config/darwin-x86/config-host.h
index d5e8507..1731340 100644
--- a/android/config/darwin-x86/config-host.h
+++ b/android/config/darwin-x86/config-host.h
@@ -14,7 +14,6 @@
 #define CONFIG_GDBSTUB  1
 #define CONFIG_SLIRP    1
 #define CONFIG_SKINS    1
-#define CONFIG_TRACE    1
 #define CONFIG_NAND_LIMITS  1
 #define QEMU_VERSION    "0.10.50"
 #define QEMU_PKGVERSION "Android"
diff --git a/android/config/darwin-x86_64/config-host.h b/android/config/darwin-x86_64/config-host.h
index f66a35d..cc60aae 100644
--- a/android/config/darwin-x86_64/config-host.h
+++ b/android/config/darwin-x86_64/config-host.h
@@ -16,7 +16,6 @@
 #define CONFIG_GDBSTUB  1
 #define CONFIG_SLIRP    1
 #define CONFIG_SKINS    1
-#define CONFIG_TRACE    1
 #define CONFIG_POSIX  1
 #define CONFIG_MADVISE  1
 #define CONFIG_NAND_LIMITS  1
diff --git a/android/config/linux-ppc/config-host.h b/android/config/linux-ppc/config-host.h
index 9faf170..f87ef47 100644
--- a/android/config/linux-ppc/config-host.h
+++ b/android/config/linux-ppc/config-host.h
@@ -6,7 +6,6 @@
 #define CONFIG_GDBSTUB  1
 #define CONFIG_SLIRP    1
 #define CONFIG_SKINS    1
-#define CONFIG_TRACE    1
 #define CONFIG_FDATASYNC    1
 #define CONFIG_NAND_LIMITS  1
 #define QEMU_VERSION    "0.10.50"
diff --git a/android/config/linux-x86/config-host.h b/android/config/linux-x86/config-host.h
index d9f04fa..fa29b96 100644
--- a/android/config/linux-x86/config-host.h
+++ b/android/config/linux-x86/config-host.h
@@ -15,7 +15,6 @@
 #define CONFIG_GDBSTUB  1
 #define CONFIG_SLIRP    1
 #define CONFIG_SKINS    1
-#define CONFIG_TRACE    1
 #define CONFIG_FDATASYNC    1
 #define CONFIG_NAND_LIMITS  1
 #define QEMU_VERSION    "0.10.50"
@@ -24,6 +23,7 @@
 #define CONFIG_IOVEC 1
 #define CONFIG_LINUX   1
 #define CONFIG_POSIX 1
+#define CONFIG_SIGNALFD 1
 #define CONFIG_ANDROID       1
 #define CONFIG_MADVISE 1
 #define CONFIG_ANDROID_OPENGLES 1
diff --git a/android/config/windows/config-host.h b/android/config/windows/config-host.h
index 2d2fdc6..fdae7e0 100644
--- a/android/config/windows/config-host.h
+++ b/android/config/windows/config-host.h
@@ -13,7 +13,6 @@
 #define CONFIG_GDBSTUB  1
 #define CONFIG_SLIRP    1
 #define CONFIG_SKINS    1
-#define CONFIG_TRACE    1
 #define QEMU_VERSION    "0.10.50"
 #define QEMU_PKGVERSION "Android"
 #define CONFIG_WIN32   1
diff --git a/android/console.c b/android/console.c
index a6b2239..dc55646 100644
--- a/android/console.c
+++ b/android/console.c
@@ -214,18 +214,6 @@
 
 static void  control_client_read( void*  _client );  /* forward */
 
-/* Reattach a control client to a given socket.
- * Return the old socket descriptor for the client.
- */
-static int
-control_client_reattach( ControlClient client, int fd )
-{
-    int result = control_client_detach(client);
-    client->sock = fd;
-    qemu_set_fd_handler( fd, control_client_read, NULL, client );
-    return result;
-}
-
 static void
 control_client_destroy( ControlClient  client )
 {
@@ -2654,26 +2642,8 @@
 static int
 do_qemu_monitor( ControlClient client, char* args )
 {
-    char             socketname[32];
-    int              fd;
-    CharDriverState* cs;
-
-    if (args != NULL) {
-        control_write( client, "KO: no argument for 'qemu monitor'\r\n" );
-        return -1;
-    }
-    /* Detach the client socket, and re-attach it to a monitor */
-    fd = control_client_detach(client);
-    snprintf(socketname, sizeof socketname, "tcp:socket=%d", fd);
-    cs = qemu_chr_open("monitor", socketname, NULL);
-    if (cs == NULL) {
-        control_client_reattach(client, fd);
-        control_write( client, "KO: internal error: could not detach from console !\r\n" );
-        return -1;
-    }
-    monitor_init(cs, MONITOR_USE_READLINE|MONITOR_QUIT_DOESNT_EXIT);
-    control_client_destroy(client);
-    return 0;
+    control_write(client, "KO: QEMU support no longer available\r\n");
+    return -1;
 }
 
 #ifdef CONFIG_STANDALONE_CORE
diff --git a/android/main-common.h b/android/main-common.h
index 0d184d5..523e441 100644
--- a/android/main-common.h
+++ b/android/main-common.h
@@ -15,7 +15,7 @@
 #include <stdint.h>
 #include "android/cmdline-option.h"
 #include "android/skin/keyset.h"
-#include "android/config.h"
+#include "android/config-file.h"
 #include "android/avd/hw-config.h"
 
 /* Common routines used by both android/main.c and android/main-ui.c */
diff --git a/android/main.c b/android/main.c
index e0797d9..2189dfa 100644
--- a/android/main.c
+++ b/android/main.c
@@ -18,6 +18,7 @@
 #include <process.h>
 #endif
 
+#include "config.h"
 #include "android/sockets.h"
 
 #include "android/android.h"
@@ -33,7 +34,7 @@
 
 #include "android/charmap.h"
 #include "android/utils/debug.h"
-#include "android/config.h"
+#include "android/config-file.h"
 #include "android/config/config.h"
 
 #include "android/user-config.h"
@@ -78,11 +79,6 @@
  */
 #define  DEFAULT_DEVICE_DPI  165
 
-#ifdef CONFIG_TRACE
-extern void  start_tracing(void);
-extern void  stop_tracing(void);
-#endif
-
 int qemu_main(int argc, char **argv);
 
 /* this function dumps the QEMU help */
diff --git a/android/protocol/core-commands-qemu.c b/android/protocol/core-commands-qemu.c
index 0b662c5..d26840c 100644
--- a/android/protocol/core-commands-qemu.c
+++ b/android/protocol/core-commands-qemu.c
@@ -19,7 +19,6 @@
 #include "android/globals.h"
 #include "android/hw-sensors.h"
 #include "telephony/modem_driver.h"
-#include "android/trace.h"
 #include "audio/audio.h"
 #include "android/protocol/core-commands-api.h"
 
@@ -48,11 +47,6 @@
 
 int corecmd_trace_control(int start)
 {
-    if (start) {
-        start_tracing();
-    } else {
-        stop_tracing();
-    }
     return 0;
 }
 
diff --git a/android/qemulator.c b/android/qemulator.c
index b625be6..ffd547b 100644
--- a/android/qemulator.c
+++ b/android/qemulator.c
@@ -363,9 +363,6 @@
         { SKIN_KEY_COMMAND_NONE, 0 }
     };
     int          nn;
-#ifdef CONFIG_TRACE
-    static int   tracing = 0;
-#endif
     QEmulator*   emulator = opaque;
 
 
@@ -408,15 +405,6 @@
         }
         break;
 
-    case SKIN_KEY_COMMAND_TOGGLE_TRACING:
-        {
-#ifdef CONFIG_TRACE
-            tracing = !tracing;
-            corecmd_trace_control(tracing);
-#endif
-        }
-        break;
-
     case SKIN_KEY_COMMAND_TOGGLE_TRACKBALL:
         emulator->show_trackball = !emulator->show_trackball;
         skin_window_show_trackball( emulator->window, emulator->show_trackball );
diff --git a/android/qemulator.h b/android/qemulator.h
index bd77ae1..16cafcf 100644
--- a/android/qemulator.h
+++ b/android/qemulator.h
@@ -13,7 +13,7 @@
 #ifndef QEMU_ANDROID_QEMULATOR_H
 #define QEMU_ANDROID_QEMULATOR_H
 
-#include "android/config.h"
+#include "android/config-file.h"
 #include "android/skin/file.h"
 #include "android/skin/keyboard.h"
 #include "android/skin/window.h"
diff --git a/android/skin/file.h b/android/skin/file.h
index 21922e6..ab6a3ec 100644
--- a/android/skin/file.h
+++ b/android/skin/file.h
@@ -13,7 +13,7 @@
 #define _ANDROID_SKIN_FILE_H
 
 #include "android/skin/image.h"
-#include "android/config.h"
+#include "android/config-file.h"
 #include "android/framebuffer.h"
 
 /**  Layout
diff --git a/android/skin/keyboard.h b/android/skin/keyboard.h
index 1c3b088..62e1869 100644
--- a/android/skin/keyboard.h
+++ b/android/skin/keyboard.h
@@ -13,7 +13,7 @@
 #define _ANDROID_SKIN_KEYBOARD_H
 
 #include "android/charmap.h"
-#include "android/config.h"
+#include "android/config-file.h"
 #include "android/skin/image.h"  /* for SkinRotation */
 #include "android/skin/keyset.h"
 #include <SDL.h>
diff --git a/android/skin/keyset.h b/android/skin/keyset.h
index 81eb2e7..7cdcaab 100644
--- a/android/skin/keyset.h
+++ b/android/skin/keyset.h
@@ -12,7 +12,7 @@
 #ifndef _ANDROID_SKIN_KEYSET_H_
 #define _ANDROID_SKIN_KEYSET_H_
 
-#include "android/config.h"
+#include "android/config-file.h"
 
 /* A SkinKeySet maps keystrokes to specific commands. we have a few hard-coded
  * keysets in the emulator binary, and the user can define its own if he wants
diff --git a/android/snaphost-android.h b/android/snaphost-android.h
index ae558ba..0211b50 100644
--- a/android/snaphost-android.h
+++ b/android/snaphost-android.h
@@ -13,6 +13,8 @@
 #ifndef _ANDROID_SNAPHOST_ANDROID_H_
 #define _ANDROID_SNAPHOST_ANDROID_H_
 
+#include "android/utils/ini.h"
+
 /* Matches HW config saved for a VM snapshot against the current HW config.
  * Param:
  *  hw_ini - IniFile instance containing the current HW config settings.
diff --git a/android/sockets.c b/android/sockets.c
index 697501e..4b8796d 100644
--- a/android/sockets.c
+++ b/android/sockets.c
@@ -1167,6 +1167,14 @@
     return socket_setoption(fd, SOL_SOCKET, SO_OOBINLINE, 1);
 }
 
+int socket_set_cork(int fd, int v)
+{
+#if defined(SOL_TCP) && defined(TCP_CORK)
+    return socket_setoption(fd, SOL_TCP, TCP_CORK, v);
+#else
+    return 0;
+#endif
+}
 
 int  socket_set_nodelay(int  fd)
 {
@@ -1566,3 +1574,24 @@
     else
         return buf;
 }
+
+
+// Temporary work-arounds until we get rid of this source file.
+
+int qemu_getsockopt(int sock, int level, int optname, void* optval,
+                    size_t* optlen) {
+    socklen_t len = (socklen_t) *optlen;
+    int ret = getsockopt(sock, level, optname, (char*)optval, &len);
+    *optlen = (size_t) len;
+    return ret;
+}
+
+int qemu_setsockopt(int sock, int level, int optname, const void* optval,
+                    size_t optlen) {
+  return setsockopt(sock, level, optname, (const char*)optval,
+                    (socklen_t)optlen);
+}
+
+int qemu_recv(int sock, void* buf, size_t len, int flags) {
+  return recv(sock, buf, len, flags);
+}
diff --git a/android/trace.c b/android/trace.c
deleted file mode 100644
index 006582e..0000000
--- a/android/trace.c
+++ /dev/null
@@ -1,1981 +0,0 @@
-/* Copyright (C) 2006-2007 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** 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.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <time.h>
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "android/trace.h"
-#include "varint.h"
-#include "android/utils/path.h"
-
-// For tracing dynamic execution of basic blocks
-typedef struct TraceBB {
-    char        *filename;
-    FILE        *fstream;
-    BBRec       buffer[kMaxNumBasicBlocks];
-    BBRec       *next;          // points to next record in buffer
-    uint64_t    flush_time;     // time of last buffer flush
-    char        compressed[kCompressedSize];
-    char        *compressed_ptr;
-    char        *high_water_ptr;
-    int64_t     prev_bb_num;
-    uint64_t    prev_bb_time;
-    uint64_t    current_bb_num;
-    uint64_t    current_bb_start_time;
-    uint64_t    recnum;         // counts number of trace records
-    uint32_t    current_bb_addr;
-    int         num_insns;
-} TraceBB;
-
-// For tracing simuation start times of instructions
-typedef struct TraceInsn {
-    char        *filename;
-    FILE        *fstream;
-    InsnRec     dummy;          // this is here so we can use buffer[-1]
-    InsnRec     buffer[kInsnBufferSize];
-    InsnRec     *current;
-    uint64_t    prev_time;      // time of last instruction start
-    char        compressed[kCompressedSize];
-    char        *compressed_ptr;
-    char        *high_water_ptr;
-} TraceInsn;
-
-// For tracing the static information about a basic block
-typedef struct TraceStatic {
-    char        *filename;
-    FILE        *fstream;
-    uint32_t    insns[kMaxInsnPerBB];
-    int         next_insn;
-    uint64_t    bb_num;
-    uint32_t    bb_addr;
-    int         is_thumb;
-} TraceStatic;
-
-// For tracing load and store addresses
-typedef struct TraceAddr {
-    char        *filename;
-    FILE        *fstream;
-    AddrRec     buffer[kMaxNumAddrs];
-    AddrRec     *next;
-    char        compressed[kCompressedSize];
-    char        *compressed_ptr;
-    char        *high_water_ptr;
-    uint32_t    prev_addr;
-    uint64_t    prev_time;
-} TraceAddr;
-
-// For tracing exceptions
-typedef struct TraceExc {
-    char        *filename;
-    FILE        *fstream;
-    char        compressed[kCompressedSize];
-    char        *compressed_ptr;
-    char        *high_water_ptr;
-    uint64_t    prev_time;
-    uint64_t    prev_bb_recnum;
-} TraceExc;
-
-// For tracing process id changes
-typedef struct TracePid {
-    char        *filename;
-    FILE        *fstream;
-    char        compressed[kCompressedSize];
-    char        *compressed_ptr;
-    uint64_t    prev_time;
-} TracePid;
-
-// For tracing Dalvik VM method enter and exit
-typedef struct TraceMethod {
-    char        *filename;
-    FILE        *fstream;
-    char        compressed[kCompressedSize];
-    char        *compressed_ptr;
-    uint64_t    prev_time;
-    uint32_t    prev_addr;
-    int32_t     prev_pid;
-} TraceMethod;
-
-extern TraceBB trace_bb;
-extern TraceInsn trace_insn;
-extern TraceStatic trace_static;
-extern TraceAddr trace_load;
-extern TraceAddr trace_store;
-extern TraceExc trace_exc;
-extern TracePid trace_pid;
-extern TraceMethod trace_method;
-
-TraceBB trace_bb;
-TraceInsn trace_insn;
-TraceStatic trace_static;
-TraceAddr trace_load;
-TraceAddr trace_store;
-TraceExc trace_exc;
-TracePid trace_pid;
-TraceMethod trace_method;
-static TraceHeader header;
-
-const char *trace_filename;
-int tracing;
-int trace_cache_miss;
-int trace_all_addr;
-
-// The simulation time in cpu clock cycles
-uint64_t sim_time = 1;
-
-// The current process id
-int current_pid;
-
-// The start and end (wall-clock) time in microseconds
-uint64_t start_time, end_time;
-uint64_t elapsed_usecs;
-
-// For debugging output
-FILE *ftrace_debug;
-
-// The maximum number of bytes consumed by an InsnRec after compression.
-// This is very conservative but needed to ensure no buffer overflows.
-#define kMaxInsnCompressed 14
-
-// The maximum number of bytes consumed by an BBRec after compression.
-// This is very conservative but needed to ensure no buffer overflows.
-#define kMaxBBCompressed 32
-
-// The maximum number of bytes consumed by an AddrRec after compression.
-// This is very conservative but needed to ensure no buffer overflows.
-#define kMaxAddrCompressed 14
-
-// The maximum number of bytes consumed by a MethodRec after compression.
-// This is very conservative but needed to ensure no buffer overflows.
-#define kMaxMethodCompressed 18
-
-// The maximum number of bytes consumed by an exception record after
-// compression.
-#define kMaxExcCompressed 38
-
-// The maximum number of bytes consumed by a pid record for
-// kPidSwitch, or kPidExit after compression.
-#define kMaxPidCompressed 15
-
-// The maximum number of bytes consumed by a pid record for kPidFork,
-// or kPidClone after compression.
-#define kMaxPid2Compressed 20
-
-// The maximum number of bytes consumed by a pid record for kPidExecArgs
-// after compression, not counting the bytes for the args.
-#define kMaxExecArgsCompressed 15
-
-// The maximum number of bytes consumed by a pid record for kPidName
-// after compression, not counting the bytes for the name.
-#define kMaxNameCompressed 20
-
-// The maximum number of bytes consumed by a pid record for kPidMmap
-// after compression, not counting the bytes for the pathname.
-#define kMaxMmapCompressed 33
-
-// The maximum number of bytes consumed by a pid record for kPidMunmap,
-// after compression.
-#define kMaxMunmapCompressed 28
-
-// The maximum number of bytes consumed by a pid record for kPidSymbol
-// after compression, not counting the bytes for the symbol name.
-#define kMaxSymbolCompressed 24
-
-// The maximum number of bytes consumed by a pid record for kPidKthreadName
-// after compression, not counting the bytes for the name.
-#define kMaxKthreadNameCompressed 25
-
-void trace_cleanup();
-
-// Return current time in microseconds as a 64-bit integer.
-uint64 Now() {
-    struct timeval        tv;
-
-    gettimeofday(&tv, NULL);
-    uint64 val = tv.tv_sec;
-    val = val * 1000000ull + tv.tv_usec;
-    return val;
-}
-
-static void create_trace_dir(const char *dirname)
-{
-    int err;
-
-    err = path_mkdir(dirname, 0755);
-    if (err != 0 && errno != EEXIST) {
-        printf("err: %d\n", err);
-        perror(dirname);
-        exit(1);
-    }
-}
-
-static char *create_trace_path(const char *filename, const char *ext)
-{
-    char *fname;
-    const char *base_start, *base_end;
-    int ii, len, base_len, dir_len, path_len, qtrace_len;
-
-    // Handle error cases
-    if (filename == NULL || *filename == 0 || strcmp(filename, "/") == 0)
-        return NULL;
-
-    // Ignore a trailing slash, if any
-    len = strlen(filename);
-    if (filename[len - 1] == '/')
-        len -= 1;
-
-    // Find the basename.  We don't use basename(3) because there are
-    // different behaviors for GNU and Posix in the case where the
-    // last character is a slash.
-    base_start = base_end = &filename[len];
-    for (ii = 0; ii < len; ++ii) {
-        base_start -= 1;
-        if (*base_start == '/') {
-            base_start += 1;
-            break;
-        }
-    }
-    base_len = base_end - base_start;
-    dir_len = len - base_len;
-    qtrace_len = strlen("/qtrace");
-
-    // Create space for the pathname: "/dir/basename/qtrace.ext"
-    // The "ext" string already contains the dot, so just add a byte
-    // for the terminating zero.
-    path_len = dir_len + base_len + qtrace_len + strlen(ext) + 1;
-    fname = malloc(path_len);
-    if (dir_len > 0)
-        strncpy(fname, filename, dir_len);
-    fname[dir_len] = 0;
-    strncat(fname, base_start, base_len);
-    strcat(fname, "/qtrace");
-    strcat(fname, ext);
-    return fname;
-}
-
-void convert_secs_to_date_time(time_t secs, uint32_t *pdate, uint32_t *ptime)
-{
-    struct tm *tm = localtime(&secs);
-    uint32_t year = tm->tm_year + 1900;
-    uint32_t thousands = year / 1000;
-    year -= thousands * 1000;
-    uint32_t hundreds = year / 100;
-    year -= hundreds * 100;
-    uint32_t tens = year / 10;
-    year -= tens * 10;
-    uint32_t ones = year;
-    year = (thousands << 12) | (hundreds << 8) | (tens << 4) | ones;
-
-    uint32_t mon = tm->tm_mon + 1;
-    tens = mon / 10;
-    ones = (mon - tens * 10);
-    mon = (tens << 4) | ones;
-
-    uint32_t day = tm->tm_mday;
-    tens = day / 10;
-    ones = (day - tens * 10);
-    day = (tens << 4) | ones;
-
-    *pdate = (year << 16) | (mon << 8) | day;
-
-    uint32_t hour = tm->tm_hour;
-    tens = hour / 10;
-    ones = (hour - tens * 10);
-    hour = (tens << 4) | ones;
-
-    uint32_t min = tm->tm_min;
-    tens = min / 10;
-    ones = (min - tens * 10);
-    min = (tens << 4) | ones;
-
-    uint32_t sec = tm->tm_sec;
-    tens = sec / 10;
-    ones = (sec - tens * 10);
-    sec = (tens << 4) | ones;
-
-    *ptime = (hour << 16) | (min << 8) | sec;
-}
-
-void write_trace_header(TraceHeader *header)
-{
-    TraceHeader swappedHeader;
-
-    memcpy(&swappedHeader, header, sizeof(TraceHeader));
-
-    convert32(swappedHeader.version);
-    convert32(swappedHeader.start_sec);
-    convert32(swappedHeader.start_usec);
-    convert32(swappedHeader.pdate);
-    convert32(swappedHeader.ptime);
-    convert32(swappedHeader.num_used_pids);
-    convert32(swappedHeader.first_unused_pid);
-    convert64(swappedHeader.num_static_bb);
-    convert64(swappedHeader.num_static_insn);
-    convert64(swappedHeader.num_dynamic_bb);
-    convert64(swappedHeader.num_dynamic_insn);
-    convert64(swappedHeader.elapsed_usecs);
-
-    fwrite(&swappedHeader, sizeof(TraceHeader), 1, trace_static.fstream);
-}
-
-void create_trace_bb(const char *filename)
-{
-    char *fname = create_trace_path(filename, ".bb");
-    trace_bb.filename = fname;
-
-    FILE *fstream = fopen(fname, "wb");
-    if (fstream == NULL) {
-        perror(fname);
-        exit(1);
-    }
-    trace_bb.fstream = fstream;
-    trace_bb.next = &trace_bb.buffer[0];
-    trace_bb.flush_time = 0;
-    trace_bb.compressed_ptr = trace_bb.compressed;
-    trace_bb.high_water_ptr = &trace_bb.compressed[kCompressedSize] - kMaxBBCompressed;
-    trace_bb.prev_bb_num = 0;
-    trace_bb.prev_bb_time = 0;
-    trace_bb.num_insns = 0;
-    trace_bb.recnum = 0;
-}
-
-void create_trace_insn(const char *filename)
-{
-    // Create the instruction time trace file
-    char *fname = create_trace_path(filename, ".insn");
-    trace_insn.filename = fname;
-
-    FILE *fstream = fopen(fname, "wb");
-    if (fstream == NULL) {
-        perror(fname);
-        exit(1);
-    }
-    trace_insn.fstream = fstream;
-    trace_insn.current = &trace_insn.dummy;
-    trace_insn.dummy.time_diff = 0;
-    trace_insn.dummy.repeat = 0;
-    trace_insn.prev_time = 0;
-    trace_insn.compressed_ptr = trace_insn.compressed;
-    trace_insn.high_water_ptr = &trace_insn.compressed[kCompressedSize] - kMaxInsnCompressed;
-}
-
-void create_trace_static(const char *filename)
-{
-    // Create the static basic block trace file
-    char *fname = create_trace_path(filename, ".static");
-    trace_static.filename = fname;
-
-    FILE *fstream = fopen(fname, "wb");
-    if (fstream == NULL) {
-        perror(fname);
-        exit(1);
-    }
-    trace_static.fstream = fstream;
-    trace_static.next_insn = 0;
-    trace_static.bb_num = 1;
-    trace_static.bb_addr = 0;
-
-    // Write an empty header to reserve space for it in the file.
-    // The header will be filled in later when post-processing the
-    // trace file.
-    memset(&header, 0, sizeof(TraceHeader));
-
-    // Write out the version number so that tools can detect if the trace
-    // file format is the same as what they expect.
-    header.version = TRACE_VERSION;
-
-    // Record the start time in the header now.
-    struct timeval tv;
-    struct timezone tz;
-    gettimeofday(&tv, &tz);
-    header.start_sec = tv.tv_sec;
-    header.start_usec = tv.tv_usec;
-    convert_secs_to_date_time(header.start_sec, &header.pdate, &header.ptime);
-    write_trace_header(&header);
-
-    // Write out the record for the unused basic block number 0.
-    uint64_t zero = 0;
-    fwrite(&zero, sizeof(uint64_t), 1, trace_static.fstream);	// bb_num
-    fwrite(&zero, sizeof(uint32_t), 1, trace_static.fstream);	// bb_addr
-    fwrite(&zero, sizeof(uint32_t), 1, trace_static.fstream);	// num_insns
-}
-
-void create_trace_addr(const char *filename)
-{
-    // The "qtrace.load" and "qtrace.store" files are optional
-    trace_load.fstream = NULL;
-    trace_store.fstream = NULL;
-    if (trace_all_addr || trace_cache_miss) {
-        // Create the "qtrace.load" file
-        char *fname = create_trace_path(filename, ".load");
-        trace_load.filename = fname;
-
-        FILE *fstream = fopen(fname, "wb");
-        if (fstream == NULL) {
-            perror(fname);
-            exit(1);
-        }
-        trace_load.fstream = fstream;
-        trace_load.next = &trace_load.buffer[0];
-        trace_load.compressed_ptr = trace_load.compressed;
-        trace_load.high_water_ptr = &trace_load.compressed[kCompressedSize] - kMaxAddrCompressed;
-        trace_load.prev_addr = 0;
-        trace_load.prev_time = 0;
-
-        // Create the "qtrace.store" file
-        fname = create_trace_path(filename, ".store");
-        trace_store.filename = fname;
-
-        fstream = fopen(fname, "wb");
-        if (fstream == NULL) {
-            perror(fname);
-            exit(1);
-        }
-        trace_store.fstream = fstream;
-        trace_store.next = &trace_store.buffer[0];
-        trace_store.compressed_ptr = trace_store.compressed;
-        trace_store.high_water_ptr = &trace_store.compressed[kCompressedSize] - kMaxAddrCompressed;
-        trace_store.prev_addr = 0;
-        trace_store.prev_time = 0;
-    }
-}
-
-void create_trace_exc(const char *filename)
-{
-    // Create the exception trace file
-    char *fname = create_trace_path(filename, ".exc");
-    trace_exc.filename = fname;
-
-    FILE *fstream = fopen(fname, "wb");
-    if (fstream == NULL) {
-        perror(fname);
-        exit(1);
-    }
-    trace_exc.fstream = fstream;
-    trace_exc.compressed_ptr = trace_exc.compressed;
-    trace_exc.high_water_ptr = &trace_exc.compressed[kCompressedSize] - kMaxExcCompressed;
-    trace_exc.prev_time = 0;
-    trace_exc.prev_bb_recnum = 0;
-}
-
-void create_trace_pid(const char *filename)
-{
-    // Create the pid trace file
-    char *fname = create_trace_path(filename, ".pid");
-    trace_pid.filename = fname;
-
-    FILE *fstream = fopen(fname, "wb");
-    if (fstream == NULL) {
-        perror(fname);
-        exit(1);
-    }
-    trace_pid.fstream = fstream;
-    trace_pid.compressed_ptr = trace_pid.compressed;
-    trace_pid.prev_time = 0;
-}
-
-void create_trace_method(const char *filename)
-{
-    // Create the method trace file
-    char *fname = create_trace_path(filename, ".method");
-    trace_method.filename = fname;
-
-    FILE *fstream = fopen(fname, "wb");
-    if (fstream == NULL) {
-        perror(fname);
-        exit(1);
-    }
-    trace_method.fstream = fstream;
-    trace_method.compressed_ptr = trace_method.compressed;
-    trace_method.prev_time = 0;
-    trace_method.prev_addr = 0;
-    trace_method.prev_pid = 0;
-}
-
-void trace_init(const char *filename)
-{
-    // Create the trace files
-    create_trace_dir(filename);
-    create_trace_bb(filename);
-    create_trace_insn(filename);
-    create_trace_static(filename);
-    create_trace_addr(filename);
-    create_trace_exc(filename);
-    create_trace_pid(filename);
-    create_trace_method(filename);
-
-#if 0
-    char *fname = create_trace_path(filename, ".debug");
-    ftrace_debug = fopen(fname, "wb");
-    if (ftrace_debug == NULL) {
-        perror(fname);
-        exit(1);
-    }
-#else
-    ftrace_debug = NULL;
-#endif
-    atexit(trace_cleanup);
-
-    // If tracing is on, then start timing the simulator
-    if (tracing)
-        start_time = Now();
-}
-
-/* the following array is used to deal with def-use register interlocks, which we
- * can compute statically (ignoring conditions), very fortunately.
- *
- * the idea is that interlock_base contains the number of cycles "executed" from
- * the start of a basic block. It is set to 0 in trace_bb_start, and incremented
- * in each call to get_insn_ticks_arm.
- *
- * interlocks[N] correspond to the value of interlock_base after which a register N
- * can be used by another operation, it is set each time an instruction writes to
- * the register in get_insn_ticks()
- */
-
-static int   interlocks[16];
-static int   interlock_base;
-
-static void
-_interlock_def(int  reg, int  delay)
-{
-    if (reg >= 0)
-        interlocks[reg] = interlock_base + delay;
-}
-
-static int
-_interlock_use(int  reg)
-{
-    int  delay = 0;
-
-    if (reg >= 0)
-    {
-        delay = interlocks[reg] - interlock_base;
-        if (delay < 0)
-            delay = 0;
-    }
-    return delay;
-}
-
-void trace_bb_start(uint32_t bb_addr)
-{
-    int  nn;
-
-    trace_static.bb_addr = bb_addr;
-    trace_static.is_thumb = 0;
-
-    interlock_base = 0;
-    for (nn = 0; nn < 16; nn++)
-        interlocks[nn] = 0;
-}
-
-void trace_add_insn(uint32_t insn, int is_thumb)
-{
-    trace_static.insns[trace_static.next_insn++] = insn;
-    // This relies on the fact that a basic block does not contain a mix
-    // of ARM and Thumb instructions.  If that is not true, then many
-    // software tools that read the trace will have to change.
-    trace_static.is_thumb = is_thumb;
-}
-
-void trace_bb_end()
-{
-    int		ii, num_insns;
-    uint32_t	insn;
-
-    uint64_t bb_num = hostToLE64(trace_static.bb_num);
-    // If these are Thumb instructions, then encode that fact by setting
-    // the low bit of the basic-block address to 1.
-    uint32_t bb_addr = trace_static.bb_addr | trace_static.is_thumb;
-    bb_addr = hostToLE32(bb_addr);
-    num_insns = hostToLE32(trace_static.next_insn);
-    fwrite(&bb_num, sizeof(bb_num), 1, trace_static.fstream);
-    fwrite(&bb_addr, sizeof(bb_addr), 1, trace_static.fstream);
-    fwrite(&num_insns, sizeof(num_insns), 1, trace_static.fstream);
-    for (ii = 0; ii < trace_static.next_insn; ++ii) {
-        insn = hostToLE32(trace_static.insns[ii]);
-        fwrite(&insn, sizeof(insn), 1, trace_static.fstream);
-    }
-
-    trace_static.bb_num += 1;
-    trace_static.next_insn = 0;
-}
-
-void trace_cleanup()
-{
-    if (tracing) {
-        end_time = Now();
-        elapsed_usecs += end_time - start_time;
-    }
-    header.elapsed_usecs = elapsed_usecs;
-    double elapsed_secs = elapsed_usecs / 1000000.0;
-    double cycles_per_sec = 0;
-    if (elapsed_secs != 0)
-        cycles_per_sec = sim_time / elapsed_secs;
-    char *suffix = "";
-    if (cycles_per_sec >= 1000000) {
-        cycles_per_sec /= 1000000.0;
-        suffix = "M";
-    } else if (cycles_per_sec > 1000) {
-        cycles_per_sec /= 1000.0;
-        suffix = "K";
-    }
-    printf("Elapsed seconds: %.2f, simulated cycles/sec: %.1f%s\n",
-           elapsed_secs, cycles_per_sec, suffix);
-    if (trace_bb.fstream) {
-        BBRec *ptr;
-        BBRec *next = trace_bb.next;
-        char *comp_ptr = trace_bb.compressed_ptr;
-        int64_t prev_bb_num = trace_bb.prev_bb_num;
-        uint64_t prev_bb_time = trace_bb.prev_bb_time;
-        for (ptr = trace_bb.buffer; ptr != next; ++ptr) {
-            if (comp_ptr >= trace_bb.high_water_ptr) {
-                uint32_t size = comp_ptr - trace_bb.compressed;
-                fwrite(trace_bb.compressed, sizeof(char), size,
-                       trace_bb.fstream);
-                comp_ptr = trace_bb.compressed;
-            }
-            int64_t bb_diff = ptr->bb_num - prev_bb_num;
-            prev_bb_num = ptr->bb_num;
-            uint64_t time_diff = ptr->start_time - prev_bb_time;
-            prev_bb_time = ptr->start_time;
-            comp_ptr = varint_encode_signed(bb_diff, comp_ptr);
-            comp_ptr = varint_encode(time_diff, comp_ptr);
-            comp_ptr = varint_encode(ptr->repeat, comp_ptr);
-            if (ptr->repeat)
-                comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
-        }
-
-        // Add an extra record at the end containing the ending simulation
-        // time and a basic block number of 0.
-        uint64_t time_diff = sim_time - prev_bb_time;
-        if (time_diff > 0) {
-            int64_t bb_diff = -prev_bb_num;
-            comp_ptr = varint_encode_signed(bb_diff, comp_ptr);
-            comp_ptr = varint_encode(time_diff, comp_ptr);
-            comp_ptr = varint_encode(0, comp_ptr);
-        }
-
-        uint32_t size = comp_ptr - trace_bb.compressed;
-        if (size)
-            fwrite(trace_bb.compressed, sizeof(char), size, trace_bb.fstream);
-
-        // Terminate the file with three zeros so that we can detect
-        // the end of file quickly.
-        uint32_t zeros = 0;
-        fwrite(&zeros, 3, 1, trace_bb.fstream);
-        fclose(trace_bb.fstream);
-    }
-
-    if (trace_insn.fstream) {
-        InsnRec *ptr;
-        InsnRec *current = trace_insn.current + 1;
-        char *comp_ptr = trace_insn.compressed_ptr;
-        for (ptr = trace_insn.buffer; ptr != current; ++ptr) {
-            if (comp_ptr >= trace_insn.high_water_ptr) {
-                uint32_t size = comp_ptr - trace_insn.compressed;
-                uint32_t rval = fwrite(trace_insn.compressed, sizeof(char),
-                                       size, trace_insn.fstream);
-                if (rval != size) {
-                    fprintf(stderr, "fwrite() failed\n");
-                    perror(trace_insn.filename);
-                    exit(1);
-                }
-                comp_ptr = trace_insn.compressed;
-            }
-            comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
-            comp_ptr = varint_encode(ptr->repeat, comp_ptr);
-        }
-
-        uint32_t size = comp_ptr - trace_insn.compressed;
-        if (size) {
-            uint32_t rval = fwrite(trace_insn.compressed, sizeof(char), size,
-                                   trace_insn.fstream);
-            if (rval != size) {
-                fprintf(stderr, "fwrite() failed\n");
-                perror(trace_insn.filename);
-                exit(1);
-            }
-        }
-        fclose(trace_insn.fstream);
-    }
-
-    if (trace_static.fstream) {
-        fseek(trace_static.fstream, 0, SEEK_SET);
-        write_trace_header(&header);
-        fclose(trace_static.fstream);
-    }
-
-    if (trace_load.fstream) {
-        AddrRec *ptr;
-        char *comp_ptr = trace_load.compressed_ptr;
-        AddrRec *next = trace_load.next;
-        uint32_t prev_addr = trace_load.prev_addr;
-        uint64_t prev_time = trace_load.prev_time;
-        for (ptr = trace_load.buffer; ptr != next; ++ptr) {
-            if (comp_ptr >= trace_load.high_water_ptr) {
-                uint32_t size = comp_ptr - trace_load.compressed;
-                fwrite(trace_load.compressed, sizeof(char), size,
-                       trace_load.fstream);
-                comp_ptr = trace_load.compressed;
-            }
-
-            int addr_diff = ptr->addr - prev_addr;
-            uint64_t time_diff = ptr->time - prev_time;
-            prev_addr = ptr->addr;
-            prev_time = ptr->time;
-
-            comp_ptr = varint_encode_signed(addr_diff, comp_ptr);
-            comp_ptr = varint_encode(time_diff, comp_ptr);
-        }
-
-        uint32_t size = comp_ptr - trace_load.compressed;
-        if (size) {
-            fwrite(trace_load.compressed, sizeof(char), size,
-                   trace_load.fstream);
-        }
-
-        // Terminate the file with two zeros so that we can detect
-        // the end of file quickly.
-        uint32_t zeros = 0;
-        fwrite(&zeros, 2, 1, trace_load.fstream);
-        fclose(trace_load.fstream);
-    }
-
-    if (trace_store.fstream) {
-        AddrRec *ptr;
-        char *comp_ptr = trace_store.compressed_ptr;
-        AddrRec *next = trace_store.next;
-        uint32_t prev_addr = trace_store.prev_addr;
-        uint64_t prev_time = trace_store.prev_time;
-        for (ptr = trace_store.buffer; ptr != next; ++ptr) {
-            if (comp_ptr >= trace_store.high_water_ptr) {
-                uint32_t size = comp_ptr - trace_store.compressed;
-                fwrite(trace_store.compressed, sizeof(char), size,
-                       trace_store.fstream);
-                comp_ptr = trace_store.compressed;
-            }
-
-            int addr_diff = ptr->addr - prev_addr;
-            uint64_t time_diff = ptr->time - prev_time;
-            prev_addr = ptr->addr;
-            prev_time = ptr->time;
-
-            comp_ptr = varint_encode_signed(addr_diff, comp_ptr);
-            comp_ptr = varint_encode(time_diff, comp_ptr);
-        }
-
-        uint32_t size = comp_ptr - trace_store.compressed;
-        if (size) {
-            fwrite(trace_store.compressed, sizeof(char), size,
-                   trace_store.fstream);
-        }
-
-        // Terminate the file with two zeros so that we can detect
-        // the end of file quickly.
-        uint32_t zeros = 0;
-        fwrite(&zeros, 2, 1, trace_store.fstream);
-        fclose(trace_store.fstream);
-    }
-
-    if (trace_exc.fstream) {
-        uint32_t size = trace_exc.compressed_ptr - trace_exc.compressed;
-        if (size) {
-            fwrite(trace_exc.compressed, sizeof(char), size,
-                   trace_exc.fstream);
-        }
-
-        // Terminate the file with 7 zeros so that we can detect
-        // the end of file quickly.
-        uint64_t zeros = 0;
-        fwrite(&zeros, 7, 1, trace_exc.fstream);
-        fclose(trace_exc.fstream);
-    }
-    if (trace_pid.fstream) {
-        uint32_t size = trace_pid.compressed_ptr - trace_pid.compressed;
-        if (size) {
-            fwrite(trace_pid.compressed, sizeof(char), size,
-                   trace_pid.fstream);
-        }
-
-        // Terminate the file with 2 zeros so that we can detect
-        // the end of file quickly.
-        uint64_t zeros = 0;
-        fwrite(&zeros, 2, 1, trace_pid.fstream);
-        fclose(trace_pid.fstream);
-    }
-    if (trace_method.fstream) {
-        uint32_t size = trace_method.compressed_ptr - trace_method.compressed;
-        if (size) {
-            fwrite(trace_method.compressed, sizeof(char), size,
-                   trace_method.fstream);
-        }
-
-        // Terminate the file with 2 zeros so that we can detect
-        // the end of file quickly.
-        uint64_t zeros = 0;
-        fwrite(&zeros, 2, 1, trace_method.fstream);
-        fclose(trace_method.fstream);
-    }
-    if (ftrace_debug)
-        fclose(ftrace_debug);
-}
-
-// Define the number of clock ticks for some instructions.  Add one to these
-// (in some cases) if there is an interlock.  We currently do not check for
-// interlocks.
-#define TICKS_OTHER	1
-#define TICKS_SMULxy	1
-#define TICKS_SMLAWy	1
-#define TICKS_SMLALxy	2
-#define TICKS_MUL	2
-#define TICKS_MLA	2
-#define TICKS_MULS	4	// no interlock penalty
-#define TICKS_MLAS	4	// no interlock penalty
-#define TICKS_UMULL	3
-#define TICKS_UMLAL	3
-#define TICKS_SMULL	3
-#define TICKS_SMLAL	3
-#define TICKS_UMULLS	5	// no interlock penalty
-#define TICKS_UMLALS	5	// no interlock penalty
-#define TICKS_SMULLS	5	// no interlock penalty
-#define TICKS_SMLALS	5	// no interlock penalty
-
-// Compute the number of cycles that this instruction will take,
-// not including any I-cache or D-cache misses.  This function
-// is called for each instruction in a basic block when that
-// block is being translated.
-int get_insn_ticks_arm(uint32_t insn)
-{
-#if 1
-    int   result   =  1;   /* by default, use 1 cycle */
-
-    /* See Chapter 12 of the ARM920T Reference Manual for details about clock cycles */
-
-    /* first check for invalid condition codes */
-    if ((insn >> 28) == 0xf)
-    {
-        if ((insn >> 25) == 0x7d) {  /* BLX */
-            result = 3;
-            goto Exit;
-        }
-        /* XXX: if we get there, we're either in an UNDEFINED instruction     */
-        /*      or in co-processor related ones. For now, only return 1 cycle */
-        goto Exit;
-    }
-
-    /* other cases */
-    switch ((insn >> 25) & 7)
-    {
-        case 0:
-            if ((insn & 0x00000090) == 0x00000090)  /* Multiplies, extra load/store, Table 3-2 */
-            {
-                /* XXX: TODO: Add support for multiplier operand content penalties in the translator */
-
-                if ((insn & 0x0fc000f0) == 0x00000090)   /* 3-2: Multiply (accumulate) */
-                {
-                    int  Rm = (insn & 15);
-                    int  Rs = (insn >> 8) & 15;
-                    int  Rn = (insn >> 12) & 15;
-
-                    if ((insn & 0x00200000) != 0) {  /* MLA */
-                        result += _interlock_use(Rn);
-                    } else {   /* MLU */
-                        if (Rn != 0)      /* UNDEFINED */
-                            goto Exit;
-                    }
-                    /* cycles=2+m, assume m=1, this should be adjusted at interpretation time */
-                    result += 2 + _interlock_use(Rm) + _interlock_use(Rs);
-                }
-                else if ((insn & 0x0f8000f0) == 0x00800090)  /* 3-2: Multiply (accumulate) long */
-                {
-                    int  Rm   = (insn & 15);
-                    int  Rs   = (insn >> 8) & 15;
-                    int  RdLo = (insn >> 12) & 15;
-                    int  RdHi = (insn >> 16) & 15;
-
-                    if ((insn & 0x00200000) != 0) { /* SMLAL & UMLAL */
-                        result += _interlock_use(RdLo) + _interlock_use(RdHi);
-                    }
-                    /* else SMLL and UMLL */
-
-                    /* cucles=3+m, assume m=1, this should be adjusted at interpretation time */
-                    result += 3 + _interlock_use(Rm) + _interlock_use(Rs);
-                }
-                else if ((insn & 0x0fd00ff0) == 0x01000090)  /* 3-2: Swap/swap byte */
-                {
-                    int  Rm = (insn & 15);
-                    int  Rd = (insn >> 8) & 15;
-
-                    result = 2 + _interlock_use(Rm);
-                    _interlock_def(Rd, result+1);
-                }
-                else if ((insn & 0x0e400ff0) == 0x00000090)  /* 3-2: load/store halfword, reg offset */
-                {
-                    int  Rm = (insn & 15);
-                    int  Rd = (insn >> 12) & 15;
-                    int  Rn = (insn >> 16) & 15;
-
-                    result += _interlock_use(Rn) + _interlock_use(Rm);
-                    if ((insn & 0x00100000) != 0)  /* it's a load, there's a 2-cycle interlock */
-                        _interlock_def(Rd, result+2);
-                }
-                else if ((insn & 0x0e400ff0) == 0x00400090)  /* 3-2: load/store halfword, imm offset */
-                {
-                    int  Rd = (insn >> 12) & 15;
-                    int  Rn = (insn >> 16) & 15;
-
-                    result += _interlock_use(Rn);
-                    if ((insn & 0x00100000) != 0)  /* it's a load, there's a 2-cycle interlock */
-                        _interlock_def(Rd, result+2);
-                }
-                else if ((insn & 0x0e500fd0) == 0x000000d0) /* 3-2: load/store two words, reg offset */
-                {
-                    /* XXX: TODO: Enhanced DSP instructions */
-                }
-                else if ((insn & 0x0e500fd0) == 0x001000d0) /* 3-2: load/store half/byte, reg offset */
-                {
-                    int  Rm = (insn & 15);
-                    int  Rd = (insn >> 12) & 15;
-                    int  Rn = (insn >> 16) & 15;
-
-                    result += _interlock_use(Rn) + _interlock_use(Rm);
-                    if ((insn & 0x00100000) != 0)  /* load, 2-cycle interlock */
-                        _interlock_def(Rd, result+2);
-                }
-                else if ((insn & 0x0e5000d0) == 0x004000d0) /* 3-2: load/store two words, imm offset */
-                {
-                    /* XXX: TODO: Enhanced DSP instructions */
-                }
-                else if ((insn & 0x0e5000d0) == 0x005000d0) /* 3-2: load/store half/byte, imm offset */
-                {
-                    int  Rd = (insn >> 12) & 15;
-                    int  Rn = (insn >> 16) & 15;
-
-                    result += _interlock_use(Rn);
-                    if ((insn & 0x00100000) != 0)  /* load, 2-cycle interlock */
-                        _interlock_def(Rd, result+2);
-                }
-                else
-                {
-                    /* UNDEFINED */
-                }
-            }
-            else if ((insn & 0x0f900000) == 0x01000000)  /* Misc. instructions, table 3-3 */
-            {
-                switch ((insn >> 4) & 15)
-                {
-                    case 0:
-                        if ((insn & 0x0fb0fff0) == 0x0120f000) /* move register to status register */
-                        {
-                            int  Rm = (insn & 15);
-                            result += _interlock_use(Rm);
-                        }
-                        break;
-
-                    case 1:
-                        if ( ((insn & 0x0ffffff0) == 0x01200010) ||  /* branch/exchange */
-                             ((insn & 0x0fff0ff0) == 0x01600010) )   /* count leading zeroes */
-                        {
-                            int  Rm = (insn & 15);
-                            result += _interlock_use(Rm);
-                        }
-                        break;
-
-                    case 3:
-                        if ((insn & 0x0ffffff0) == 0x01200030)   /* link/exchange */
-                        {
-                            int  Rm = (insn & 15);
-                            result += _interlock_use(Rm);
-                        }
-                        break;
-
-                    default:
-                        /* TODO: Enhanced DSP instructions */
-                        ;
-                }
-            }
-            else  /* Data processing */
-            {
-                int  Rm = (insn & 15);
-                int  Rn = (insn >> 16) & 15;
-
-                result += _interlock_use(Rn) + _interlock_use(Rm);
-                if ((insn & 0x10)) {   /* register-controlled shift => 1 cycle penalty */
-                    int  Rs = (insn >> 8) & 15;
-                    result += 1 + _interlock_use(Rs);
-                }
-            }
-            break;
-
-        case 1:
-            if ((insn & 0x01900000) == 0x01900000)
-            {
-                /* either UNDEFINED or move immediate to CPSR */
-            }
-            else  /* Data processing immediate */
-            {
-                int  Rn = (insn >> 12) & 15;
-                result += _interlock_use(Rn);
-            }
-            break;
-
-        case 2:  /* load/store immediate */
-            {
-                int  Rn = (insn >> 16) & 15;
-
-                result += _interlock_use(Rn);
-                if (insn & 0x00100000) {  /* LDR */
-                    int  Rd = (insn >> 12) & 15;
-
-                    if (Rd == 15)  /* loading PC */
-                        result = 5;
-                    else
-                        _interlock_def(Rd,result+1);
-                }
-            }
-            break;
-
-        case 3:
-            if ((insn & 0x10) == 0)  /* load/store register offset */
-            {
-                int  Rm = (insn & 15);
-                int  Rn = (insn >> 16) & 15;
-
-                result += _interlock_use(Rm) + _interlock_use(Rn);
-
-                if (insn & 0x00100000) {  /* LDR */
-                    int  Rd = (insn >> 12) & 15;
-                    if (Rd == 15)
-                        result = 5;
-                    else
-                        _interlock_def(Rd,result+1);
-                }
-            }
-            /* else UNDEFINED */
-            break;
-
-        case 4:  /* load/store multiple */
-            {
-                int       Rn   = (insn >> 16) & 15;
-                uint32_t  mask = (insn & 0xffff);
-                int       count;
-
-                for (count = 0; mask; count++)
-                    mask &= (mask-1);
-
-                result += _interlock_use(Rn);
-
-                if (insn & 0x00100000)  /* LDM */
-                {
-                    int  nn;
-
-                    if (insn & 0x8000) {  /* loading PC */
-                        result = count+4;
-                    } else {  /* not loading PC */
-                        result = (count < 2) ? 2 : count;
-                    }
-                    /* create defs, all registers locked until the end of the load */
-                    for (nn = 0; nn < 15; nn++)
-                        if ((insn & (1U << nn)) != 0)
-                            _interlock_def(nn,result);
-                }
-                else  /* STM */
-                    result = (count < 2) ? 2 : count;
-            }
-            break;
-
-        case 5:  /* branch and branch+link */
-            break;
-
-        case 6:  /* coprocessor load/store */
-            {
-                int  Rn = (insn >> 16) & 15;
-
-                if (insn & 0x00100000)
-                    result += _interlock_use(Rn);
-
-                /* XXX: other things to do ? */
-            }
-            break;
-
-        default: /* i.e. 7 */
-            /* XXX: TODO: co-processor related things */
-            ;
-    }
-Exit:
-    interlock_base += result;
-    return result;
-#else /* old code - this seems to be completely buggy ?? */
-    if ((insn & 0x0ff0f090) == 0x01600080) {
-        return TICKS_SMULxy;
-    } else if ((insn & 0x0ff00090) == 0x01200080) {
-        return TICKS_SMLAWy;
-    } else if ((insn & 0x0ff00090) == 0x01400080) {
-        return TICKS_SMLALxy;
-    } else if ((insn & 0x0f0000f0) == 0x00000090) {
-        // multiply
-        uint8_t bit23 = (insn >> 23) & 0x1;
-        uint8_t bit22_U = (insn >> 22) & 0x1;
-        uint8_t bit21_A = (insn >> 21) & 0x1;
-        uint8_t bit20_S = (insn >> 20) & 0x1;
-
-        if (bit23 == 0) {
-            // 32-bit multiply
-            if (bit22_U != 0) {
-                // This is an unexpected bit pattern.
-                return TICKS_OTHER;
-            }
-            if (bit21_A == 0) {
-                if (bit20_S)
-                    return TICKS_MULS;
-                return TICKS_MUL;
-            }
-            if (bit20_S)
-                return TICKS_MLAS;
-            return TICKS_MLA;
-        }
-        // 64-bit multiply
-        if (bit22_U == 0) {
-            // Unsigned multiply long
-            if (bit21_A == 0) {
-                if (bit20_S)
-                    return TICKS_UMULLS;
-                return TICKS_UMULL;
-            }
-            if (bit20_S)
-                return TICKS_UMLALS;
-            return TICKS_UMLAL;
-        }
-        // Signed multiply long
-        if (bit21_A == 0) {
-            if (bit20_S)
-                return TICKS_SMULLS;
-            return TICKS_SMULL;
-        }
-        if (bit20_S)
-            return TICKS_SMLALS;
-        return TICKS_SMLAL;
-    }
-    return TICKS_OTHER;
-#endif
-}
-
-int  get_insn_ticks_thumb(uint32_t  insn)
-{
-#if 1
-    int  result = 1;
-
-    switch ((insn >> 11) & 31)
-    {
-        case 0:
-        case 1:
-        case 2:   /* Shift by immediate */
-            {
-                int  Rm = (insn >> 3) & 7;
-                result += _interlock_use(Rm);
-            }
-            break;
-
-        case 3:  /* Add/Substract */
-            {
-                int  Rn = (insn >> 3) & 7;
-                result += _interlock_use(Rn);
-
-                if ((insn & 0x0400) == 0) {  /* register value */
-                    int  Rm = (insn >> 6) & 7;
-                    result += _interlock_use(Rm);
-                }
-            }
-            break;
-
-        case 4:  /* move immediate */
-            break;
-
-        case 5:
-        case 6:
-        case 7:  /* add/substract/compare immediate */
-            {
-                int  Rd = (insn >> 8) & 7;
-                result += _interlock_use(Rd);
-            }
-            break;
-
-        case 8:
-            {
-                if ((insn & 0x0400) == 0)  /* data processing register */
-                {
-                    /* the registers can also be Rs and Rn in some cases */
-                    /* but they're always read anyway and located at the */
-                    /* same place, so we don't check the opcode          */
-                    int  Rm = (insn >> 3) & 7;
-                    int  Rd = (insn >> 3) & 7;
-
-                    result += _interlock_use(Rm) + _interlock_use(Rd);
-                }
-                else switch ((insn >> 8) & 3)
-                {
-                    case 0:
-                    case 1:
-                    case 2:  /* special data processing */
-                        {
-                            int  Rn = (insn & 7) | ((insn >> 4) & 0x8);
-                            int  Rm = ((insn >> 3) & 15);
-
-                            result += _interlock_use(Rn) + _interlock_use(Rm);
-                        }
-                        break;
-
-                    case 3:
-                        if ((insn & 0xff07) == 0x4700)  /* branch/exchange */
-                        {
-                            int  Rm = (insn >> 3) & 15;
-
-                            result = 3 + _interlock_use(Rm);
-                        }
-                        /* else UNDEFINED */
-                        break;
-                }
-            }
-            break;
-
-        case 9:  /* load from literal pool */
-            {
-                int  Rd = (insn >> 8) & 7;
-                _interlock_def(Rd,result+1);
-            }
-            break;
-
-        case 10:
-        case 11:  /* load/store register offset */
-            {
-                int  Rd = (insn & 7);
-                int  Rn = (insn >> 3) & 7;
-                int  Rm = (insn >> 6) & 7;
-
-                result += _interlock_use(Rn) + _interlock_use(Rm);
-
-                switch ((insn >> 9) & 7)
-                {
-                    case 0: /* STR  */
-                    case 1: /* STRH */
-                    case 2: /* STRB */
-                        result += _interlock_use(Rd);
-                        break;
-
-                    case 3: /* LDRSB */
-                    case 5: /* LDRH */
-                    case 6: /* LDRB */
-                    case 7: /* LDRSH */
-                        _interlock_def(Rd,result+2);
-                        break;
-
-                    case 4: /* LDR */
-                        _interlock_def(Rd,result+1);
-                }
-            }
-            break;
-
-        case 12:  /* store word immediate offset */
-        case 14:  /* store byte immediate offset */
-            {
-                int  Rd = (insn & 7);
-                int  Rn = (insn >> 3) & 7;
-
-                result += _interlock_use(Rd) + _interlock_use(Rn);
-            }
-            break;
-
-        case 13:  /* load word immediate offset */
-            {
-                int  Rd = (insn & 7);
-                int  Rn = (insn >> 3) & 7;
-
-                result += _interlock_use(Rn);
-                _interlock_def(Rd,result+1);
-            }
-            break;
-
-        case 15:  /* load byte immediate offset */
-            {
-                int  Rd = (insn & 7);
-                int  Rn = (insn >> 3) & 7;
-
-                result += _interlock_use(Rn);
-                _interlock_def(Rd,result+2);
-            }
-            break;
-
-        case 16:  /* store halfword immediate offset */
-            {
-                int  Rd = (insn & 7);
-                int  Rn = (insn >> 3) & 7;
-
-                result += _interlock_use(Rn) + _interlock_use(Rd);
-            }
-            break;
-
-        case 17:  /* load halfword immediate offset */
-            {
-                int  Rd = (insn & 7);
-                int  Rn = (insn >> 3) & 7;
-
-                result += _interlock_use(Rn);
-                _interlock_def(Rd,result+2);
-            }
-            break;
-
-        case 18:  /* store to stack */
-            {
-                int  Rd = (insn >> 8) & 3;
-                result += _interlock_use(Rd);
-            }
-            break;
-
-        case 19:  /* load from stack */
-            {
-                int  Rd = (insn >> 8) & 3;
-                _interlock_def(Rd,result+1);
-            }
-            break;
-
-        case 20:  /* add to PC */
-        case 21:  /* add to SP */
-            {
-                int  Rd = (insn >> 8) & 3;
-                result += _interlock_use(Rd);
-            }
-            break;
-
-        case 22:
-        case 23:  /* misc. instructions, table 6-2 */
-            {
-                if ((insn & 0xff00) == 0xb000)  /* adjust stack pointer */
-                {
-                    result += _interlock_use(14);
-                }
-                else if ((insn & 0x0600) == 0x0400)  /* push pop register list */
-                {
-                    uint32_t  mask = insn & 0x01ff;
-                    int       count, nn;
-
-                    for (count = 0; mask; count++)
-                        mask &= (mask-1);
-
-                    result = (count < 2) ? 2 : count;
-
-                    if (insn & 0x0800)  /* pop register list */
-                    {
-                        for (nn = 0; nn < 9; nn++)
-                            if (insn & (1 << nn))
-                                _interlock_def(nn, result);
-                    }
-                    else  /* push register list */
-                    {
-                        for (nn = 0; nn < 9; nn++)
-                            if (insn & (1 << nn))
-                                result += _interlock_use(nn);
-                    }
-                }
-                /* else  software breakpoint */
-            }
-            break;
-
-        case 24:  /* store multiple */
-            {
-                int  Rd = (insn >> 8) & 7;
-                uint32_t  mask = insn & 255;
-                int       count, nn;
-
-                for (count = 0; mask; count++)
-                    mask &= (mask-1);
-
-                result = (count < 2) ? 2 : count;
-                result += _interlock_use(Rd);
-
-                for (nn = 0; nn < 8; nn++)
-                    if (insn & (1 << nn))
-                        result += _interlock_use(nn);
-            }
-            break;
-
-        case 25:  /* load multiple */
-            {
-                int  Rd = (insn >> 8) & 7;
-                uint32_t  mask = insn & 255;
-                int       count, nn;
-
-                for (count = 0; mask; count++)
-                    mask &= (mask-1);
-
-                result  = (count < 2) ? 2 : count;
-                result += _interlock_use(Rd);
-
-                for (nn = 0; nn < 8; nn++)
-                    if (insn & (1 << nn))
-                        _interlock_def(nn, result);
-            }
-            break;
-
-        case 26:
-        case 27:  /* conditional branch / undefined / software interrupt */
-            switch ((insn >> 8) & 15)
-            {
-                case 14: /* UNDEFINED */
-                case 15: /* SWI */
-                    break;
-
-                default:  /* conditional branch */
-                    result = 3;
-            }
-            break;
-
-        case 28:  /* unconditional branch */
-            result = 3;
-            break;
-
-        case 29:  /* BLX suffix or undefined */
-            if ((insn & 1) == 0)
-                result = 3;
-            break;
-
-        case 30:  /* BLX/BLX prefix */
-            break;
-
-        case 31:  /* BL suffix */
-            result = 3;
-            break;
-    }
-    interlock_base += result;
-    return result;
-#else /* old code */
-    if ((insn & 0xfc00) == 0x4340) /* MUL */
-        return TICKS_SMULxy;
-
-    return TICKS_OTHER;
-#endif
-}
-
-// Adds an exception trace record.
-void trace_exception(uint32 target_pc)
-{
-    if (trace_exc.fstream == NULL)
-        return;
-
-    // Sometimes we get an unexpected exception as the first record.  If the
-    // basic block number is zero, then we know it is bogus.
-    if (trace_bb.current_bb_num == 0)
-        return;
-
-    uint32_t current_pc = trace_bb.current_bb_addr + 4 * (trace_bb.num_insns - 1);
-#if 0
-    if (ftrace_debug) {
-        fprintf(ftrace_debug, "t%llu exc pc: 0x%x bb_addr: 0x%x num_insns: %d current_pc: 0x%x bb_num %llu bb_start_time %llu\n",
-                sim_time, target_pc, trace_bb.current_bb_addr,
-                trace_bb.num_insns, current_pc, trace_bb.current_bb_num,
-                trace_bb.current_bb_start_time);
-    }
-#endif
-    char *comp_ptr = trace_exc.compressed_ptr;
-    if (comp_ptr >= trace_exc.high_water_ptr) {
-        uint32_t size = comp_ptr - trace_exc.compressed;
-        fwrite(trace_exc.compressed, sizeof(char), size, trace_exc.fstream);
-        comp_ptr = trace_exc.compressed;
-    }
-    uint64_t time_diff = sim_time - trace_exc.prev_time;
-    trace_exc.prev_time = sim_time;
-    uint64_t bb_recnum_diff = trace_bb.recnum - trace_exc.prev_bb_recnum;
-    trace_exc.prev_bb_recnum = trace_bb.recnum;
-    comp_ptr = varint_encode(time_diff, comp_ptr);
-    comp_ptr = varint_encode(current_pc, comp_ptr);
-    comp_ptr = varint_encode(bb_recnum_diff, comp_ptr);
-    comp_ptr = varint_encode(target_pc, comp_ptr);
-    comp_ptr = varint_encode(trace_bb.current_bb_num, comp_ptr);
-    comp_ptr = varint_encode(trace_bb.current_bb_start_time, comp_ptr);
-    comp_ptr = varint_encode(trace_bb.num_insns, comp_ptr);
-    trace_exc.compressed_ptr = comp_ptr;
-}
-
-void trace_pid_1arg(int pid, int rec_type)
-{
-    if (trace_pid.fstream == NULL)
-        return;
-    char *comp_ptr = trace_pid.compressed_ptr;
-    char *max_end_ptr = comp_ptr + kMaxPidCompressed;
-    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
-        uint32_t size = comp_ptr - trace_pid.compressed;
-        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
-        comp_ptr = trace_pid.compressed;
-    }
-    uint64_t time_diff = sim_time - trace_pid.prev_time;
-    trace_pid.prev_time = sim_time;
-    comp_ptr = varint_encode(time_diff, comp_ptr);
-    comp_ptr = varint_encode(rec_type, comp_ptr);
-    comp_ptr = varint_encode(pid, comp_ptr);
-    trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_pid_2arg(int tgid, int pid, int rec_type)
-{
-    if (trace_pid.fstream == NULL)
-        return;
-    char *comp_ptr = trace_pid.compressed_ptr;
-    char *max_end_ptr = comp_ptr + kMaxPid2Compressed;
-    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
-        uint32_t size = comp_ptr - trace_pid.compressed;
-        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
-        comp_ptr = trace_pid.compressed;
-    }
-    uint64_t time_diff = sim_time - trace_pid.prev_time;
-    trace_pid.prev_time = sim_time;
-    comp_ptr = varint_encode(time_diff, comp_ptr);
-    comp_ptr = varint_encode(rec_type, comp_ptr);
-    comp_ptr = varint_encode(tgid, comp_ptr);
-    comp_ptr = varint_encode(pid, comp_ptr);
-    trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_switch(int pid)
-{
-#if 0
-    if (ftrace_debug && trace_pid.fstream)
-        fprintf(ftrace_debug, "t%lld switch %d\n", sim_time, pid);
-#endif
-    trace_pid_1arg(pid, kPidSwitch);
-    current_pid = pid;
-}
-
-void trace_fork(int tgid, int pid)
-{
-#if 0
-    if (ftrace_debug && trace_pid.fstream)
-        fprintf(ftrace_debug, "t%lld fork %d\n", sim_time, pid);
-#endif
-    trace_pid_2arg(tgid, pid, kPidFork);
-}
-
-void trace_clone(int tgid, int pid)
-{
-#if 0
-    if (ftrace_debug && trace_pid.fstream)
-        fprintf(ftrace_debug, "t%lld clone %d\n", sim_time, pid);
-#endif
-    trace_pid_2arg(tgid, pid, kPidClone);
-}
-
-void trace_exit(int exitcode)
-{
-#if 0
-    if (ftrace_debug && trace_pid.fstream)
-        fprintf(ftrace_debug, "t%lld exit %d\n", sim_time, exitcode);
-#endif
-    trace_pid_1arg(exitcode, kPidExit);
-}
-
-void trace_name(char *name)
-{
-#if 0
-    if (ftrace_debug && trace_pid.fstream) {
-        fprintf(ftrace_debug, "t%lld pid %d name %s\n",
-                sim_time, current_pid, name);
-    }
-#endif
-    if (trace_pid.fstream == NULL)
-        return;
-    int len = strlen(name);
-    char *comp_ptr = trace_pid.compressed_ptr;
-    char *max_end_ptr = comp_ptr + len + kMaxNameCompressed;
-    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
-        uint32_t size = comp_ptr - trace_pid.compressed;
-        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
-        comp_ptr = trace_pid.compressed;
-    }
-    uint64_t time_diff = sim_time - trace_pid.prev_time;
-    trace_pid.prev_time = sim_time;
-    comp_ptr = varint_encode(time_diff, comp_ptr);
-    int rec_type = kPidName;
-    comp_ptr = varint_encode(rec_type, comp_ptr);
-    comp_ptr = varint_encode(current_pid, comp_ptr);
-    comp_ptr = varint_encode(len, comp_ptr);
-    strncpy(comp_ptr, name, len);
-    comp_ptr += len;
-    trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_execve(const char *argv, int len)
-{
-    int ii;
-
-    if (trace_pid.fstream == NULL)
-        return;
-    // Count the number of args
-    int alen = 0;
-    int sum_len = 0;
-    int argc = 0;
-    const char *ptr = argv;
-    while (sum_len < len) {
-        argc += 1;
-        alen = strlen(ptr);
-        ptr += alen + 1;
-        sum_len += alen + 1;
-    }
-
-#if 0
-    if (ftrace_debug) {
-        fprintf(ftrace_debug, "t%lld argc: %d\n", sim_time, argc);
-        alen = 0;
-        ptr = argv;
-        for (ii = 0; ii < argc; ++ii) {
-            fprintf(ftrace_debug, "  argv[%d]: %s\n", ii, ptr);
-            alen = strlen(ptr);
-            ptr += alen + 1;
-        }
-    }
-#endif
-
-    char *comp_ptr = trace_pid.compressed_ptr;
-    char *max_end_ptr = comp_ptr + len + 5 * argc + kMaxExecArgsCompressed;
-    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
-        uint32_t size = comp_ptr - trace_pid.compressed;
-        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
-        comp_ptr = trace_pid.compressed;
-    }
-    uint64_t time_diff = sim_time - trace_pid.prev_time;
-    trace_pid.prev_time = sim_time;
-    comp_ptr = varint_encode(time_diff, comp_ptr);
-    int rec_type = kPidExec;
-    comp_ptr = varint_encode(rec_type, comp_ptr);
-    comp_ptr = varint_encode(argc, comp_ptr);
-
-    ptr = argv;
-    for (ii = 0; ii < argc; ++ii) {
-        alen = strlen(ptr);
-        comp_ptr = varint_encode(alen, comp_ptr);
-        strncpy(comp_ptr, ptr, alen);
-        comp_ptr += alen;
-        ptr += alen + 1;
-    }
-    trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_mmap(unsigned long vstart, unsigned long vend,
-                unsigned long offset, const char *path)
-{
-    if (trace_pid.fstream == NULL)
-        return;
-#if 0
-    if (ftrace_debug)
-        fprintf(ftrace_debug, "t%lld mmap %08lx - %08lx, offset %08lx '%s'\n",
-                sim_time, vstart, vend, offset, path);
-#endif
-    int len = strlen(path);
-    char *comp_ptr = trace_pid.compressed_ptr;
-    char *max_end_ptr = comp_ptr + len + kMaxMmapCompressed;
-    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
-        uint32_t size = comp_ptr - trace_pid.compressed;
-        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
-        comp_ptr = trace_pid.compressed;
-    }
-    uint64_t time_diff = sim_time - trace_pid.prev_time;
-    trace_pid.prev_time = sim_time;
-    comp_ptr = varint_encode(time_diff, comp_ptr);
-    int rec_type = kPidMmap;
-    comp_ptr = varint_encode(rec_type, comp_ptr);
-    comp_ptr = varint_encode(vstart, comp_ptr);
-    comp_ptr = varint_encode(vend, comp_ptr);
-    comp_ptr = varint_encode(offset, comp_ptr);
-    comp_ptr = varint_encode(len, comp_ptr);
-    strncpy(comp_ptr, path, len);
-    trace_pid.compressed_ptr = comp_ptr + len;
-}
-
-void trace_munmap(unsigned long vstart, unsigned long vend)
-{
-    if (trace_pid.fstream == NULL)
-        return;
-#if 0
-    if (ftrace_debug)
-        fprintf(ftrace_debug, "t%lld munmap %08lx - %08lx\n",
-                sim_time, vstart, vend);
-#endif
-    char *comp_ptr = trace_pid.compressed_ptr;
-    char *max_end_ptr = comp_ptr + kMaxMunmapCompressed;
-    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
-        uint32_t size = comp_ptr - trace_pid.compressed;
-        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
-        comp_ptr = trace_pid.compressed;
-    }
-    uint64_t time_diff = sim_time - trace_pid.prev_time;
-    trace_pid.prev_time = sim_time;
-    comp_ptr = varint_encode(time_diff, comp_ptr);
-    int rec_type = kPidMunmap;
-    comp_ptr = varint_encode(rec_type, comp_ptr);
-    comp_ptr = varint_encode(vstart, comp_ptr);
-    comp_ptr = varint_encode(vend, comp_ptr);
-    trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_dynamic_symbol_add(unsigned long vaddr, const char *name)
-{
-    if (trace_pid.fstream == NULL)
-        return;
-#if 0
-    if (ftrace_debug)
-        fprintf(ftrace_debug, "t%lld sym %08lx '%s'\n", sim_time, vaddr, name);
-#endif
-    int len = strlen(name);
-    char *comp_ptr = trace_pid.compressed_ptr;
-    char *max_end_ptr = comp_ptr + len + kMaxSymbolCompressed;
-    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
-        uint32_t size = comp_ptr - trace_pid.compressed;
-        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
-        comp_ptr = trace_pid.compressed;
-    }
-    uint64_t time_diff = sim_time - trace_pid.prev_time;
-    trace_pid.prev_time = sim_time;
-    comp_ptr = varint_encode(time_diff, comp_ptr);
-    int rec_type = kPidSymbolAdd;
-    comp_ptr = varint_encode(rec_type, comp_ptr);
-    comp_ptr = varint_encode(vaddr, comp_ptr);
-    comp_ptr = varint_encode(len, comp_ptr);
-    strncpy(comp_ptr, name, len);
-    trace_pid.compressed_ptr = comp_ptr + len;
-}
-
-void trace_dynamic_symbol_remove(unsigned long vaddr)
-{
-    if (trace_pid.fstream == NULL)
-        return;
-#if 0
-    if (ftrace_debug)
-        fprintf(ftrace_debug, "t%lld remove %08lx\n", sim_time, vaddr);
-#endif
-    char *comp_ptr = trace_pid.compressed_ptr;
-    char *max_end_ptr = comp_ptr + kMaxSymbolCompressed;
-    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
-        uint32_t size = comp_ptr - trace_pid.compressed;
-        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
-        comp_ptr = trace_pid.compressed;
-    }
-    uint64_t time_diff = sim_time - trace_pid.prev_time;
-    trace_pid.prev_time = sim_time;
-    comp_ptr = varint_encode(time_diff, comp_ptr);
-    int rec_type = kPidSymbolRemove;
-    comp_ptr = varint_encode(rec_type, comp_ptr);
-    comp_ptr = varint_encode(vaddr, comp_ptr);
-    trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_init_name(int tgid, int pid, const char *name)
-{
-    if (trace_pid.fstream == NULL)
-        return;
-#if 0
-    if (ftrace_debug)
-        fprintf(ftrace_debug, "t%lld kthread %d %s\n", sim_time, pid, name);
-#endif
-    int len = strlen(name);
-    char *comp_ptr = trace_pid.compressed_ptr;
-    char *max_end_ptr = comp_ptr + len + kMaxKthreadNameCompressed;
-    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
-        uint32_t size = comp_ptr - trace_pid.compressed;
-        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
-        comp_ptr = trace_pid.compressed;
-    }
-    uint64_t time_diff = sim_time - trace_pid.prev_time;
-    trace_pid.prev_time = sim_time;
-    comp_ptr = varint_encode(time_diff, comp_ptr);
-    int rec_type = kPidKthreadName;
-    comp_ptr = varint_encode(rec_type, comp_ptr);
-    comp_ptr = varint_encode(tgid, comp_ptr);
-    comp_ptr = varint_encode(pid, comp_ptr);
-    comp_ptr = varint_encode(len, comp_ptr);
-    strncpy(comp_ptr, name, len);
-    trace_pid.compressed_ptr = comp_ptr + len;
-}
-
-void trace_init_exec(unsigned long start, unsigned long end,
-                     unsigned long offset, const char *exe)
-{
-}
-
-// This function is called by the generated code to record the basic
-// block number.
-void trace_bb_helper(uint64_t bb_num, TranslationBlock *tb)
-{
-    BBRec *bb_rec = tb->bb_rec;
-    uint64_t prev_time = tb->prev_time;
-    trace_bb.current_bb_addr = tb->pc;
-    trace_bb.current_bb_num = bb_num;
-    trace_bb.current_bb_start_time = sim_time;
-    trace_bb.num_insns = 0;
-    trace_bb.recnum += 1;
-
-#if 0
-    if (ftrace_debug)
-        fprintf(ftrace_debug, "t%lld %lld\n", sim_time, bb_num);
-#endif
-    if (bb_rec && bb_rec->bb_num == bb_num && prev_time > trace_bb.flush_time) {
-        uint64_t time_diff = sim_time - prev_time;
-        if (bb_rec->repeat == 0) {
-            bb_rec->repeat = 1;
-            bb_rec->time_diff = time_diff;
-            tb->prev_time = sim_time;
-            return;
-        } else if (time_diff == bb_rec->time_diff) {
-            bb_rec->repeat += 1;
-            tb->prev_time = sim_time;
-            return;
-        }
-    }
-
-    BBRec *next = trace_bb.next;
-    if (next == &trace_bb.buffer[kMaxNumBasicBlocks]) {
-        BBRec *ptr;
-        char *comp_ptr = trace_bb.compressed_ptr;
-        int64_t prev_bb_num = trace_bb.prev_bb_num;
-        uint64_t prev_bb_time = trace_bb.prev_bb_time;
-        for (ptr = trace_bb.buffer; ptr != next; ++ptr) {
-            if (comp_ptr >= trace_bb.high_water_ptr) {
-                uint32_t size = comp_ptr - trace_bb.compressed;
-                fwrite(trace_bb.compressed, sizeof(char), size, trace_bb.fstream);
-                comp_ptr = trace_bb.compressed;
-            }
-            int64_t bb_diff = ptr->bb_num - prev_bb_num;
-            prev_bb_num = ptr->bb_num;
-            uint64_t time_diff = ptr->start_time - prev_bb_time;
-            prev_bb_time = ptr->start_time;
-            comp_ptr = varint_encode_signed(bb_diff, comp_ptr);
-            comp_ptr = varint_encode(time_diff, comp_ptr);
-            comp_ptr = varint_encode(ptr->repeat, comp_ptr);
-            if (ptr->repeat)
-                comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
-        }
-        trace_bb.compressed_ptr = comp_ptr;
-        trace_bb.prev_bb_num = prev_bb_num;
-        trace_bb.prev_bb_time = prev_bb_time;
-
-        next = trace_bb.buffer;
-        trace_bb.flush_time = sim_time;
-    }
-    tb->bb_rec = next;
-    next->bb_num = bb_num;
-    next->start_time = sim_time;
-    next->time_diff = 0;
-    next->repeat = 0;
-    tb->prev_time = sim_time;
-    next += 1;
-    trace_bb.next = next;
-}
-
-// This function is called by the generated code to record the simulation
-// time at the start of each instruction.
-void trace_insn_helper()
-{
-    InsnRec *current = trace_insn.current;
-    uint64_t time_diff = sim_time - trace_insn.prev_time;
-    trace_insn.prev_time = sim_time;
-
-    // Keep track of the number of traced instructions so far in this
-    // basic block in case we get an exception in the middle of the bb.
-    trace_bb.num_insns += 1;
-
-#if 0
-    if (ftrace_debug) {
-        uint32_t current_pc = trace_bb.current_bb_addr + 4 * (trace_bb.num_insns - 1);
-        fprintf(ftrace_debug, "%llu %x\n", sim_time, current_pc);
-    }
-#endif
-    if (time_diff == current->time_diff) {
-        current->repeat += 1;
-        if (current->repeat != 0)
-            return;
-
-        // The repeat count wrapped around, so back up one and create
-        // a new record.
-        current->repeat -= 1;
-    }
-    current += 1;
-
-    if (current == &trace_insn.buffer[kInsnBufferSize]) {
-        InsnRec *ptr;
-        char *comp_ptr = trace_insn.compressed_ptr;
-        for (ptr = trace_insn.buffer; ptr != current; ++ptr) {
-            if (comp_ptr >= trace_insn.high_water_ptr) {
-                uint32_t size = comp_ptr - trace_insn.compressed;
-                uint32_t rval = fwrite(trace_insn.compressed, sizeof(char),
-                                       size, trace_insn.fstream);
-                if (rval != size) {
-                    fprintf(stderr, "fwrite() failed\n");
-                    perror(trace_insn.filename);
-                    exit(1);
-                }
-                comp_ptr = trace_insn.compressed;
-            }
-            comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
-            comp_ptr = varint_encode(ptr->repeat, comp_ptr);
-        }
-        trace_insn.compressed_ptr = comp_ptr;
-        current = trace_insn.buffer;
-    }
-    current->time_diff = time_diff;
-    current->repeat = 0;
-    trace_insn.current = current;
-}
-
-// Adds an interpreted method trace record.  Each trace record is a time
-// stamped entry or exit to a method in a language executed by a "virtual
-// machine".  This allows profiling tools to show the method names instead
-// of the core virtual machine interpreter.
-void trace_interpreted_method(uint32_t addr, int call_type)
-{
-    if (trace_method.fstream == NULL)
-        return;
-#if 0
-    fprintf(stderr, "trace_method time: %llu p%d 0x%x %d\n",
-            sim_time, current_pid, addr, call_type);
-#endif
-    char *comp_ptr = trace_method.compressed_ptr;
-    char *max_end_ptr = comp_ptr + kMaxMethodCompressed;
-    if (max_end_ptr >= &trace_method.compressed[kCompressedSize]) {
-        uint32_t size = comp_ptr - trace_method.compressed;
-        fwrite(trace_method.compressed, sizeof(char), size, trace_method.fstream);
-        comp_ptr = trace_method.compressed;
-    }
-    uint64_t time_diff = sim_time - trace_method.prev_time;
-    trace_method.prev_time = sim_time;
-
-    int32_t addr_diff = addr - trace_method.prev_addr;
-    trace_method.prev_addr = addr;
-
-    int32_t pid_diff = current_pid - trace_method.prev_pid;
-    trace_method.prev_pid = current_pid;
-
-    comp_ptr = varint_encode(time_diff, comp_ptr);
-    comp_ptr = varint_encode_signed(addr_diff, comp_ptr);
-    comp_ptr = varint_encode_signed(pid_diff, comp_ptr);
-    comp_ptr = varint_encode(call_type, comp_ptr);
-    trace_method.compressed_ptr = comp_ptr;
-}
-
-uint64_t trace_static_bb_num(void)
-{
-    return trace_static.bb_num;
-}
diff --git a/arch_init.c b/arch_init.c
index 4ad6a02..4c44dc5 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -38,6 +38,7 @@
 #include "hw/audiodev.h"
 #include "sysemu/kvm.h"
 #include "migration/migration.h"
+#include "migration/qemu-file.h"
 #include "net/net.h"
 #include "exec/gdbstub.h"
 #include "hw/i386/smbios.h"
@@ -262,7 +263,7 @@
     }
 
     if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
-        qemu_file_set_error(f);
+        qemu_file_set_error(f, -errno);
         return 0;
     }
 
@@ -448,7 +449,7 @@
 
             qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
         }
-        if (qemu_file_has_error(f)) {
+        if (qemu_file_get_error(f)) {
             return -EIO;
         }
     } while (!(flags & RAM_SAVE_FLAG_EOS));
@@ -457,11 +458,6 @@
 }
 #endif
 
-void qemu_service_io(void)
-{
-    qemu_notify_event();
-}
-
 #ifdef HAS_AUDIO
 struct soundhw {
     const char *name;
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 2ec0bf0..53dbb58 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -245,7 +245,7 @@
 #define INIT_FIELD(f) /**/
 #endif
 
-static void GCC_ATTR dolog (const char *fmt, ...)
+static void GCC_FMT_ATTR(1,2) dolog (const char *fmt, ...)
 {
     va_list ap;
 
@@ -255,7 +255,7 @@
 }
 
 #ifdef DEBUG
-static void GCC_ATTR ldebug (const char *fmt, ...)
+static void GCC_FMT_ATTR(1,2) ldebug (const char *fmt, ...)
 {
     va_list ap;
 
@@ -269,15 +269,13 @@
 #elif defined NDEBUG && defined _MSC_VER
 #define ldebug __noop
 #else
-static void GCC_ATTR ldebug (const char *fmt, ...)
+static void GCC_FMT_ATTR(1,2) ldebug (const char *fmt, ...)
 {
     (void) fmt;
 }
 #endif
 #endif
 
-#undef GCC_ATTR
-
 #define AUDIO_STRINGIFY_(n) #n
 #define AUDIO_STRINGIFY(n) AUDIO_STRINGIFY_(n)
 
diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index 7213407..466e924 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -28,7 +28,6 @@
 
 #define AUDIO_CAP "wav"
 #include "audio_int.h"
-#include "migration/qemu-file.h"
 
 #define  WAV_AUDIO_IN  1
 
@@ -36,7 +35,7 @@
  **/
 typedef struct WAVVoiceOut {
     HWVoiceOut hw;
-    QEMUFile *f;
+    FILE *f;
     int64_t old_ticks;
     void *pcm_buf;
     int total_samples;
@@ -85,7 +84,10 @@
         dst = advance (wav->pcm_buf, rpos << hw->info.shift);
 
         hw->clip (dst, src, convert_samples);
-        qemu_put_buffer (wav->f, dst, convert_samples << hw->info.shift);
+        if (fwrite (dst, convert_samples << hw->info.shift, 1, wav->f) != 1) {
+            dolog ("wav_run_out: fwrite of %d bytes failed\nReaons: %s\n",
+                   convert_samples << hw->info.shift, strerror (errno));
+        }
 
         rpos = (rpos + convert_samples) % hw->samples;
         samples -= convert_samples;
@@ -161,7 +163,7 @@
     le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4);
     le_store (hdr + 32, 1 << (bits16 + stereo), 2);
 
-    wav->f = qemu_fopen (conf_out.wav_path, "wb");
+    wav->f = fopen (conf_out.wav_path, "wb");
     if (!wav->f) {
         dolog ("Failed to open wave file `%s'\nReason: %s\n",
                conf_out.wav_path, strerror (errno));
@@ -170,7 +172,11 @@
         return -1;
     }
 
-    qemu_put_buffer (wav->f, hdr, sizeof (hdr));
+    if (fwrite (hdr, sizeof (hdr), 1, wav->f) != 1) {
+        dolog ("wav_init_out: failed to write header\nReason: %s\n",
+               strerror(errno));
+        return -1;
+    }
     return 0;
 }
 
@@ -189,13 +195,13 @@
     le_store (rlen, rifflen, 4);
     le_store (dlen, datalen, 4);
 
-    qemu_fseek (wav->f, 4, SEEK_SET);
-    qemu_put_buffer (wav->f, rlen, 4);
+    fseek (wav->f, 4, SEEK_SET);
+    fwrite(rlen, 4, 1, wav->f);
 
-    qemu_fseek (wav->f, 32, SEEK_CUR);
-    qemu_put_buffer (wav->f, dlen, 4);
+    fseek (wav->f, 32, SEEK_CUR);
+    fwrite(dlen, 4, 1, wav->f);
 
-    qemu_fclose (wav->f);
+    fclose (wav->f);
     wav->f = NULL;
 
     g_free (wav->pcm_buf);
@@ -223,7 +229,7 @@
 
 typedef struct WAVVoiceIn {
     HWVoiceIn  hw;
-    QEMUFile*  f;
+    FILE*      f;
     int64_t    old_ticks;
     void*      pcm_buf;
     int        total_samples;
@@ -252,15 +258,15 @@
     struct audsettings wav_as = *as;
     int           nchannels, freq, format, bits;
 
-    wav->f = qemu_fopen (path, "rb");
+    wav->f = fopen (path, "rb");
     if (wav->f == NULL) {
         dolog("Failed to open wave file '%s'\nReason: %s\n", path,
               strerror(errno));
         return -1;
     }
 
-    if (qemu_get_buffer (wav->f, hdr, sizeof(hdr)) != (int)sizeof(hdr)) {
-        dolog("File '%s' to be a .wav file\n", path);
+    if (fread(hdr, sizeof(hdr), 1, wav->f) != 1) {
+        dolog("File '%s' doesn't seem to be a .wav file\n", path);
         goto Fail;
     }
 
@@ -321,7 +327,7 @@
     return 0;
 
 Fail:
-    qemu_fclose (wav->f);
+    fclose (wav->f);
     wav->f = NULL;
     return -1;
 }
@@ -335,7 +341,7 @@
         return;
     }
 
-    qemu_fclose (wav->f);
+    fclose (wav->f);
     wav->f = NULL;
 
     g_free (wav->pcm_buf);
@@ -377,12 +383,17 @@
         dst = hw->conv_buf + wpos;
         src = advance (wav->pcm_buf, wpos << hw->info.shift);
 
-        qemu_get_buffer (wav->f, src, convert_samples << hw->info.shift);
-        memcpy (dst, src, convert_samples << hw->info.shift);
+        clearerr(wav->f);
+        size_t read_bytes = fread(src, 1, convert_samples << hw->info.shift, wav->f);
+        if (read_bytes == 0 && ferror(wav->f) != EINTR)
+            return 0;
 
-        wpos                = (wpos + convert_samples) % hw->samples;
-        samples            -= convert_samples;
-        wav->total_samples += convert_samples;
+        size_t read_samples = read_bytes >> hw->info.shift;
+        memcpy (dst, src, read_bytes);
+
+        wpos                = (wpos + read_samples) % hw->samples;
+        samples            -= read_samples;
+        wav->total_samples += read_samples;
     }
 
     hw->wpos = wpos;
diff --git a/audio/wavcapture.c b/audio/wavcapture.c
index 4d9b15d..ef86c69 100644
--- a/audio/wavcapture.c
+++ b/audio/wavcapture.c
@@ -1,9 +1,9 @@
-#include "hw/hw.h"
+#include <stdio.h>
 #include "monitor/monitor.h"
 #include "audio.h"
 
 typedef struct {
-    QEMUFile *f;
+    FILE *f;
     int bytes;
     char *path;
     int freq;
@@ -40,12 +40,12 @@
         le_store (rlen, rifflen, 4);
         le_store (dlen, datalen, 4);
 
-        qemu_fseek (wav->f, 4, SEEK_SET);
-        qemu_put_buffer (wav->f, rlen, 4);
+        fseek (wav->f, 4, SEEK_SET);
+        fwrite(rlen, 4, 1, wav->f);
 
-        qemu_fseek (wav->f, 32, SEEK_CUR);
-        qemu_put_buffer (wav->f, dlen, 4);
-        qemu_fclose (wav->f);
+        fseek (wav->f, 32, SEEK_CUR);
+        fwrite(dlen, 4, 1, wav->f);
+        fclose (wav->f);
     }
 
     g_free (wav->path);
@@ -55,7 +55,7 @@
 {
     WAVState *wav = opaque;
 
-    qemu_put_buffer (wav->f, buf, size);
+    fwrite(buf, size, 1, wav->f);
     wav->bytes += size;
 }
 
@@ -130,7 +130,7 @@
     le_store (hdr + 28, freq << shift, 4);
     le_store (hdr + 32, 1 << shift, 2);
 
-    wav->f = qemu_fopen (path, "wb");
+    wav->f = fopen (path, "wb");
     if (!wav->f) {
         monitor_printf(mon, "Failed to open wave file `%s'\nReason: %s\n",
                        path, strerror (errno));
@@ -143,13 +143,13 @@
     wav->nchannels = nchannels;
     wav->freq = freq;
 
-    qemu_put_buffer (wav->f, hdr, sizeof (hdr));
+    fwrite(hdr, sizeof(hdr), 1, wav->f);
 
     cap = AUD_add_capture (&as, &ops, wav);
     if (!cap) {
         monitor_printf(mon, "Failed to add audio capture\n");
         g_free (wav->path);
-        qemu_fclose (wav->f);
+        fclose (wav->f);
         g_free (wav);
         return -1;
     }
diff --git a/block.c b/block.c
index b82d600..c21b7c5 100644
--- a/block.c
+++ b/block.c
@@ -25,6 +25,7 @@
 #include "qemu-common.h"
 #include "monitor/monitor.h"
 #include "block/block_int.h"
+#include "qemu/iov.h"
 #include "qemu/module.h"
 //#include "qapi/qmp/types.h"
 #include "qapi/qmp/qjson.h"
@@ -2137,7 +2138,7 @@
             // Add the first request to the merged one. If the requests are
             // overlapping, drop the last sectors of the first request.
             size = (reqs[i].sector - reqs[outidx].sector) << 9;
-            qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
+            qemu_iovec_concat(qiov, reqs[outidx].qiov, 0, size);
 
             // We might need to add some zeros between the two requests
             if (reqs[i].sector > oldreq_last) {
@@ -2149,7 +2150,7 @@
             }
 
             // Add the second request
-            qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
+            qemu_iovec_concat(qiov, reqs[i].qiov, 0, reqs[i].qiov->size);
 
             reqs[outidx].nb_sectors = qiov->size >> 9;
             reqs[outidx].qiov = qiov;
@@ -2307,7 +2308,7 @@
     BlockDriverAIOCBSync *acb = opaque;
 
     if (!acb->is_write)
-        qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
+        qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
     qemu_vfree(acb->bounce);
     acb->common.cb(acb->common.opaque, acb->ret);
     qemu_bh_delete(acb->bh);
@@ -2335,7 +2336,7 @@
         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
 
     if (is_write) {
-        qemu_iovec_to_buffer(acb->qiov, acb->bounce);
+        qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
         acb->ret = bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
     } else {
         acb->ret = bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
diff --git a/block/bochs.c b/block/bochs.c
deleted file mode 100644
index 478852e..0000000
--- a/block/bochs.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Block driver for the various disk image formats used by Bochs
- * Currently only for "growing" type in read-only mode
- *
- * Copyright (c) 2005 Alex Beregszaszi
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "qemu/module.h"
-
-/**************************************************************/
-
-#define HEADER_MAGIC "Bochs Virtual HD Image"
-#define HEADER_VERSION 0x00020000
-#define HEADER_V1 0x00010000
-#define HEADER_SIZE 512
-
-#define REDOLOG_TYPE "Redolog"
-#define GROWING_TYPE "Growing"
-
-// not allocated: 0xffffffff
-
-// always little-endian
-struct bochs_header_v1 {
-    char magic[32]; // "Bochs Virtual HD Image"
-    char type[16]; // "Redolog"
-    char subtype[16]; // "Undoable" / "Volatile" / "Growing"
-    uint32_t version;
-    uint32_t header; // size of header
-
-    union {
-	struct {
-	    uint32_t catalog; // num of entries
-	    uint32_t bitmap; // bitmap size
-	    uint32_t extent; // extent size
-	    uint64_t disk; // disk size
-	    char padding[HEADER_SIZE - 64 - 8 - 20];
-	} redolog;
-	char padding[HEADER_SIZE - 64 - 8];
-    } extra;
-};
-
-// always little-endian
-struct bochs_header {
-    char magic[32]; // "Bochs Virtual HD Image"
-    char type[16]; // "Redolog"
-    char subtype[16]; // "Undoable" / "Volatile" / "Growing"
-    uint32_t version;
-    uint32_t header; // size of header
-
-    union {
-	struct {
-	    uint32_t catalog; // num of entries
-	    uint32_t bitmap; // bitmap size
-	    uint32_t extent; // extent size
-	    uint32_t reserved; // for ???
-	    uint64_t disk; // disk size
-	    char padding[HEADER_SIZE - 64 - 8 - 24];
-	} redolog;
-	char padding[HEADER_SIZE - 64 - 8];
-    } extra;
-};
-
-typedef struct BDRVBochsState {
-    uint32_t *catalog_bitmap;
-    int catalog_size;
-
-    int data_offset;
-
-    int bitmap_blocks;
-    int extent_blocks;
-    int extent_size;
-} BDRVBochsState;
-
-static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
-    const struct bochs_header *bochs = (const void *)buf;
-
-    if (buf_size < HEADER_SIZE)
-	return 0;
-
-    if (!strcmp(bochs->magic, HEADER_MAGIC) &&
-	!strcmp(bochs->type, REDOLOG_TYPE) &&
-	!strcmp(bochs->subtype, GROWING_TYPE) &&
-	((le32_to_cpu(bochs->version) == HEADER_VERSION) ||
-	(le32_to_cpu(bochs->version) == HEADER_V1)))
-	return 100;
-
-    return 0;
-}
-
-static int bochs_open(BlockDriverState *bs, int flags)
-{
-    BDRVBochsState *s = bs->opaque;
-    int i;
-    struct bochs_header bochs;
-    struct bochs_header_v1 header_v1;
-
-    bs->read_only = 1; // no write support yet
-
-    if (bdrv_pread(bs->file, 0, &bochs, sizeof(bochs)) != sizeof(bochs)) {
-        goto fail;
-    }
-
-    if (strcmp(bochs.magic, HEADER_MAGIC) ||
-        strcmp(bochs.type, REDOLOG_TYPE) ||
-        strcmp(bochs.subtype, GROWING_TYPE) ||
-	((le32_to_cpu(bochs.version) != HEADER_VERSION) &&
-	(le32_to_cpu(bochs.version) != HEADER_V1))) {
-        goto fail;
-    }
-
-    if (le32_to_cpu(bochs.version) == HEADER_V1) {
-      memcpy(&header_v1, &bochs, sizeof(bochs));
-      bs->total_sectors = le64_to_cpu(header_v1.extra.redolog.disk) / 512;
-    } else {
-      bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
-    }
-
-    s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);
-    s->catalog_bitmap = g_malloc(s->catalog_size * 4);
-    if (bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
-                   s->catalog_size * 4) != s->catalog_size * 4)
-	goto fail;
-    for (i = 0; i < s->catalog_size; i++)
-	le32_to_cpus(&s->catalog_bitmap[i]);
-
-    s->data_offset = le32_to_cpu(bochs.header) + (s->catalog_size * 4);
-
-    s->bitmap_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.bitmap) - 1) / 512;
-    s->extent_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.extent) - 1) / 512;
-
-    s->extent_size = le32_to_cpu(bochs.extra.redolog.extent);
-
-    return 0;
- fail:
-    return -1;
-}
-
-static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
-{
-    BDRVBochsState *s = bs->opaque;
-    int64_t offset = sector_num * 512;
-    int64_t extent_index, extent_offset, bitmap_offset;
-    char bitmap_entry;
-
-    // seek to sector
-    extent_index = offset / s->extent_size;
-    extent_offset = (offset % s->extent_size) / 512;
-
-    if (s->catalog_bitmap[extent_index] == 0xffffffff) {
-	return -1; /* not allocated */
-    }
-
-    bitmap_offset = s->data_offset + (512 * s->catalog_bitmap[extent_index] *
-	(s->extent_blocks + s->bitmap_blocks));
-
-    /* read in bitmap for current extent */
-    if (bdrv_pread(bs->file, bitmap_offset + (extent_offset / 8),
-                   &bitmap_entry, 1) != 1) {
-        return -1;
-    }
-
-    if (!((bitmap_entry >> (extent_offset % 8)) & 1)) {
-	return -1; /* not allocated */
-    }
-
-    return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
-}
-
-static int bochs_read(BlockDriverState *bs, int64_t sector_num,
-                    uint8_t *buf, int nb_sectors)
-{
-    int ret;
-
-    while (nb_sectors > 0) {
-        int64_t block_offset = seek_to_sector(bs, sector_num);
-        if (block_offset >= 0) {
-            ret = bdrv_pread(bs->file, block_offset, buf, 512);
-            if (ret != 512) {
-                return -1;
-            }
-        } else
-            memset(buf, 0, 512);
-        nb_sectors--;
-        sector_num++;
-        buf += 512;
-    }
-    return 0;
-}
-
-static void bochs_close(BlockDriverState *bs)
-{
-    BDRVBochsState *s = bs->opaque;
-    g_free(s->catalog_bitmap);
-}
-
-static BlockDriver bdrv_bochs = {
-    .format_name	= "bochs",
-    .instance_size	= sizeof(BDRVBochsState),
-    .bdrv_probe		= bochs_probe,
-    .bdrv_open		= bochs_open,
-    .bdrv_read		= bochs_read,
-    .bdrv_close		= bochs_close,
-};
-
-static void bdrv_bochs_init(void)
-{
-    bdrv_register(&bdrv_bochs);
-}
-
-block_init(bdrv_bochs_init);
diff --git a/block/cloop.c b/block/cloop.c
deleted file mode 100644
index 62d6449..0000000
--- a/block/cloop.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * QEMU Block driver for CLOOP images
- *
- * Copyright (c) 2004 Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "qemu/module.h"
-#include <zlib.h>
-
-typedef struct BDRVCloopState {
-    uint32_t block_size;
-    uint32_t n_blocks;
-    uint64_t* offsets;
-    uint32_t sectors_per_block;
-    uint32_t current_block;
-    uint8_t *compressed_block;
-    uint8_t *uncompressed_block;
-    z_stream zstream;
-} BDRVCloopState;
-
-static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
-    const char* magic_version_2_0="#!/bin/sh\n"
-	"#V2.0 Format\n"
-	"modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n";
-    int length=strlen(magic_version_2_0);
-    if(length>buf_size)
-	length=buf_size;
-    if(!memcmp(magic_version_2_0,buf,length))
-	return 2;
-    return 0;
-}
-
-static int cloop_open(BlockDriverState *bs, int flags)
-{
-    BDRVCloopState *s = bs->opaque;
-    uint32_t offsets_size,max_compressed_block_size=1,i;
-
-    bs->read_only = 1;
-
-    /* read header */
-    if (bdrv_pread(bs->file, 128, &s->block_size, 4) < 4) {
-        goto cloop_close;
-    }
-    s->block_size = be32_to_cpu(s->block_size);
-
-    if (bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4) < 4) {
-        goto cloop_close;
-    }
-    s->n_blocks = be32_to_cpu(s->n_blocks);
-
-    /* read offsets */
-    offsets_size = s->n_blocks * sizeof(uint64_t);
-    s->offsets = g_malloc(offsets_size);
-    if (bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size) <
-            offsets_size) {
-	goto cloop_close;
-    }
-    for(i=0;i<s->n_blocks;i++) {
-	s->offsets[i]=be64_to_cpu(s->offsets[i]);
-	if(i>0) {
-	    uint32_t size=s->offsets[i]-s->offsets[i-1];
-	    if(size>max_compressed_block_size)
-		max_compressed_block_size=size;
-	}
-    }
-
-    /* initialize zlib engine */
-    s->compressed_block = g_malloc(max_compressed_block_size+1);
-    s->uncompressed_block = g_malloc(s->block_size);
-    if(inflateInit(&s->zstream) != Z_OK)
-	goto cloop_close;
-    s->current_block=s->n_blocks;
-
-    s->sectors_per_block = s->block_size/512;
-    bs->total_sectors = s->n_blocks*s->sectors_per_block;
-    return 0;
-
-cloop_close:
-    return -1;
-}
-
-static inline int cloop_read_block(BlockDriverState *bs, int block_num)
-{
-    BDRVCloopState *s = bs->opaque;
-
-    if(s->current_block != block_num) {
-	int ret;
-        uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num];
-
-        ret = bdrv_pread(bs->file, s->offsets[block_num], s->compressed_block,
-                         bytes);
-        if (ret != bytes)
-            return -1;
-
-	s->zstream.next_in = s->compressed_block;
-	s->zstream.avail_in = bytes;
-	s->zstream.next_out = s->uncompressed_block;
-	s->zstream.avail_out = s->block_size;
-	ret = inflateReset(&s->zstream);
-	if(ret != Z_OK)
-	    return -1;
-	ret = inflate(&s->zstream, Z_FINISH);
-	if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size)
-	    return -1;
-
-	s->current_block = block_num;
-    }
-    return 0;
-}
-
-static int cloop_read(BlockDriverState *bs, int64_t sector_num,
-                    uint8_t *buf, int nb_sectors)
-{
-    BDRVCloopState *s = bs->opaque;
-    int i;
-
-    for(i=0;i<nb_sectors;i++) {
-	uint32_t sector_offset_in_block=((sector_num+i)%s->sectors_per_block),
-	    block_num=(sector_num+i)/s->sectors_per_block;
-	if(cloop_read_block(bs, block_num) != 0)
-	    return -1;
-	memcpy(buf+i*512,s->uncompressed_block+sector_offset_in_block*512,512);
-    }
-    return 0;
-}
-
-static void cloop_close(BlockDriverState *bs)
-{
-    BDRVCloopState *s = bs->opaque;
-    if(s->n_blocks>0)
-	free(s->offsets);
-    free(s->compressed_block);
-    free(s->uncompressed_block);
-    inflateEnd(&s->zstream);
-}
-
-static BlockDriver bdrv_cloop = {
-    .format_name	= "cloop",
-    .instance_size	= sizeof(BDRVCloopState),
-    .bdrv_probe		= cloop_probe,
-    .bdrv_open		= cloop_open,
-    .bdrv_read		= cloop_read,
-    .bdrv_close		= cloop_close,
-};
-
-static void bdrv_cloop_init(void)
-{
-    bdrv_register(&bdrv_cloop);
-}
-
-block_init(bdrv_cloop_init);
diff --git a/block/dmg.c b/block/dmg.c
deleted file mode 100644
index 1206ac2..0000000
--- a/block/dmg.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * QEMU Block driver for DMG images
- *
- * Copyright (c) 2004 Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "qemu/bswap.h"
-#include "qemu/module.h"
-#include <zlib.h>
-
-typedef struct BDRVDMGState {
-    /* each chunk contains a certain number of sectors,
-     * offsets[i] is the offset in the .dmg file,
-     * lengths[i] is the length of the compressed chunk,
-     * sectors[i] is the sector beginning at offsets[i],
-     * sectorcounts[i] is the number of sectors in that chunk,
-     * the sectors array is ordered
-     * 0<=i<n_chunks */
-
-    uint32_t n_chunks;
-    uint32_t* types;
-    uint64_t* offsets;
-    uint64_t* lengths;
-    uint64_t* sectors;
-    uint64_t* sectorcounts;
-    uint32_t current_chunk;
-    uint8_t *compressed_chunk;
-    uint8_t *uncompressed_chunk;
-    z_stream zstream;
-} BDRVDMGState;
-
-static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
-    int len=strlen(filename);
-    if(len>4 && !strcmp(filename+len-4,".dmg"))
-	return 2;
-    return 0;
-}
-
-static off_t read_off(BlockDriverState *bs, int64_t offset)
-{
-	uint64_t buffer;
-	if (bdrv_pread(bs->file, offset, &buffer, 8) < 8)
-		return 0;
-	return be64_to_cpu(buffer);
-}
-
-static off_t read_uint32(BlockDriverState *bs, int64_t offset)
-{
-	uint32_t buffer;
-	if (bdrv_pread(bs->file, offset, &buffer, 4) < 4)
-		return 0;
-	return be32_to_cpu(buffer);
-}
-
-static int dmg_open(BlockDriverState *bs, int flags)
-{
-    BDRVDMGState *s = bs->opaque;
-    off_t info_begin,info_end,last_in_offset,last_out_offset;
-    uint32_t count;
-    uint32_t max_compressed_size=1,max_sectors_per_chunk=1,i;
-    int64_t offset;
-
-    bs->read_only = 1;
-    s->n_chunks = 0;
-    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
-
-    /* read offset of info blocks */
-    offset = bdrv_getlength(bs->file);
-    if (offset < 0) {
-        goto fail;
-    }
-    offset -= 0x1d8;
-
-    info_begin = read_off(bs, offset);
-    if (info_begin == 0) {
-	goto fail;
-    }
-
-    if (read_uint32(bs, info_begin) != 0x100) {
-        goto fail;
-    }
-
-    count = read_uint32(bs, info_begin + 4);
-    if (count == 0) {
-        goto fail;
-    }
-    info_end = info_begin + count;
-
-    offset = info_begin + 0x100;
-
-    /* read offsets */
-    last_in_offset = last_out_offset = 0;
-    while (offset < info_end) {
-        uint32_t type;
-
-	count = read_uint32(bs, offset);
-	if(count==0)
-	    goto fail;
-        offset += 4;
-
-	type = read_uint32(bs, offset);
-	if (type == 0x6d697368 && count >= 244) {
-	    int new_size, chunk_count;
-
-            offset += 4;
-            offset += 200;
-
-	    chunk_count = (count-204)/40;
-	    new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
-	    s->types = g_realloc(s->types, new_size/2);
-	    s->offsets = g_realloc(s->offsets, new_size);
-	    s->lengths = g_realloc(s->lengths, new_size);
-	    s->sectors = g_realloc(s->sectors, new_size);
-	    s->sectorcounts = g_realloc(s->sectorcounts, new_size);
-
-	    for(i=s->n_chunks;i<s->n_chunks+chunk_count;i++) {
-		s->types[i] = read_uint32(bs, offset);
-		offset += 4;
-		if(s->types[i]!=0x80000005 && s->types[i]!=1 && s->types[i]!=2) {
-		    if(s->types[i]==0xffffffff) {
-			last_in_offset = s->offsets[i-1]+s->lengths[i-1];
-			last_out_offset = s->sectors[i-1]+s->sectorcounts[i-1];
-		    }
-		    chunk_count--;
-		    i--;
-		    offset += 36;
-		    continue;
-		}
-		offset += 4;
-
-		s->sectors[i] = last_out_offset+read_off(bs, offset);
-		offset += 8;
-
-		s->sectorcounts[i] = read_off(bs, offset);
-		offset += 8;
-
-		s->offsets[i] = last_in_offset+read_off(bs, offset);
-		offset += 8;
-
-		s->lengths[i] = read_off(bs, offset);
-		offset += 8;
-
-		if(s->lengths[i]>max_compressed_size)
-		    max_compressed_size = s->lengths[i];
-		if(s->sectorcounts[i]>max_sectors_per_chunk)
-		    max_sectors_per_chunk = s->sectorcounts[i];
-	    }
-	    s->n_chunks+=chunk_count;
-	}
-    }
-
-    /* initialize zlib engine */
-    s->compressed_chunk = g_malloc(max_compressed_size+1);
-    s->uncompressed_chunk = g_malloc(512*max_sectors_per_chunk);
-    if(inflateInit(&s->zstream) != Z_OK)
-	goto fail;
-
-    s->current_chunk = s->n_chunks;
-
-    return 0;
-fail:
-    return -1;
-}
-
-static inline int is_sector_in_chunk(BDRVDMGState* s,
-		uint32_t chunk_num,int sector_num)
-{
-    if(chunk_num>=s->n_chunks || s->sectors[chunk_num]>sector_num ||
-	    s->sectors[chunk_num]+s->sectorcounts[chunk_num]<=sector_num)
-	return 0;
-    else
-	return -1;
-}
-
-static inline uint32_t search_chunk(BDRVDMGState* s,int sector_num)
-{
-    /* binary search */
-    uint32_t chunk1=0,chunk2=s->n_chunks,chunk3;
-    while(chunk1!=chunk2) {
-	chunk3 = (chunk1+chunk2)/2;
-	if(s->sectors[chunk3]>sector_num)
-	    chunk2 = chunk3;
-	else if(s->sectors[chunk3]+s->sectorcounts[chunk3]>sector_num)
-	    return chunk3;
-	else
-	    chunk1 = chunk3;
-    }
-    return s->n_chunks; /* error */
-}
-
-static inline int dmg_read_chunk(BlockDriverState *bs, int sector_num)
-{
-    BDRVDMGState *s = bs->opaque;
-
-    if(!is_sector_in_chunk(s,s->current_chunk,sector_num)) {
-	int ret;
-	uint32_t chunk = search_chunk(s,sector_num);
-
-	if(chunk>=s->n_chunks)
-	    return -1;
-
-	s->current_chunk = s->n_chunks;
-	switch(s->types[chunk]) {
-	case 0x80000005: { /* zlib compressed */
-	    int i;
-
-	    /* we need to buffer, because only the chunk as whole can be
-	     * inflated. */
-	    i=0;
-	    do {
-                ret = bdrv_pread(bs->file, s->offsets[chunk] + i,
-                                 s->compressed_chunk+i, s->lengths[chunk]-i);
-		if(ret<0 && errno==EINTR)
-		    ret=0;
-		i+=ret;
-	    } while(ret>=0 && ret+i<s->lengths[chunk]);
-
-	    if (ret != s->lengths[chunk])
-		return -1;
-
-	    s->zstream.next_in = s->compressed_chunk;
-	    s->zstream.avail_in = s->lengths[chunk];
-	    s->zstream.next_out = s->uncompressed_chunk;
-	    s->zstream.avail_out = 512*s->sectorcounts[chunk];
-	    ret = inflateReset(&s->zstream);
-	    if(ret != Z_OK)
-		return -1;
-	    ret = inflate(&s->zstream, Z_FINISH);
-	    if(ret != Z_STREAM_END || s->zstream.total_out != 512*s->sectorcounts[chunk])
-		return -1;
-	    break; }
-	case 1: /* copy */
-	    ret = bdrv_pread(bs->file, s->offsets[chunk],
-                             s->uncompressed_chunk, s->lengths[chunk]);
-	    if (ret != s->lengths[chunk])
-		return -1;
-	    break;
-	case 2: /* zero */
-	    memset(s->uncompressed_chunk, 0, 512*s->sectorcounts[chunk]);
-	    break;
-	}
-	s->current_chunk = chunk;
-    }
-    return 0;
-}
-
-static int dmg_read(BlockDriverState *bs, int64_t sector_num,
-                    uint8_t *buf, int nb_sectors)
-{
-    BDRVDMGState *s = bs->opaque;
-    int i;
-
-    for(i=0;i<nb_sectors;i++) {
-	uint32_t sector_offset_in_chunk;
-	if(dmg_read_chunk(bs, sector_num+i) != 0)
-	    return -1;
-	sector_offset_in_chunk = sector_num+i-s->sectors[s->current_chunk];
-	memcpy(buf+i*512,s->uncompressed_chunk+sector_offset_in_chunk*512,512);
-    }
-    return 0;
-}
-
-static void dmg_close(BlockDriverState *bs)
-{
-    BDRVDMGState *s = bs->opaque;
-    if(s->n_chunks>0) {
-	free(s->types);
-	free(s->offsets);
-	free(s->lengths);
-	free(s->sectors);
-	free(s->sectorcounts);
-    }
-    free(s->compressed_chunk);
-    free(s->uncompressed_chunk);
-    inflateEnd(&s->zstream);
-}
-
-static BlockDriver bdrv_dmg = {
-    .format_name	= "dmg",
-    .instance_size	= sizeof(BDRVDMGState),
-    .bdrv_probe		= dmg_probe,
-    .bdrv_open		= dmg_open,
-    .bdrv_read		= dmg_read,
-    .bdrv_close		= dmg_close,
-};
-
-static void bdrv_dmg_init(void)
-{
-    bdrv_register(&bdrv_dmg);
-}
-
-block_init(bdrv_dmg_init);
diff --git a/block/nbd.c b/block/nbd.c
deleted file mode 100644
index ccf0fd0..0000000
--- a/block/nbd.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * QEMU Block driver for  NBD
- *
- * Copyright (C) 2008 Bull S.A.S.
- *     Author: Laurent Vivier <Laurent.Vivier@bull.net>
- *
- * Some parts:
- *    Copyright (C) 2007 Anthony Liguori <anthony@codemonkey.ws>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu-common.h"
-#include "nbd.h"
-#include "qemu/module.h"
-
-#include <sys/types.h>
-#include <unistd.h>
-
-typedef struct BDRVNBDState {
-    int sock;
-    off_t size;
-    size_t blocksize;
-} BDRVNBDState;
-
-static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
-{
-    BDRVNBDState *s = bs->opaque;
-    const char *host;
-    const char *unixpath;
-    int sock;
-    off_t size;
-    size_t blocksize;
-    int ret;
-
-    if (!strstart(filename, "nbd:", &host))
-        return -EINVAL;
-
-    if (strstart(host, "unix:", &unixpath)) {
-
-        if (unixpath[0] != '/')
-            return -EINVAL;
-
-        sock = unix_socket_outgoing(unixpath);
-
-    } else {
-        uint16_t port;
-        char *p, *r;
-        char hostname[128];
-
-        pstrcpy(hostname, 128, host);
-
-        p = strchr(hostname, ':');
-        if (p == NULL)
-            return -EINVAL;
-
-        *p = '\0';
-        p++;
-
-        port = strtol(p, &r, 0);
-        if (r == p)
-            return -EINVAL;
-        sock = tcp_socket_outgoing(hostname, port);
-    }
-
-    if (sock == -1)
-        return -errno;
-
-    ret = nbd_receive_negotiate(sock, &size, &blocksize);
-    if (ret == -1)
-        return -errno;
-
-    s->sock = sock;
-    s->size = size;
-    s->blocksize = blocksize;
-
-    return 0;
-}
-
-static int nbd_read(BlockDriverState *bs, int64_t sector_num,
-                    uint8_t *buf, int nb_sectors)
-{
-    BDRVNBDState *s = bs->opaque;
-    struct nbd_request request;
-    struct nbd_reply reply;
-
-    request.type = NBD_CMD_READ;
-    request.handle = (uint64_t)(intptr_t)bs;
-    request.from = sector_num * 512;;
-    request.len = nb_sectors * 512;
-
-    if (nbd_send_request(s->sock, &request) == -1)
-        return -errno;
-
-    if (nbd_receive_reply(s->sock, &reply) == -1)
-        return -errno;
-
-    if (reply.error !=0)
-        return -reply.error;
-
-    if (reply.handle != request.handle)
-        return -EIO;
-
-    if (nbd_wr_sync(s->sock, buf, request.len, 1) != request.len)
-        return -EIO;
-
-    return 0;
-}
-
-static int nbd_write(BlockDriverState *bs, int64_t sector_num,
-                     const uint8_t *buf, int nb_sectors)
-{
-    BDRVNBDState *s = bs->opaque;
-    struct nbd_request request;
-    struct nbd_reply reply;
-
-    request.type = NBD_CMD_WRITE;
-    request.handle = (uint64_t)(intptr_t)bs;
-    request.from = sector_num * 512;;
-    request.len = nb_sectors * 512;
-
-    if (nbd_send_request(s->sock, &request) == -1)
-        return -errno;
-
-    if (nbd_wr_sync(s->sock, (uint8_t*)buf, request.len, 0) != request.len)
-        return -EIO;
-
-    if (nbd_receive_reply(s->sock, &reply) == -1)
-        return -errno;
-
-    if (reply.error !=0)
-        return -reply.error;
-
-    if (reply.handle != request.handle)
-        return -EIO;
-
-    return 0;
-}
-
-static void nbd_close(BlockDriverState *bs)
-{
-    BDRVNBDState *s = bs->opaque;
-    struct nbd_request request;
-
-    request.type = NBD_CMD_DISC;
-    request.handle = (uint64_t)(intptr_t)bs;
-    request.from = 0;
-    request.len = 0;
-    nbd_send_request(s->sock, &request);
-
-    close(s->sock);
-}
-
-static int64_t nbd_getlength(BlockDriverState *bs)
-{
-    BDRVNBDState *s = bs->opaque;
-
-    return s->size;
-}
-
-static BlockDriver bdrv_nbd = {
-    .format_name	= "nbd",
-    .instance_size	= sizeof(BDRVNBDState),
-    .bdrv_file_open	= nbd_open,
-    .bdrv_read		= nbd_read,
-    .bdrv_write		= nbd_write,
-    .bdrv_close		= nbd_close,
-    .bdrv_getlength	= nbd_getlength,
-    .protocol_name	= "nbd",
-};
-
-static void bdrv_nbd_init(void)
-{
-    bdrv_register(&bdrv_nbd);
-}
-
-block_init(bdrv_nbd_init);
diff --git a/block/parallels.c b/block/parallels.c
deleted file mode 100644
index 9aed8c5..0000000
--- a/block/parallels.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Block driver for Parallels disk image format
- *
- * Copyright (c) 2007 Alex Beregszaszi
- *
- * This code is based on comparing different disk images created by Parallels.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "qemu/module.h"
-
-/**************************************************************/
-
-#define HEADER_MAGIC "WithoutFreeSpace"
-#define HEADER_VERSION 2
-#define HEADER_SIZE 64
-
-// always little-endian
-struct parallels_header {
-    char magic[16]; // "WithoutFreeSpace"
-    uint32_t version;
-    uint32_t heads;
-    uint32_t cylinders;
-    uint32_t tracks;
-    uint32_t catalog_entries;
-    uint32_t nb_sectors;
-    char padding[24];
-} __attribute__((packed));
-
-typedef struct BDRVParallelsState {
-
-    uint32_t *catalog_bitmap;
-    int catalog_size;
-
-    int tracks;
-} BDRVParallelsState;
-
-static int parallels_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
-    const struct parallels_header *ph = (const void *)buf;
-
-    if (buf_size < HEADER_SIZE)
-	return 0;
-
-    if (!memcmp(ph->magic, HEADER_MAGIC, 16) &&
-	(le32_to_cpu(ph->version) == HEADER_VERSION))
-	return 100;
-
-    return 0;
-}
-
-static int parallels_open(BlockDriverState *bs, int flags)
-{
-    BDRVParallelsState *s = bs->opaque;
-    int i;
-    struct parallels_header ph;
-
-    bs->read_only = 1; // no write support yet
-
-    if (bdrv_pread(bs->file, 0, &ph, sizeof(ph)) != sizeof(ph))
-        goto fail;
-
-    if (memcmp(ph.magic, HEADER_MAGIC, 16) ||
-	(le32_to_cpu(ph.version) != HEADER_VERSION)) {
-        goto fail;
-    }
-
-    bs->total_sectors = le32_to_cpu(ph.nb_sectors);
-
-    s->tracks = le32_to_cpu(ph.tracks);
-
-    s->catalog_size = le32_to_cpu(ph.catalog_entries);
-    s->catalog_bitmap = g_malloc(s->catalog_size * 4);
-    if (bdrv_pread(bs->file, 64, s->catalog_bitmap, s->catalog_size * 4) !=
-	s->catalog_size * 4)
-	goto fail;
-    for (i = 0; i < s->catalog_size; i++)
-	le32_to_cpus(&s->catalog_bitmap[i]);
-
-    return 0;
-fail:
-    if (s->catalog_bitmap)
-	g_free(s->catalog_bitmap);
-    return -1;
-}
-
-static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
-{
-    BDRVParallelsState *s = bs->opaque;
-    uint32_t index, offset;
-
-    index = sector_num / s->tracks;
-    offset = sector_num % s->tracks;
-
-    /* not allocated */
-    if ((index > s->catalog_size) || (s->catalog_bitmap[index] == 0))
-	return -1;
-    return (uint64_t)(s->catalog_bitmap[index] + offset) * 512;
-}
-
-static int parallels_read(BlockDriverState *bs, int64_t sector_num,
-                    uint8_t *buf, int nb_sectors)
-{
-    while (nb_sectors > 0) {
-        int64_t position = seek_to_sector(bs, sector_num);
-        if (position >= 0) {
-            if (bdrv_pread(bs->file, position, buf, 512) != 512)
-                return -1;
-        } else {
-            memset(buf, 0, 512);
-        }
-        nb_sectors--;
-        sector_num++;
-        buf += 512;
-    }
-    return 0;
-}
-
-static void parallels_close(BlockDriverState *bs)
-{
-    BDRVParallelsState *s = bs->opaque;
-    g_free(s->catalog_bitmap);
-}
-
-static BlockDriver bdrv_parallels = {
-    .format_name	= "parallels",
-    .instance_size	= sizeof(BDRVParallelsState),
-    .bdrv_probe		= parallels_probe,
-    .bdrv_open		= parallels_open,
-    .bdrv_read		= parallels_read,
-    .bdrv_close		= parallels_close,
-};
-
-static void bdrv_parallels_init(void)
-{
-    bdrv_register(&bdrv_parallels);
-}
-
-block_init(bdrv_parallels_init);
diff --git a/block/qcow.c b/block/qcow.c
index 1ec7d64..7b22d32 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -23,6 +23,7 @@
  */
 #include "qemu-common.h"
 #include "block/block_int.h"
+#include "qemu/iov.h"
 #include "qemu/module.h"
 #include <zlib.h>
 #include "qemu/aes.h"
@@ -529,7 +530,7 @@
     if (qiov->niov > 1) {
         acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size);
         if (is_write)
-            qemu_iovec_to_buffer(qiov, acb->buf);
+            qemu_iovec_to_buf(qiov, 0, acb->buf, qiov->size);
     } else {
         acb->buf = (uint8_t *)qiov->iov->iov_base;
     }
@@ -623,7 +624,7 @@
 
 done:
     if (acb->qiov->niov > 1) {
-        qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
+        qemu_iovec_from_buf(acb->qiov, 0, acb->orig_buf, acb->qiov->size);
         qemu_vfree(acb->orig_buf);
     }
     acb->common.cb(acb->common.opaque, ret);
diff --git a/block/qcow2.c b/block/qcow2.c
index 752c06a..9a4a4d1 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -482,7 +482,7 @@
     return;
 done:
     if (acb->qiov->niov > 1) {
-        qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
+        qemu_iovec_from_buf(acb->qiov, 0, acb->orig_buf, acb->qiov->size);
         qemu_vfree(acb->orig_buf);
     }
     acb->common.cb(acb->common.opaque, ret);
@@ -504,7 +504,7 @@
     if (qiov->niov > 1) {
         acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size);
         if (is_write)
-            qemu_iovec_to_buffer(qiov, acb->buf);
+            qemu_iovec_to_buf(qiov, 0, acb->buf, qiov->size);
     } else {
         acb->buf = (uint8_t *)qiov->iov->iov_base;
     }
diff --git a/block/raw.c b/block/raw.c
index 3c618d9..bfe0915 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -152,7 +152,7 @@
         b->opaque = opaque;
 
         qemu_iovec_init(&b->qiov, qiov->nalloc);
-        qemu_iovec_concat(&b->qiov, qiov, qiov->size);
+        qemu_iovec_concat(&b->qiov, qiov, 0, qiov->size);
 
         b->qiov.size -= 512;
         b->qiov.iov[first_buf_index].iov_base += 512;
diff --git a/block/vmdk.c b/block/vmdk.c
deleted file mode 100644
index 0a22e14..0000000
--- a/block/vmdk.c
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
- * Block driver for the VMDK format
- *
- * Copyright (c) 2004 Fabrice Bellard
- * Copyright (c) 2005 Filip Navara
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "qemu/module.h"
-
-#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
-#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
-
-typedef struct {
-    uint32_t version;
-    uint32_t flags;
-    uint32_t disk_sectors;
-    uint32_t granularity;
-    uint32_t l1dir_offset;
-    uint32_t l1dir_size;
-    uint32_t file_sectors;
-    uint32_t cylinders;
-    uint32_t heads;
-    uint32_t sectors_per_track;
-} VMDK3Header;
-
-typedef struct {
-    uint32_t version;
-    uint32_t flags;
-    int64_t capacity;
-    int64_t granularity;
-    int64_t desc_offset;
-    int64_t desc_size;
-    int32_t num_gtes_per_gte;
-    int64_t rgd_offset;
-    int64_t gd_offset;
-    int64_t grain_offset;
-    char filler[1];
-    char check_bytes[4];
-} __attribute__((packed)) VMDK4Header;
-
-#define L2_CACHE_SIZE 16
-
-typedef struct BDRVVmdkState {
-    BlockDriverState *hd;
-    int64_t l1_table_offset;
-    int64_t l1_backup_table_offset;
-    uint32_t *l1_table;
-    uint32_t *l1_backup_table;
-    unsigned int l1_size;
-    uint32_t l1_entry_sectors;
-
-    unsigned int l2_size;
-    uint32_t *l2_cache;
-    uint32_t l2_cache_offsets[L2_CACHE_SIZE];
-    uint32_t l2_cache_counts[L2_CACHE_SIZE];
-
-    unsigned int cluster_sectors;
-    uint32_t parent_cid;
-} BDRVVmdkState;
-
-typedef struct VmdkMetaData {
-    uint32_t offset;
-    unsigned int l1_index;
-    unsigned int l2_index;
-    unsigned int l2_offset;
-    int valid;
-} VmdkMetaData;
-
-static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
-    uint32_t magic;
-
-    if (buf_size < 4)
-        return 0;
-    magic = be32_to_cpu(*(uint32_t *)buf);
-    if (magic == VMDK3_MAGIC ||
-        magic == VMDK4_MAGIC)
-        return 100;
-    else
-        return 0;
-}
-
-#define CHECK_CID 1
-
-#define SECTOR_SIZE 512
-#define DESC_SIZE 20*SECTOR_SIZE	// 20 sectors of 512 bytes each
-#define HEADER_SIZE 512   			// first sector of 512 bytes
-
-static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
-{
-    char desc[DESC_SIZE];
-    uint32_t cid;
-    const char *p_name, *cid_str;
-    size_t cid_str_size;
-
-    /* the descriptor offset = 0x200 */
-    if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
-        return 0;
-
-    if (parent) {
-        cid_str = "parentCID";
-        cid_str_size = sizeof("parentCID");
-    } else {
-        cid_str = "CID";
-        cid_str_size = sizeof("CID");
-    }
-
-    if ((p_name = strstr(desc,cid_str)) != NULL) {
-        p_name += cid_str_size;
-        sscanf(p_name,"%x",&cid);
-    }
-
-    return cid;
-}
-
-static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
-{
-    char desc[DESC_SIZE], tmp_desc[DESC_SIZE];
-    char *p_name, *tmp_str;
-
-    /* the descriptor offset = 0x200 */
-    if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
-        return -1;
-
-    tmp_str = strstr(desc,"parentCID");
-    pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);
-    if ((p_name = strstr(desc,"CID")) != NULL) {
-        p_name += sizeof("CID");
-        snprintf(p_name, sizeof(desc) - (p_name - desc), "%x\n", cid);
-        pstrcat(desc, sizeof(desc), tmp_desc);
-    }
-
-    if (bdrv_pwrite_sync(bs->file, 0x200, desc, DESC_SIZE) < 0)
-        return -1;
-    return 0;
-}
-
-static int vmdk_is_cid_valid(BlockDriverState *bs)
-{
-#ifdef CHECK_CID
-    BDRVVmdkState *s = bs->opaque;
-    BlockDriverState *p_bs = bs->backing_hd;
-    uint32_t cur_pcid;
-
-    if (p_bs) {
-        cur_pcid = vmdk_read_cid(p_bs,0);
-        if (s->parent_cid != cur_pcid)
-            // CID not valid
-            return 0;
-    }
-#endif
-    // CID valid
-    return 1;
-}
-
-static int vmdk_snapshot_create(const char *filename, const char *backing_file)
-{
-    int snp_fd, p_fd;
-    int ret;
-    uint32_t p_cid;
-    char *p_name, *gd_buf, *rgd_buf;
-    const char *real_filename, *temp_str;
-    VMDK4Header header;
-    uint32_t gde_entries, gd_size;
-    int64_t gd_offset, rgd_offset, capacity, gt_size;
-    char p_desc[DESC_SIZE], s_desc[DESC_SIZE], hdr[HEADER_SIZE];
-    static const char desc_template[] =
-    "# Disk DescriptorFile\n"
-    "version=1\n"
-    "CID=%x\n"
-    "parentCID=%x\n"
-    "createType=\"monolithicSparse\"\n"
-    "parentFileNameHint=\"%s\"\n"
-    "\n"
-    "# Extent description\n"
-    "RW %u SPARSE \"%s\"\n"
-    "\n"
-    "# The Disk Data Base \n"
-    "#DDB\n"
-    "\n";
-
-    snp_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644);
-    if (snp_fd < 0)
-        return -errno;
-    p_fd = open(backing_file, O_RDONLY | O_BINARY | O_LARGEFILE);
-    if (p_fd < 0) {
-        close(snp_fd);
-        return -errno;
-    }
-
-    /* read the header */
-    if (lseek(p_fd, 0x0, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-    if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE) {
-        ret = -errno;
-        goto fail;
-    }
-
-    /* write the header */
-    if (lseek(snp_fd, 0x0, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-    if (write(snp_fd, hdr, HEADER_SIZE) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-
-    memset(&header, 0, sizeof(header));
-    memcpy(&header,&hdr[4], sizeof(header)); // skip the VMDK4_MAGIC
-
-    if (ftruncate(snp_fd, header.grain_offset << 9)) {
-        ret = -errno;
-        goto fail;
-    }
-    /* the descriptor offset = 0x200 */
-    if (lseek(p_fd, 0x200, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-    if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE) {
-        ret = -errno;
-        goto fail;
-    }
-
-    if ((p_name = strstr(p_desc,"CID")) != NULL) {
-        p_name += sizeof("CID");
-        sscanf(p_name,"%x",&p_cid);
-    }
-
-    real_filename = filename;
-    if ((temp_str = strrchr(real_filename, '\\')) != NULL)
-        real_filename = temp_str + 1;
-    if ((temp_str = strrchr(real_filename, '/')) != NULL)
-        real_filename = temp_str + 1;
-    if ((temp_str = strrchr(real_filename, ':')) != NULL)
-        real_filename = temp_str + 1;
-
-    snprintf(s_desc, sizeof(s_desc), desc_template, p_cid, p_cid, backing_file,
-             (uint32_t)header.capacity, real_filename);
-
-    /* write the descriptor */
-    if (lseek(snp_fd, 0x200, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-    if (write(snp_fd, s_desc, strlen(s_desc)) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-
-    gd_offset = header.gd_offset * SECTOR_SIZE;     // offset of GD table
-    rgd_offset = header.rgd_offset * SECTOR_SIZE;   // offset of RGD table
-    capacity = header.capacity * SECTOR_SIZE;       // Extent size
-    /*
-     * Each GDE span 32M disk, means:
-     * 512 GTE per GT, each GTE points to grain
-     */
-    gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * SECTOR_SIZE;
-    if (!gt_size) {
-        ret = -EINVAL;
-        goto fail;
-    }
-    gde_entries = (uint32_t)(capacity / gt_size);  // number of gde/rgde
-    gd_size = gde_entries * sizeof(uint32_t);
-
-    /* write RGD */
-    rgd_buf = g_malloc(gd_size);
-    if (lseek(p_fd, rgd_offset, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail_rgd;
-    }
-    if (read(p_fd, rgd_buf, gd_size) != gd_size) {
-        ret = -errno;
-        goto fail_rgd;
-    }
-    if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail_rgd;
-    }
-    if (write(snp_fd, rgd_buf, gd_size) == -1) {
-        ret = -errno;
-        goto fail_rgd;
-    }
-
-    /* write GD */
-    gd_buf = g_malloc(gd_size);
-    if (lseek(p_fd, gd_offset, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail_gd;
-    }
-    if (read(p_fd, gd_buf, gd_size) != gd_size) {
-        ret = -errno;
-        goto fail_gd;
-    }
-    if (lseek(snp_fd, gd_offset, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail_gd;
-    }
-    if (write(snp_fd, gd_buf, gd_size) == -1) {
-        ret = -errno;
-        goto fail_gd;
-    }
-    ret = 0;
-
-fail_gd:
-    g_free(gd_buf);
-fail_rgd:
-    g_free(rgd_buf);
-fail:
-    close(p_fd);
-    close(snp_fd);
-    return ret;
-}
-
-static int vmdk_parent_open(BlockDriverState *bs)
-{
-    char *p_name;
-    char desc[DESC_SIZE];
-
-    /* the descriptor offset = 0x200 */
-    if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
-        return -1;
-
-    if ((p_name = strstr(desc,"parentFileNameHint")) != NULL) {
-        char *end_name;
-
-        p_name += sizeof("parentFileNameHint") + 1;
-        if ((end_name = strchr(p_name,'\"')) == NULL)
-            return -1;
-        if ((end_name - p_name) > sizeof (bs->backing_file) - 1)
-            return -1;
-
-        pstrcpy(bs->backing_file, end_name - p_name + 1, p_name);
-    }
-
-    return 0;
-}
-
-static int vmdk_open(BlockDriverState *bs, int flags)
-{
-    BDRVVmdkState *s = bs->opaque;
-    uint32_t magic;
-    int l1_size, i;
-
-    if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic))
-        goto fail;
-
-    magic = be32_to_cpu(magic);
-    if (magic == VMDK3_MAGIC) {
-        VMDK3Header header;
-
-        if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header))
-            goto fail;
-        s->cluster_sectors = le32_to_cpu(header.granularity);
-        s->l2_size = 1 << 9;
-        s->l1_size = 1 << 6;
-        bs->total_sectors = le32_to_cpu(header.disk_sectors);
-        s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9;
-        s->l1_backup_table_offset = 0;
-        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
-    } else if (magic == VMDK4_MAGIC) {
-        VMDK4Header header;
-
-        if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header))
-            goto fail;
-        bs->total_sectors = le64_to_cpu(header.capacity);
-        s->cluster_sectors = le64_to_cpu(header.granularity);
-        s->l2_size = le32_to_cpu(header.num_gtes_per_gte);
-        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
-        if (s->l1_entry_sectors <= 0)
-            goto fail;
-        s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)
-            / s->l1_entry_sectors;
-        s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;
-        s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;
-
-        // try to open parent images, if exist
-        if (vmdk_parent_open(bs) != 0)
-            goto fail;
-        // write the CID once after the image creation
-        s->parent_cid = vmdk_read_cid(bs,1);
-    } else {
-        goto fail;
-    }
-
-    /* read the L1 table */
-    l1_size = s->l1_size * sizeof(uint32_t);
-    s->l1_table = g_malloc(l1_size);
-    if (bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, l1_size) != l1_size)
-        goto fail;
-    for(i = 0; i < s->l1_size; i++) {
-        le32_to_cpus(&s->l1_table[i]);
-    }
-
-    if (s->l1_backup_table_offset) {
-        s->l1_backup_table = g_malloc(l1_size);
-        if (bdrv_pread(bs->file, s->l1_backup_table_offset, s->l1_backup_table, l1_size) != l1_size)
-            goto fail;
-        for(i = 0; i < s->l1_size; i++) {
-            le32_to_cpus(&s->l1_backup_table[i]);
-        }
-    }
-
-    s->l2_cache = g_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
-    return 0;
- fail:
-    g_free(s->l1_backup_table);
-    g_free(s->l1_table);
-    g_free(s->l2_cache);
-    return -1;
-}
-
-static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
-                                   uint64_t offset, int allocate);
-
-static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset,
-                             uint64_t offset, int allocate)
-{
-    BDRVVmdkState *s = bs->opaque;
-    uint8_t  whole_grain[s->cluster_sectors*512];        // 128 sectors * 512 bytes each = grain size 64KB
-
-    // we will be here if it's first write on non-exist grain(cluster).
-    // try to read from parent image, if exist
-    if (bs->backing_hd) {
-        int ret;
-
-        if (!vmdk_is_cid_valid(bs))
-            return -1;
-
-        ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
-            s->cluster_sectors);
-        if (ret < 0) {
-            return -1;
-        }
-
-        //Write grain only into the active image
-        ret = bdrv_write(bs->file, cluster_offset, whole_grain,
-            s->cluster_sectors);
-        if (ret < 0) {
-            return -1;
-        }
-    }
-    return 0;
-}
-
-static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data)
-{
-    BDRVVmdkState *s = bs->opaque;
-
-    /* update L2 table */
-    if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
-                    &(m_data->offset), sizeof(m_data->offset)) < 0)
-        return -1;
-    /* update backup L2 table */
-    if (s->l1_backup_table_offset != 0) {
-        m_data->l2_offset = s->l1_backup_table[m_data->l1_index];
-        if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
-                        &(m_data->offset), sizeof(m_data->offset)) < 0)
-            return -1;
-    }
-
-    return 0;
-}
-
-static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
-                                   uint64_t offset, int allocate)
-{
-    BDRVVmdkState *s = bs->opaque;
-    unsigned int l1_index, l2_offset, l2_index;
-    int min_index, i, j;
-    uint32_t min_count, *l2_table, tmp = 0;
-    uint64_t cluster_offset;
-
-    if (m_data)
-        m_data->valid = 0;
-
-    l1_index = (offset >> 9) / s->l1_entry_sectors;
-    if (l1_index >= s->l1_size)
-        return 0;
-    l2_offset = s->l1_table[l1_index];
-    if (!l2_offset)
-        return 0;
-    for(i = 0; i < L2_CACHE_SIZE; i++) {
-        if (l2_offset == s->l2_cache_offsets[i]) {
-            /* increment the hit count */
-            if (++s->l2_cache_counts[i] == 0xffffffff) {
-                for(j = 0; j < L2_CACHE_SIZE; j++) {
-                    s->l2_cache_counts[j] >>= 1;
-                }
-            }
-            l2_table = s->l2_cache + (i * s->l2_size);
-            goto found;
-        }
-    }
-    /* not found: load a new entry in the least used one */
-    min_index = 0;
-    min_count = 0xffffffff;
-    for(i = 0; i < L2_CACHE_SIZE; i++) {
-        if (s->l2_cache_counts[i] < min_count) {
-            min_count = s->l2_cache_counts[i];
-            min_index = i;
-        }
-    }
-    l2_table = s->l2_cache + (min_index * s->l2_size);
-    if (bdrv_pread(bs->file, (int64_t)l2_offset * 512, l2_table, s->l2_size * sizeof(uint32_t)) !=
-                                                                        s->l2_size * sizeof(uint32_t))
-        return 0;
-
-    s->l2_cache_offsets[min_index] = l2_offset;
-    s->l2_cache_counts[min_index] = 1;
- found:
-    l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
-    cluster_offset = le32_to_cpu(l2_table[l2_index]);
-
-    if (!cluster_offset) {
-        if (!allocate)
-            return 0;
-
-        // Avoid the L2 tables update for the images that have snapshots.
-        cluster_offset = bdrv_getlength(bs->file);
-        bdrv_truncate(bs->file, cluster_offset + (s->cluster_sectors << 9));
-
-        cluster_offset >>= 9;
-        tmp = cpu_to_le32(cluster_offset);
-        l2_table[l2_index] = tmp;
-
-        /* First of all we write grain itself, to avoid race condition
-         * that may to corrupt the image.
-         * This problem may occur because of insufficient space on host disk
-         * or inappropriate VM shutdown.
-         */
-        if (get_whole_cluster(bs, cluster_offset, offset, allocate) == -1)
-            return 0;
-
-        if (m_data) {
-            m_data->offset = tmp;
-            m_data->l1_index = l1_index;
-            m_data->l2_index = l2_index;
-            m_data->l2_offset = l2_offset;
-            m_data->valid = 1;
-        }
-    }
-    cluster_offset <<= 9;
-    return cluster_offset;
-}
-
-static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
-                             int nb_sectors, int *pnum)
-{
-    BDRVVmdkState *s = bs->opaque;
-    int index_in_cluster, n;
-    uint64_t cluster_offset;
-
-    cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
-    index_in_cluster = sector_num % s->cluster_sectors;
-    n = s->cluster_sectors - index_in_cluster;
-    if (n > nb_sectors)
-        n = nb_sectors;
-    *pnum = n;
-    return (cluster_offset != 0);
-}
-
-static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
-                    uint8_t *buf, int nb_sectors)
-{
-    BDRVVmdkState *s = bs->opaque;
-    int index_in_cluster, n, ret;
-    uint64_t cluster_offset;
-
-    while (nb_sectors > 0) {
-        cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
-        index_in_cluster = sector_num % s->cluster_sectors;
-        n = s->cluster_sectors - index_in_cluster;
-        if (n > nb_sectors)
-            n = nb_sectors;
-        if (!cluster_offset) {
-            // try to read from parent image, if exist
-            if (bs->backing_hd) {
-                if (!vmdk_is_cid_valid(bs))
-                    return -1;
-                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
-                if (ret < 0)
-                    return -1;
-            } else {
-                memset(buf, 0, 512 * n);
-            }
-        } else {
-            if(bdrv_pread(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
-                return -1;
-        }
-        nb_sectors -= n;
-        sector_num += n;
-        buf += n * 512;
-    }
-    return 0;
-}
-
-static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
-                     const uint8_t *buf, int nb_sectors)
-{
-    BDRVVmdkState *s = bs->opaque;
-    VmdkMetaData m_data;
-    int index_in_cluster, n;
-    uint64_t cluster_offset;
-    static int cid_update = 0;
-
-    if (sector_num > bs->total_sectors) {
-        fprintf(stderr,
-                "(VMDK) Wrong offset: sector_num=0x%" PRIx64
-                " total_sectors=0x%" PRIx64 "\n",
-                sector_num, bs->total_sectors);
-        return -1;
-    }
-
-    while (nb_sectors > 0) {
-        index_in_cluster = sector_num & (s->cluster_sectors - 1);
-        n = s->cluster_sectors - index_in_cluster;
-        if (n > nb_sectors)
-            n = nb_sectors;
-        cluster_offset = get_cluster_offset(bs, &m_data, sector_num << 9, 1);
-        if (!cluster_offset)
-            return -1;
-
-        if (bdrv_pwrite(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
-            return -1;
-        if (m_data.valid) {
-            /* update L2 tables */
-            if (vmdk_L2update(bs, &m_data) == -1)
-                return -1;
-        }
-        nb_sectors -= n;
-        sector_num += n;
-        buf += n * 512;
-
-        // update CID on the first write every time the virtual disk is opened
-        if (!cid_update) {
-            vmdk_write_cid(bs, time(NULL));
-            cid_update++;
-        }
-    }
-    return 0;
-}
-
-static int vmdk_create(const char *filename, QEMUOptionParameter *options)
-{
-    int fd, i;
-    VMDK4Header header;
-    uint32_t tmp, magic, grains, gd_size, gt_size, gt_count;
-    static const char desc_template[] =
-        "# Disk DescriptorFile\n"
-        "version=1\n"
-        "CID=%x\n"
-        "parentCID=ffffffff\n"
-        "createType=\"monolithicSparse\"\n"
-        "\n"
-        "# Extent description\n"
-        "RW %" PRId64 " SPARSE \"%s\"\n"
-        "\n"
-        "# The Disk Data Base \n"
-        "#DDB\n"
-        "\n"
-        "ddb.virtualHWVersion = \"%d\"\n"
-        "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
-        "ddb.geometry.heads = \"16\"\n"
-        "ddb.geometry.sectors = \"63\"\n"
-        "ddb.adapterType = \"ide\"\n";
-    char desc[1024];
-    const char *real_filename, *temp_str;
-    int64_t total_size = 0;
-    const char *backing_file = NULL;
-    int flags = 0;
-    int ret;
-
-    // Read out options
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            total_size = options->value.n / 512;
-        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-            backing_file = options->value.s;
-        } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
-            flags |= options->value.n ? BLOCK_FLAG_COMPAT6: 0;
-        }
-        options++;
-    }
-
-    /* XXX: add support for backing file */
-    if (backing_file) {
-        return vmdk_snapshot_create(filename, backing_file);
-    }
-
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
-              0644);
-    if (fd < 0)
-        return -errno;
-    magic = cpu_to_be32(VMDK4_MAGIC);
-    memset(&header, 0, sizeof(header));
-    header.version = cpu_to_le32(1);
-    header.flags = cpu_to_le32(3); /* ?? */
-    header.capacity = cpu_to_le64(total_size);
-    header.granularity = cpu_to_le64(128);
-    header.num_gtes_per_gte = cpu_to_le32(512);
-
-    grains = (total_size + header.granularity - 1) / header.granularity;
-    gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
-    gt_count = (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
-    gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9;
-
-    header.desc_offset = 1;
-    header.desc_size = 20;
-    header.rgd_offset = header.desc_offset + header.desc_size;
-    header.gd_offset = header.rgd_offset + gd_size + (gt_size * gt_count);
-    header.grain_offset =
-       ((header.gd_offset + gd_size + (gt_size * gt_count) +
-         header.granularity - 1) / header.granularity) *
-        header.granularity;
-
-    header.desc_offset = cpu_to_le64(header.desc_offset);
-    header.desc_size = cpu_to_le64(header.desc_size);
-    header.rgd_offset = cpu_to_le64(header.rgd_offset);
-    header.gd_offset = cpu_to_le64(header.gd_offset);
-    header.grain_offset = cpu_to_le64(header.grain_offset);
-
-    header.check_bytes[0] = 0xa;
-    header.check_bytes[1] = 0x20;
-    header.check_bytes[2] = 0xd;
-    header.check_bytes[3] = 0xa;
-
-    /* write all the data */
-    ret = qemu_write_full(fd, &magic, sizeof(magic));
-    if (ret != sizeof(magic)) {
-        ret = -errno;
-        goto exit;
-    }
-    ret = qemu_write_full(fd, &header, sizeof(header));
-    if (ret != sizeof(header)) {
-        ret = -errno;
-        goto exit;
-    }
-
-    ret = ftruncate(fd, header.grain_offset << 9);
-    if (ret < 0) {
-        ret = -errno;
-        goto exit;
-    }
-
-    /* write grain directory */
-    lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET);
-    for (i = 0, tmp = header.rgd_offset + gd_size;
-         i < gt_count; i++, tmp += gt_size) {
-        ret = qemu_write_full(fd, &tmp, sizeof(tmp));
-        if (ret != sizeof(tmp)) {
-            ret = -errno;
-            goto exit;
-        }
-    }
-
-    /* write backup grain directory */
-    lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET);
-    for (i = 0, tmp = header.gd_offset + gd_size;
-         i < gt_count; i++, tmp += gt_size) {
-        ret = qemu_write_full(fd, &tmp, sizeof(tmp));
-        if (ret != sizeof(tmp)) {
-            ret = -errno;
-            goto exit;
-        }
-    }
-
-    /* compose the descriptor */
-    real_filename = filename;
-    if ((temp_str = strrchr(real_filename, '\\')) != NULL)
-        real_filename = temp_str + 1;
-    if ((temp_str = strrchr(real_filename, '/')) != NULL)
-        real_filename = temp_str + 1;
-    if ((temp_str = strrchr(real_filename, ':')) != NULL)
-        real_filename = temp_str + 1;
-    snprintf(desc, sizeof(desc), desc_template, (unsigned int)time(NULL),
-             total_size, real_filename,
-             (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
-             total_size / (int64_t)(63 * 16));
-
-    /* write the descriptor */
-    lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET);
-    ret = qemu_write_full(fd, desc, strlen(desc));
-    if (ret != strlen(desc)) {
-        ret = -errno;
-        goto exit;
-    }
-
-    ret = 0;
-exit:
-    close(fd);
-    return ret;
-}
-
-static void vmdk_close(BlockDriverState *bs)
-{
-    BDRVVmdkState *s = bs->opaque;
-
-    g_free(s->l1_table);
-    g_free(s->l2_cache);
-}
-
-static void vmdk_flush(BlockDriverState *bs)
-{
-    bdrv_flush(bs->file);
-}
-
-
-static QEMUOptionParameter vmdk_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    {
-        .name = BLOCK_OPT_BACKING_FILE,
-        .type = OPT_STRING,
-        .help = "File name of a base image"
-    },
-    {
-        .name = BLOCK_OPT_COMPAT6,
-        .type = OPT_FLAG,
-        .help = "VMDK version 6 image"
-    },
-    { NULL }
-};
-
-static BlockDriver bdrv_vmdk = {
-    .format_name	= "vmdk",
-    .instance_size	= sizeof(BDRVVmdkState),
-    .bdrv_probe		= vmdk_probe,
-    .bdrv_open      = vmdk_open,
-    .bdrv_read		= vmdk_read,
-    .bdrv_write		= vmdk_write,
-    .bdrv_close		= vmdk_close,
-    .bdrv_create	= vmdk_create,
-    .bdrv_flush		= vmdk_flush,
-    .bdrv_is_allocated	= vmdk_is_allocated,
-
-    .create_options = vmdk_create_options,
-};
-
-static void bdrv_vmdk_init(void)
-{
-    bdrv_register(&bdrv_vmdk);
-}
-
-block_init(bdrv_vmdk_init);
diff --git a/block/vpc.c b/block/vpc.c
deleted file mode 100644
index 9adaa75..0000000
--- a/block/vpc.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * Block driver for Connectix / Microsoft Virtual PC images
- *
- * Copyright (c) 2005 Alex Beregszaszi
- * Copyright (c) 2009 Kevin Wolf <kwolf@suse.de>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "qemu/module.h"
-
-/**************************************************************/
-
-#define HEADER_SIZE 512
-
-//#define CACHE
-
-enum vhd_type {
-    VHD_FIXED           = 2,
-    VHD_DYNAMIC         = 3,
-    VHD_DIFFERENCING    = 4,
-};
-
-// Seconds since Jan 1, 2000 0:00:00 (UTC)
-#define VHD_TIMESTAMP_BASE 946684800
-
-// always big-endian
-struct vhd_footer {
-    char        creator[8]; // "conectix"
-    uint32_t    features;
-    uint32_t    version;
-
-    // Offset of next header structure, 0xFFFFFFFF if none
-    uint64_t    data_offset;
-
-    // Seconds since Jan 1, 2000 0:00:00 (UTC)
-    uint32_t    timestamp;
-
-    char        creator_app[4]; // "vpc "
-    uint16_t    major;
-    uint16_t    minor;
-    char        creator_os[4]; // "Wi2k"
-
-    uint64_t    orig_size;
-    uint64_t    size;
-
-    uint16_t    cyls;
-    uint8_t     heads;
-    uint8_t     secs_per_cyl;
-
-    uint32_t    type;
-
-    // Checksum of the Hard Disk Footer ("one's complement of the sum of all
-    // the bytes in the footer without the checksum field")
-    uint32_t    checksum;
-
-    // UUID used to identify a parent hard disk (backing file)
-    uint8_t     uuid[16];
-
-    uint8_t     in_saved_state;
-};
-
-struct vhd_dyndisk_header {
-    char        magic[8]; // "cxsparse"
-
-    // Offset of next header structure, 0xFFFFFFFF if none
-    uint64_t    data_offset;
-
-    // Offset of the Block Allocation Table (BAT)
-    uint64_t    table_offset;
-
-    uint32_t    version;
-    uint32_t    max_table_entries; // 32bit/entry
-
-    // 2 MB by default, must be a power of two
-    uint32_t    block_size;
-
-    uint32_t    checksum;
-    uint8_t     parent_uuid[16];
-    uint32_t    parent_timestamp;
-    uint32_t    reserved;
-
-    // Backing file name (in UTF-16)
-    uint8_t     parent_name[512];
-
-    struct {
-        uint32_t    platform;
-        uint32_t    data_space;
-        uint32_t    data_length;
-        uint32_t    reserved;
-        uint64_t    data_offset;
-    } parent_locator[8];
-};
-
-typedef struct BDRVVPCState {
-    BlockDriverState *hd;
-
-    uint8_t footer_buf[HEADER_SIZE];
-    uint64_t free_data_block_offset;
-    int max_table_entries;
-    uint32_t *pagetable;
-    uint64_t bat_offset;
-    uint64_t last_bitmap_offset;
-
-    uint32_t block_size;
-    uint32_t bitmap_size;
-
-#ifdef CACHE
-    uint8_t *pageentry_u8;
-    uint32_t *pageentry_u32;
-    uint16_t *pageentry_u16;
-
-    uint64_t last_bitmap;
-#endif
-} BDRVVPCState;
-
-static uint32_t vpc_checksum(uint8_t* buf, size_t size)
-{
-    uint32_t res = 0;
-    int i;
-
-    for (i = 0; i < size; i++)
-        res += buf[i];
-
-    return ~res;
-}
-
-
-static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
-    if (buf_size >= 8 && !strncmp((char *)buf, "conectix", 8))
-	return 100;
-    return 0;
-}
-
-static int vpc_open(BlockDriverState *bs, int flags)
-{
-    BDRVVPCState *s = bs->opaque;
-    int i;
-    struct vhd_footer* footer;
-    struct vhd_dyndisk_header* dyndisk_header;
-    uint8_t buf[HEADER_SIZE];
-    uint32_t checksum;
-
-    if (bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE) != HEADER_SIZE)
-        goto fail;
-
-    footer = (struct vhd_footer*) s->footer_buf;
-    if (strncmp(footer->creator, "conectix", 8))
-        goto fail;
-
-    checksum = be32_to_cpu(footer->checksum);
-    footer->checksum = 0;
-    if (vpc_checksum(s->footer_buf, HEADER_SIZE) != checksum)
-        fprintf(stderr, "block-vpc: The header checksum of '%s' is "
-            "incorrect.\n", bs->filename);
-
-    // The visible size of a image in Virtual PC depends on the geometry
-    // rather than on the size stored in the footer (the size in the footer
-    // is too large usually)
-    bs->total_sectors = (int64_t)
-        be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
-
-    if (bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf, HEADER_SIZE)
-            != HEADER_SIZE)
-        goto fail;
-
-    dyndisk_header = (struct vhd_dyndisk_header*) buf;
-
-    if (strncmp(dyndisk_header->magic, "cxsparse", 8))
-        goto fail;
-
-
-    s->block_size = be32_to_cpu(dyndisk_header->block_size);
-    s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;
-
-    s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);
-    s->pagetable = g_malloc(s->max_table_entries * 4);
-
-    s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
-    if (bdrv_pread(bs->file, s->bat_offset, s->pagetable,
-            s->max_table_entries * 4) != s->max_table_entries * 4)
-	    goto fail;
-
-    s->free_data_block_offset =
-        (s->bat_offset + (s->max_table_entries * 4) + 511) & ~511;
-
-    for (i = 0; i < s->max_table_entries; i++) {
-        be32_to_cpus(&s->pagetable[i]);
-        if (s->pagetable[i] != 0xFFFFFFFF) {
-            int64_t next = (512 * (int64_t) s->pagetable[i]) +
-                s->bitmap_size + s->block_size;
-
-            if (next> s->free_data_block_offset)
-                s->free_data_block_offset = next;
-        }
-    }
-
-    s->last_bitmap_offset = (int64_t) -1;
-
-#ifdef CACHE
-    s->pageentry_u8 = g_malloc(512);
-    s->pageentry_u32 = s->pageentry_u8;
-    s->pageentry_u16 = s->pageentry_u8;
-    s->last_pagetable = -1;
-#endif
-
-    return 0;
- fail:
-    return -1;
-}
-
-/*
- * Returns the absolute byte offset of the given sector in the image file.
- * If the sector is not allocated, -1 is returned instead.
- *
- * The parameter write must be 1 if the offset will be used for a write
- * operation (the block bitmaps is updated then), 0 otherwise.
- */
-static inline int64_t get_sector_offset(BlockDriverState *bs,
-    int64_t sector_num, int write)
-{
-    BDRVVPCState *s = bs->opaque;
-    uint64_t offset = sector_num * 512;
-    uint64_t bitmap_offset, block_offset;
-    uint32_t pagetable_index, pageentry_index;
-
-    pagetable_index = offset / s->block_size;
-    pageentry_index = (offset % s->block_size) / 512;
-
-    if (pagetable_index >= s->max_table_entries || s->pagetable[pagetable_index] == 0xffffffff)
-        return -1; // not allocated
-
-    bitmap_offset = 512 * (uint64_t) s->pagetable[pagetable_index];
-    block_offset = bitmap_offset + s->bitmap_size + (512 * pageentry_index);
-
-    // We must ensure that we don't write to any sectors which are marked as
-    // unused in the bitmap. We get away with setting all bits in the block
-    // bitmap each time we write to a new block. This might cause Virtual PC to
-    // miss sparse read optimization, but it's not a problem in terms of
-    // correctness.
-    if (write && (s->last_bitmap_offset != bitmap_offset)) {
-        uint8_t bitmap[s->bitmap_size];
-
-        s->last_bitmap_offset = bitmap_offset;
-        memset(bitmap, 0xff, s->bitmap_size);
-        bdrv_pwrite_sync(bs->file, bitmap_offset, bitmap, s->bitmap_size);
-    }
-
-//    printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n",
-//	sector_num, pagetable_index, pageentry_index,
-//	bitmap_offset, block_offset);
-
-// disabled by reason
-#if 0
-#ifdef CACHE
-    if (bitmap_offset != s->last_bitmap)
-    {
-	lseek(s->fd, bitmap_offset, SEEK_SET);
-
-	s->last_bitmap = bitmap_offset;
-
-	// Scary! Bitmap is stored as big endian 32bit entries,
-	// while we used to look it up byte by byte
-	read(s->fd, s->pageentry_u8, 512);
-	for (i = 0; i < 128; i++)
-	    be32_to_cpus(&s->pageentry_u32[i]);
-    }
-
-    if ((s->pageentry_u8[pageentry_index / 8] >> (pageentry_index % 8)) & 1)
-	return -1;
-#else
-    lseek(s->fd, bitmap_offset + (pageentry_index / 8), SEEK_SET);
-
-    read(s->fd, &bitmap_entry, 1);
-
-    if ((bitmap_entry >> (pageentry_index % 8)) & 1)
-	return -1; // not allocated
-#endif
-#endif
-
-    return block_offset;
-}
-
-/*
- * Writes the footer to the end of the image file. This is needed when the
- * file grows as it overwrites the old footer
- *
- * Returns 0 on success and < 0 on error
- */
-static int rewrite_footer(BlockDriverState* bs)
-{
-    int ret;
-    BDRVVPCState *s = bs->opaque;
-    int64_t offset = s->free_data_block_offset;
-
-    ret = bdrv_pwrite_sync(bs->file, offset, s->footer_buf, HEADER_SIZE);
-    if (ret < 0)
-        return ret;
-
-    return 0;
-}
-
-/*
- * Allocates a new block. This involves writing a new footer and updating
- * the Block Allocation Table to use the space at the old end of the image
- * file (overwriting the old footer)
- *
- * Returns the sectors' offset in the image file on success and < 0 on error
- */
-static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
-{
-    BDRVVPCState *s = bs->opaque;
-    int64_t bat_offset;
-    uint32_t index, bat_value;
-    int ret;
-    uint8_t bitmap[s->bitmap_size];
-
-    // Check if sector_num is valid
-    if ((sector_num < 0) || (sector_num > bs->total_sectors))
-        return -1;
-
-    // Write entry into in-memory BAT
-    index = (sector_num * 512) / s->block_size;
-    if (s->pagetable[index] != 0xFFFFFFFF)
-        return -1;
-
-    s->pagetable[index] = s->free_data_block_offset / 512;
-
-    // Initialize the block's bitmap
-    memset(bitmap, 0xff, s->bitmap_size);
-    bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap,
-        s->bitmap_size);
-
-    // Write new footer (the old one will be overwritten)
-    s->free_data_block_offset += s->block_size + s->bitmap_size;
-    ret = rewrite_footer(bs);
-    if (ret < 0)
-        goto fail;
-
-    // Write BAT entry to disk
-    bat_offset = s->bat_offset + (4 * index);
-    bat_value = be32_to_cpu(s->pagetable[index]);
-    ret = bdrv_pwrite_sync(bs->file, bat_offset, &bat_value, 4);
-    if (ret < 0)
-        goto fail;
-
-    return get_sector_offset(bs, sector_num, 0);
-
-fail:
-    s->free_data_block_offset -= (s->block_size + s->bitmap_size);
-    return -1;
-}
-
-static int vpc_read(BlockDriverState *bs, int64_t sector_num,
-                    uint8_t *buf, int nb_sectors)
-{
-    BDRVVPCState *s = bs->opaque;
-    int ret;
-    int64_t offset;
-    int64_t sectors, sectors_per_block;
-
-    while (nb_sectors > 0) {
-        offset = get_sector_offset(bs, sector_num, 0);
-
-        sectors_per_block = s->block_size >> BDRV_SECTOR_BITS;
-        sectors = sectors_per_block - (sector_num % sectors_per_block);
-        if (sectors > nb_sectors) {
-            sectors = nb_sectors;
-        }
-
-        if (offset == -1) {
-            memset(buf, 0, sectors * BDRV_SECTOR_SIZE);
-        } else {
-            ret = bdrv_pread(bs->file, offset, buf,
-                sectors * BDRV_SECTOR_SIZE);
-            if (ret != sectors * BDRV_SECTOR_SIZE) {
-                return -1;
-            }
-        }
-
-        nb_sectors -= sectors;
-        sector_num += sectors;
-        buf += sectors * BDRV_SECTOR_SIZE;
-    }
-    return 0;
-}
-
-static int vpc_write(BlockDriverState *bs, int64_t sector_num,
-    const uint8_t *buf, int nb_sectors)
-{
-    BDRVVPCState *s = bs->opaque;
-    int64_t offset;
-    int64_t sectors, sectors_per_block;
-    int ret;
-
-    while (nb_sectors > 0) {
-        offset = get_sector_offset(bs, sector_num, 1);
-
-        sectors_per_block = s->block_size >> BDRV_SECTOR_BITS;
-        sectors = sectors_per_block - (sector_num % sectors_per_block);
-        if (sectors > nb_sectors) {
-            sectors = nb_sectors;
-        }
-
-        if (offset == -1) {
-            offset = alloc_block(bs, sector_num);
-            if (offset < 0)
-                return -1;
-        }
-
-        ret = bdrv_pwrite(bs->file, offset, buf, sectors * BDRV_SECTOR_SIZE);
-        if (ret != sectors * BDRV_SECTOR_SIZE) {
-            return -1;
-        }
-
-        nb_sectors -= sectors;
-        sector_num += sectors;
-        buf += sectors * BDRV_SECTOR_SIZE;
-    }
-
-    return 0;
-}
-
-
-/*
- * Calculates the number of cylinders, heads and sectors per cylinder
- * based on a given number of sectors. This is the algorithm described
- * in the VHD specification.
- *
- * Note that the geometry doesn't always exactly match total_sectors but
- * may round it down.
- *
- * Returns 0 on success, -EFBIG if the size is larger than 127 GB
- */
-static int calculate_geometry(int64_t total_sectors, uint16_t* cyls,
-    uint8_t* heads, uint8_t* secs_per_cyl)
-{
-    uint32_t cyls_times_heads;
-
-    if (total_sectors > 65535 * 16 * 255)
-        return -EFBIG;
-
-    if (total_sectors > 65535 * 16 * 63) {
-        *secs_per_cyl = 255;
-        *heads = 16;
-        cyls_times_heads = total_sectors / *secs_per_cyl;
-    } else {
-        *secs_per_cyl = 17;
-        cyls_times_heads = total_sectors / *secs_per_cyl;
-        *heads = (cyls_times_heads + 1023) / 1024;
-
-        if (*heads < 4)
-            *heads = 4;
-
-        if (cyls_times_heads >= (*heads * 1024) || *heads > 16) {
-            *secs_per_cyl = 31;
-            *heads = 16;
-            cyls_times_heads = total_sectors / *secs_per_cyl;
-        }
-
-        if (cyls_times_heads >= (*heads * 1024)) {
-            *secs_per_cyl = 63;
-            *heads = 16;
-            cyls_times_heads = total_sectors / *secs_per_cyl;
-        }
-    }
-
-    *cyls = cyls_times_heads / *heads;
-
-    return 0;
-}
-
-static int vpc_create(const char *filename, QEMUOptionParameter *options)
-{
-    uint8_t buf[1024];
-    struct vhd_footer* footer = (struct vhd_footer*) buf;
-    struct vhd_dyndisk_header* dyndisk_header =
-        (struct vhd_dyndisk_header*) buf;
-    int fd, i;
-    uint16_t cyls = 0;
-    uint8_t heads = 0;
-    uint8_t secs_per_cyl = 0;
-    size_t block_size, num_bat_entries;
-    int64_t total_sectors = 0;
-
-    // Read out options
-    while (options && options->name) {
-        if (!strcmp(options->name, "size")) {
-            total_sectors = options->value.n / 512;
-        }
-        options++;
-    }
-
-    // Create the file
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
-    if (fd < 0)
-        return -EIO;
-
-    /* Calculate matching total_size and geometry. Increase the number of
-       sectors requested until we get enough (or fail). */
-    for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) {
-        if (calculate_geometry(total_sectors + i,
-                               &cyls, &heads, &secs_per_cyl)) {
-            return -EFBIG;
-        }
-    }
-    total_sectors = (int64_t) cyls * heads * secs_per_cyl;
-
-    // Prepare the Hard Disk Footer
-    memset(buf, 0, 1024);
-
-    memcpy(footer->creator, "conectix", 8);
-    // TODO Check if "qemu" creator_app is ok for VPC
-    memcpy(footer->creator_app, "qemu", 4);
-    memcpy(footer->creator_os, "Wi2k", 4);
-
-    footer->features = be32_to_cpu(0x02);
-    footer->version = be32_to_cpu(0x00010000);
-    footer->data_offset = be64_to_cpu(HEADER_SIZE);
-    footer->timestamp = be32_to_cpu(time(NULL) - VHD_TIMESTAMP_BASE);
-
-    // Version of Virtual PC 2007
-    footer->major = be16_to_cpu(0x0005);
-    footer->minor =be16_to_cpu(0x0003);
-
-    footer->orig_size = be64_to_cpu(total_sectors * 512);
-    footer->size = be64_to_cpu(total_sectors * 512);
-
-    footer->cyls = be16_to_cpu(cyls);
-    footer->heads = heads;
-    footer->secs_per_cyl = secs_per_cyl;
-
-    footer->type = be32_to_cpu(VHD_DYNAMIC);
-
-    // TODO uuid is missing
-
-    footer->checksum = be32_to_cpu(vpc_checksum(buf, HEADER_SIZE));
-
-    // Write the footer (twice: at the beginning and at the end)
-    block_size = 0x200000;
-    num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512);
-
-    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE)
-        return -EIO;
-
-    if (lseek(fd, 1536 + ((num_bat_entries * 4 + 511) & ~511), SEEK_SET) < 0)
-        return -EIO;
-    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE)
-        return -EIO;
-
-    // Write the initial BAT
-    if (lseek(fd, 3 * 512, SEEK_SET) < 0)
-        return -EIO;
-
-    memset(buf, 0xFF, 512);
-    for (i = 0; i < (num_bat_entries * 4 + 511) / 512; i++)
-        if (write(fd, buf, 512) != 512)
-            return -EIO;
-
-
-    // Prepare the Dynamic Disk Header
-    memset(buf, 0, 1024);
-
-    memcpy(dyndisk_header->magic, "cxsparse", 8);
-
-    dyndisk_header->data_offset = be64_to_cpu(0xFFFFFFFF);
-    dyndisk_header->table_offset = be64_to_cpu(3 * 512);
-    dyndisk_header->version = be32_to_cpu(0x00010000);
-    dyndisk_header->block_size = be32_to_cpu(block_size);
-    dyndisk_header->max_table_entries = be32_to_cpu(num_bat_entries);
-
-    dyndisk_header->checksum = be32_to_cpu(vpc_checksum(buf, 1024));
-
-    // Write the header
-    if (lseek(fd, 512, SEEK_SET) < 0)
-        return -EIO;
-    if (write(fd, buf, 1024) != 1024)
-        return -EIO;
-
-    close(fd);
-    return 0;
-}
-
-static void vpc_close(BlockDriverState *bs)
-{
-    BDRVVPCState *s = bs->opaque;
-    g_free(s->pagetable);
-#ifdef CACHE
-    g_free(s->pageentry_u8);
-#endif
-}
-
-static QEMUOptionParameter vpc_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    { NULL }
-};
-
-static BlockDriver bdrv_vpc = {
-    .format_name	= "vpc",
-    .instance_size	= sizeof(BDRVVPCState),
-    .bdrv_probe		= vpc_probe,
-    .bdrv_open		= vpc_open,
-    .bdrv_read		= vpc_read,
-    .bdrv_write		= vpc_write,
-    .bdrv_close		= vpc_close,
-    .bdrv_create	= vpc_create,
-
-    .create_options = vpc_create_options,
-};
-
-static void bdrv_vpc_init(void)
-{
-    bdrv_register(&bdrv_vpc);
-}
-
-block_init(bdrv_vpc_init);
diff --git a/block/vvfat.c b/block/vvfat.c
deleted file mode 100644
index 0871352..0000000
--- a/block/vvfat.c
+++ /dev/null
@@ -1,2876 +0,0 @@
-/* vim:set shiftwidth=4 ts=8: */
-/*
- * QEMU Block driver for virtual VFAT (shadows a local directory)
- *
- * Copyright (c) 2004,2005 Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <sys/stat.h>
-#include <dirent.h>
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "qemu/module.h"
-
-#ifndef S_IWGRP
-#define S_IWGRP 0
-#endif
-#ifndef S_IWOTH
-#define S_IWOTH 0
-#endif
-
-/* TODO: add ":bootsector=blabla.img:" */
-/* LATER TODO: add automatic boot sector generation from
-    BOOTEASY.ASM and Ranish Partition Manager
-    Note that DOS assumes the system files to be the first files in the
-    file system (test if the boot sector still relies on that fact)! */
-/* MAYBE TODO: write block-visofs.c */
-/* TODO: call try_commit() only after a timeout */
-
-/* #define DEBUG */
-
-#ifdef DEBUG
-
-#define DLOG(a) a
-
-#undef stderr
-#define stderr STDERR
-FILE* stderr = NULL;
-
-static void checkpoint(void);
-
-#ifdef __MINGW32__
-void nonono(const char* file, int line, const char* msg) {
-    fprintf(stderr, "Nonono! %s:%d %s\n", file, line, msg);
-    exit(-5);
-}
-#undef assert
-#define assert(a) do {if (!(a)) nonono(__FILE__, __LINE__, #a);}while(0)
-#endif
-
-#else
-
-#define DLOG(a)
-
-#endif
-
-/* dynamic array functions */
-typedef struct array_t {
-    char* pointer;
-    unsigned int size,next,item_size;
-} array_t;
-
-static inline void array_init(array_t* array,unsigned int item_size)
-{
-    array->pointer = NULL;
-    array->size=0;
-    array->next=0;
-    array->item_size=item_size;
-}
-
-static inline void array_free(array_t* array)
-{
-    if(array->pointer)
-        free(array->pointer);
-    array->size=array->next=0;
-}
-
-/* does not automatically grow */
-static inline void* array_get(array_t* array,unsigned int index) {
-    assert(index < array->next);
-    return array->pointer + index * array->item_size;
-}
-
-static inline int array_ensure_allocated(array_t* array, int index)
-{
-    if((index + 1) * array->item_size > array->size) {
-	int new_size = (index + 32) * array->item_size;
-	array->pointer = g_realloc(array->pointer, new_size);
-	if (!array->pointer)
-	    return -1;
-	array->size = new_size;
-	array->next = index + 1;
-    }
-
-    return 0;
-}
-
-static inline void* array_get_next(array_t* array) {
-    unsigned int next = array->next;
-    void* result;
-
-    if (array_ensure_allocated(array, next) < 0)
-	return NULL;
-
-    array->next = next + 1;
-    result = array_get(array, next);
-
-    return result;
-}
-
-static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
-    if((array->next+count)*array->item_size>array->size) {
-	int increment=count*array->item_size;
-	array->pointer=g_realloc(array->pointer,array->size+increment);
-	if(!array->pointer)
-            return NULL;
-	array->size+=increment;
-    }
-    memmove(array->pointer+(index+count)*array->item_size,
-		array->pointer+index*array->item_size,
-		(array->next-index)*array->item_size);
-    array->next+=count;
-    return array->pointer+index*array->item_size;
-}
-
-/* this performs a "roll", so that the element which was at index_from becomes
- * index_to, but the order of all other elements is preserved. */
-static inline int array_roll(array_t* array,int index_to,int index_from,int count)
-{
-    char* buf;
-    char* from;
-    char* to;
-    int is;
-
-    if(!array ||
-	    index_to<0 || index_to>=array->next ||
-	    index_from<0 || index_from>=array->next)
-	return -1;
-
-    if(index_to==index_from)
-	return 0;
-
-    is=array->item_size;
-    from=array->pointer+index_from*is;
-    to=array->pointer+index_to*is;
-    buf=g_malloc(is*count);
-    memcpy(buf,from,is*count);
-
-    if(index_to<index_from)
-	memmove(to+is*count,to,from-to);
-    else
-	memmove(from,from+is*count,to-from);
-
-    memcpy(to,buf,is*count);
-
-    free(buf);
-
-    return 0;
-}
-
-static inline int array_remove_slice(array_t* array,int index, int count)
-{
-    assert(index >=0);
-    assert(count > 0);
-    assert(index + count <= array->next);
-    if(array_roll(array,array->next-1,index,count))
-	return -1;
-    array->next -= count;
-    return 0;
-}
-
-static int array_remove(array_t* array,int index)
-{
-    return array_remove_slice(array, index, 1);
-}
-
-/* return the index for a given member */
-static int array_index(array_t* array, void* pointer)
-{
-    size_t offset = (char*)pointer - array->pointer;
-    assert((offset % array->item_size) == 0);
-    assert(offset/array->item_size < array->next);
-    return offset/array->item_size;
-}
-
-/* These structures are used to fake a disk and the VFAT filesystem.
- * For this reason we need to use __attribute__((packed)). */
-
-typedef struct bootsector_t {
-    uint8_t jump[3];
-    uint8_t name[8];
-    uint16_t sector_size;
-    uint8_t sectors_per_cluster;
-    uint16_t reserved_sectors;
-    uint8_t number_of_fats;
-    uint16_t root_entries;
-    uint16_t total_sectors16;
-    uint8_t media_type;
-    uint16_t sectors_per_fat;
-    uint16_t sectors_per_track;
-    uint16_t number_of_heads;
-    uint32_t hidden_sectors;
-    uint32_t total_sectors;
-    union {
-        struct {
-	    uint8_t drive_number;
-	    uint8_t current_head;
-	    uint8_t signature;
-	    uint32_t id;
-	    uint8_t volume_label[11];
-	} __attribute__((packed)) fat16;
-	struct {
-	    uint32_t sectors_per_fat;
-	    uint16_t flags;
-	    uint8_t major,minor;
-	    uint32_t first_cluster_of_root_directory;
-	    uint16_t info_sector;
-	    uint16_t backup_boot_sector;
-	    uint16_t ignored;
-	} __attribute__((packed)) fat32;
-    } u;
-    uint8_t fat_type[8];
-    uint8_t ignored[0x1c0];
-    uint8_t magic[2];
-} __attribute__((packed)) bootsector_t;
-
-typedef struct {
-    uint8_t head;
-    uint8_t sector;
-    uint8_t cylinder;
-} mbr_chs_t;
-
-typedef struct partition_t {
-    uint8_t attributes; /* 0x80 = bootable */
-    mbr_chs_t start_CHS;
-    uint8_t   fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xe = FAT16_LBA, 0xb = FAT32, 0xc = FAT32_LBA */
-    mbr_chs_t end_CHS;
-    uint32_t start_sector_long;
-    uint32_t length_sector_long;
-} __attribute__((packed)) partition_t;
-
-typedef struct mbr_t {
-    uint8_t ignored[0x1b8];
-    uint32_t nt_id;
-    uint8_t ignored2[2];
-    partition_t partition[4];
-    uint8_t magic[2];
-} __attribute__((packed)) mbr_t;
-
-typedef struct direntry_t {
-    uint8_t name[8];
-    uint8_t extension[3];
-    uint8_t attributes;
-    uint8_t reserved[2];
-    uint16_t ctime;
-    uint16_t cdate;
-    uint16_t adate;
-    uint16_t begin_hi;
-    uint16_t mtime;
-    uint16_t mdate;
-    uint16_t begin;
-    uint32_t size;
-} __attribute__((packed)) direntry_t;
-
-/* this structure are used to transparently access the files */
-
-typedef struct mapping_t {
-    /* begin is the first cluster, end is the last+1 */
-    uint32_t begin,end;
-    /* as s->directory is growable, no pointer may be used here */
-    unsigned int dir_index;
-    /* the clusters of a file may be in any order; this points to the first */
-    int first_mapping_index;
-    union {
-	/* offset is
-	 * - the offset in the file (in clusters) for a file, or
-	 * - the next cluster of the directory for a directory, and
-	 * - the address of the buffer for a faked entry
-	 */
-	struct {
-	    uint32_t offset;
-	} file;
-	struct {
-	    int parent_mapping_index;
-	    int first_dir_index;
-	} dir;
-    } info;
-    /* path contains the full path, i.e. it always starts with s->path */
-    char* path;
-
-    enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
-	MODE_DIRECTORY = 4, MODE_FAKED = 8,
-	MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
-    int read_only;
-} mapping_t;
-
-#ifdef DEBUG
-static void print_direntry(const struct direntry_t*);
-static void print_mapping(const struct mapping_t* mapping);
-#endif
-
-/* here begins the real VVFAT driver */
-
-typedef struct BDRVVVFATState {
-    BlockDriverState* bs; /* pointer to parent */
-    unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
-    unsigned char first_sectors[0x40*0x200];
-
-    int fat_type; /* 16 or 32 */
-    array_t fat,directory,mapping;
-
-    unsigned int cluster_size;
-    unsigned int sectors_per_cluster;
-    unsigned int sectors_per_fat;
-    unsigned int sectors_of_root_directory;
-    uint32_t last_cluster_of_root_directory;
-    unsigned int faked_sectors; /* how many sectors are faked before file data */
-    uint32_t sector_count; /* total number of sectors of the partition */
-    uint32_t cluster_count; /* total number of clusters of this partition */
-    uint32_t max_fat_value;
-
-    int current_fd;
-    mapping_t* current_mapping;
-    unsigned char* cluster; /* points to current cluster */
-    unsigned char* cluster_buffer; /* points to a buffer to hold temp data */
-    unsigned int current_cluster;
-
-    /* write support */
-    BlockDriverState* write_target;
-    char* qcow_filename;
-    BlockDriverState* qcow;
-    void* fat2;
-    char* used_clusters;
-    array_t commits;
-    const char* path;
-    int downcase_short_names;
-} BDRVVVFATState;
-
-/* take the sector position spos and convert it to Cylinder/Head/Sector position
- * if the position is outside the specified geometry, fill maximum value for CHS
- * and return 1 to signal overflow.
- */
-static int sector2CHS(BlockDriverState* bs, mbr_chs_t * chs, int spos){
-    int head,sector;
-    sector   = spos % (bs->secs);  spos/= bs->secs;
-    head     = spos % (bs->heads); spos/= bs->heads;
-    if(spos >= bs->cyls){
-        /* Overflow,
-        it happens if 32bit sector positions are used, while CHS is only 24bit.
-        Windows/Dos is said to take 1023/255/63 as nonrepresentable CHS */
-        chs->head     = 0xFF;
-        chs->sector   = 0xFF;
-        chs->cylinder = 0xFF;
-        return 1;
-    }
-    chs->head     = (uint8_t)head;
-    chs->sector   = (uint8_t)( (sector+1) | ((spos>>8)<<6) );
-    chs->cylinder = (uint8_t)spos;
-    return 0;
-}
-
-static void init_mbr(BDRVVVFATState* s)
-{
-    /* TODO: if the files mbr.img and bootsect.img exist, use them */
-    mbr_t* real_mbr=(mbr_t*)s->first_sectors;
-    partition_t* partition = &(real_mbr->partition[0]);
-    int lba;
-
-    memset(s->first_sectors,0,512);
-
-    /* Win NT Disk Signature */
-    real_mbr->nt_id= cpu_to_le32(0xbe1afdfa);
-
-    partition->attributes=0x80; /* bootable */
-
-    /* LBA is used when partition is outside the CHS geometry */
-    lba = sector2CHS(s->bs, &partition->start_CHS, s->first_sectors_number-1);
-    lba|= sector2CHS(s->bs, &partition->end_CHS,   s->sector_count);
-
-    /*LBA partitions are identified only by start/length_sector_long not by CHS*/
-    partition->start_sector_long =cpu_to_le32(s->first_sectors_number-1);
-    partition->length_sector_long=cpu_to_le32(s->sector_count - s->first_sectors_number+1);
-
-    /* FAT12/FAT16/FAT32 */
-    /* DOS uses different types when partition is LBA,
-       probably to prevent older versions from using CHS on them */
-    partition->fs_type= s->fat_type==12 ? 0x1:
-                        s->fat_type==16 ? (lba?0xe:0x06):
-                         /*fat_tyoe==32*/ (lba?0xc:0x0b);
-
-    real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
-}
-
-/* direntry functions */
-
-/* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple of 26 */
-static inline int short2long_name(char* dest,const char* src)
-{
-    int i;
-    int len;
-    for(i=0;i<129 && src[i];i++) {
-        dest[2*i]=src[i];
-	dest[2*i+1]=0;
-    }
-    len=2*i;
-    dest[2*i]=dest[2*i+1]=0;
-    for(i=2*i+2;(i%26);i++)
-	dest[i]=0xff;
-    return len;
-}
-
-static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename)
-{
-    char buffer[258];
-    int length=short2long_name(buffer,filename),
-        number_of_entries=(length+25)/26,i;
-    direntry_t* entry;
-
-    for(i=0;i<number_of_entries;i++) {
-	entry=array_get_next(&(s->directory));
-	entry->attributes=0xf;
-	entry->reserved[0]=0;
-	entry->begin=0;
-	entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
-    }
-    for(i=0;i<26*number_of_entries;i++) {
-	int offset=(i%26);
-	if(offset<10) offset=1+offset;
-	else if(offset<22) offset=14+offset-10;
-	else offset=28+offset-22;
-	entry=array_get(&(s->directory),s->directory.next-1-(i/26));
-	entry->name[offset]=buffer[i];
-    }
-    return array_get(&(s->directory),s->directory.next-number_of_entries);
-}
-
-static char is_free(const direntry_t* direntry)
-{
-    return direntry->name[0]==0xe5 || direntry->name[0]==0x00;
-}
-
-static char is_volume_label(const direntry_t* direntry)
-{
-    return direntry->attributes == 0x28;
-}
-
-static char is_long_name(const direntry_t* direntry)
-{
-    return direntry->attributes == 0xf;
-}
-
-static char is_short_name(const direntry_t* direntry)
-{
-    return !is_volume_label(direntry) && !is_long_name(direntry)
-	&& !is_free(direntry);
-}
-
-static char is_directory(const direntry_t* direntry)
-{
-    return direntry->attributes & 0x10 && direntry->name[0] != 0xe5;
-}
-
-static inline char is_dot(const direntry_t* direntry)
-{
-    return is_short_name(direntry) && direntry->name[0] == '.';
-}
-
-static char is_file(const direntry_t* direntry)
-{
-    return is_short_name(direntry) && !is_directory(direntry);
-}
-
-static inline uint32_t begin_of_direntry(const direntry_t* direntry)
-{
-    return le16_to_cpu(direntry->begin)|(le16_to_cpu(direntry->begin_hi)<<16);
-}
-
-static inline uint32_t filesize_of_direntry(const direntry_t* direntry)
-{
-    return le32_to_cpu(direntry->size);
-}
-
-static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
-{
-    direntry->begin = cpu_to_le16(begin & 0xffff);
-    direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
-}
-
-/* fat functions */
-
-static inline uint8_t fat_chksum(const direntry_t* entry)
-{
-    uint8_t chksum=0;
-    int i;
-
-    for(i=0;i<11;i++) {
-        unsigned char c;
-
-        c = (i <= 8) ? entry->name[i] : entry->extension[i-8];
-        chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0)) + c;
-    }
-
-    return chksum;
-}
-
-/* if return_time==0, this returns the fat_date, else the fat_time */
-static uint16_t fat_datetime(time_t time,int return_time) {
-    struct tm* t;
-#ifdef _WIN32
-    t=localtime(&time); /* this is not thread safe */
-#else
-    struct tm t1;
-    t = &t1;
-    localtime_r(&time,t);
-#endif
-    if(return_time)
-	return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
-    return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9));
-}
-
-static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value)
-{
-    if(s->fat_type==32) {
-	uint32_t* entry=array_get(&(s->fat),cluster);
-	*entry=cpu_to_le32(value);
-    } else if(s->fat_type==16) {
-	uint16_t* entry=array_get(&(s->fat),cluster);
-	*entry=cpu_to_le16(value&0xffff);
-    } else {
-	int offset = (cluster*3/2);
-	unsigned char* p = array_get(&(s->fat), offset);
-        switch (cluster&1) {
-	case 0:
-		p[0] = value&0xff;
-		p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
-		break;
-	case 1:
-		p[0] = (p[0]&0xf) | ((value&0xf)<<4);
-		p[1] = (value>>4);
-		break;
-	}
-    }
-}
-
-static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster)
-{
-    if(s->fat_type==32) {
-	uint32_t* entry=array_get(&(s->fat),cluster);
-	return le32_to_cpu(*entry);
-    } else if(s->fat_type==16) {
-	uint16_t* entry=array_get(&(s->fat),cluster);
-	return le16_to_cpu(*entry);
-    } else {
-	const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
-	return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
-    }
-}
-
-static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry)
-{
-    if(fat_entry>s->max_fat_value-8)
-	return -1;
-    return 0;
-}
-
-static inline void init_fat(BDRVVVFATState* s)
-{
-    if (s->fat_type == 12) {
-	array_init(&(s->fat),1);
-	array_ensure_allocated(&(s->fat),
-		s->sectors_per_fat * 0x200 * 3 / 2 - 1);
-    } else {
-	array_init(&(s->fat),(s->fat_type==32?4:2));
-	array_ensure_allocated(&(s->fat),
-		s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
-    }
-    memset(s->fat.pointer,0,s->fat.size);
-
-    switch(s->fat_type) {
-	case 12: s->max_fat_value=0xfff; break;
-	case 16: s->max_fat_value=0xffff; break;
-	case 32: s->max_fat_value=0x0fffffff; break;
-	default: s->max_fat_value=0; /* error... */
-    }
-
-}
-
-/* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */
-/* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */
-static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
-	unsigned int directory_start, const char* filename, int is_dot)
-{
-    int i,j,long_index=s->directory.next;
-    direntry_t* entry = NULL;
-    direntry_t* entry_long = NULL;
-
-    if(is_dot) {
-	entry=array_get_next(&(s->directory));
-	memset(entry->name,0x20,11);
-	memcpy(entry->name,filename,strlen(filename));
-	return entry;
-    }
-
-    entry_long=create_long_filename(s,filename);
-
-    i = strlen(filename);
-    for(j = i - 1; j>0  && filename[j]!='.';j--);
-    if (j > 0)
-	i = (j > 8 ? 8 : j);
-    else if (i > 8)
-	i = 8;
-
-    entry=array_get_next(&(s->directory));
-    memset(entry->name,0x20,11);
-    memcpy(entry->name, filename, i);
-
-    if(j > 0)
-	for (i = 0; i < 3 && filename[j+1+i]; i++)
-	    entry->extension[i] = filename[j+1+i];
-
-    /* upcase & remove unwanted characters */
-    for(i=10;i>=0;i--) {
-	if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
-	if(entry->name[i]<=' ' || entry->name[i]>0x7f
-		|| strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
-	    entry->name[i]='_';
-        else if(entry->name[i]>='a' && entry->name[i]<='z')
-            entry->name[i]+='A'-'a';
-    }
-
-    /* mangle duplicates */
-    while(1) {
-	direntry_t* entry1=array_get(&(s->directory),directory_start);
-	int j;
-
-	for(;entry1<entry;entry1++)
-	    if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
-		break; /* found dupe */
-	if(entry1==entry) /* no dupe found */
-	    break;
-
-	/* use all 8 characters of name */
-	if(entry->name[7]==' ') {
-	    int j;
-	    for(j=6;j>0 && entry->name[j]==' ';j--)
-		entry->name[j]='~';
-	}
-
-	/* increment number */
-	for(j=7;j>0 && entry->name[j]=='9';j--)
-	    entry->name[j]='0';
-	if(j>0) {
-	    if(entry->name[j]<'0' || entry->name[j]>'9')
-	        entry->name[j]='0';
-	    else
-	        entry->name[j]++;
-	}
-    }
-
-    /* calculate checksum; propagate to long name */
-    if(entry_long) {
-        uint8_t chksum=fat_chksum(entry);
-
-	/* calculate anew, because realloc could have taken place */
-	entry_long=array_get(&(s->directory),long_index);
-	while(entry_long<entry && is_long_name(entry_long)) {
-	    entry_long->reserved[1]=chksum;
-	    entry_long++;
-	}
-    }
-
-    return entry;
-}
-
-/*
- * Read a directory. (the index of the corresponding mapping must be passed).
- */
-static int read_directory(BDRVVVFATState* s, int mapping_index)
-{
-    mapping_t* mapping = array_get(&(s->mapping), mapping_index);
-    direntry_t* direntry;
-    const char* dirname = mapping->path;
-    int first_cluster = mapping->begin;
-    int parent_index = mapping->info.dir.parent_mapping_index;
-    mapping_t* parent_mapping = (mapping_t*)
-        (parent_index >= 0 ? array_get(&(s->mapping), parent_index) : NULL);
-    int first_cluster_of_parent = parent_mapping ? parent_mapping->begin : -1;
-
-    DIR* dir=opendir(dirname);
-    struct dirent* entry;
-    int i;
-
-    assert(mapping->mode & MODE_DIRECTORY);
-
-    if(!dir) {
-	mapping->end = mapping->begin;
-	return -1;
-    }
-
-    i = mapping->info.dir.first_dir_index =
-	    first_cluster == 0 ? 0 : s->directory.next;
-
-    /* actually read the directory, and allocate the mappings */
-    while((entry=readdir(dir))) {
-	unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
-        char* buffer;
-	direntry_t* direntry;
-        struct stat st;
-	int is_dot=!strcmp(entry->d_name,".");
-	int is_dotdot=!strcmp(entry->d_name,"..");
-
-	if(first_cluster == 0 && (is_dotdot || is_dot))
-	    continue;
-
-	buffer=(char*)g_malloc(length);
-	snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
-
-	if(stat(buffer,&st)<0) {
-	    free(buffer);
-            continue;
-	}
-
-	/* create directory entry for this file */
-	direntry=create_short_and_long_name(s, i, entry->d_name,
-		is_dot || is_dotdot);
-	direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
-	direntry->reserved[0]=direntry->reserved[1]=0;
-	direntry->ctime=fat_datetime(st.st_ctime,1);
-	direntry->cdate=fat_datetime(st.st_ctime,0);
-	direntry->adate=fat_datetime(st.st_atime,0);
-	direntry->begin_hi=0;
-	direntry->mtime=fat_datetime(st.st_mtime,1);
-	direntry->mdate=fat_datetime(st.st_mtime,0);
-	if(is_dotdot)
-	    set_begin_of_direntry(direntry, first_cluster_of_parent);
-	else if(is_dot)
-	    set_begin_of_direntry(direntry, first_cluster);
-	else
-	    direntry->begin=0; /* do that later */
-        if (st.st_size > 0x7fffffff) {
-	    fprintf(stderr, "File %s is larger than 2GB\n", buffer);
-	    free(buffer);
-	    return -2;
-        }
-	direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
-
-	/* create mapping for this file */
-	if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
-	    s->current_mapping=(mapping_t*)array_get_next(&(s->mapping));
-	    s->current_mapping->begin=0;
-	    s->current_mapping->end=st.st_size;
-	    /*
-	     * we get the direntry of the most recent direntry, which
-	     * contains the short name and all the relevant information.
-	     */
-	    s->current_mapping->dir_index=s->directory.next-1;
-	    s->current_mapping->first_mapping_index = -1;
-	    if (S_ISDIR(st.st_mode)) {
-		s->current_mapping->mode = MODE_DIRECTORY;
-		s->current_mapping->info.dir.parent_mapping_index =
-		    mapping_index;
-	    } else {
-		s->current_mapping->mode = MODE_UNDEFINED;
-		s->current_mapping->info.file.offset = 0;
-	    }
-	    s->current_mapping->path=buffer;
-	    s->current_mapping->read_only =
-		(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
-	}
-    }
-    closedir(dir);
-
-    /* fill with zeroes up to the end of the cluster */
-    while(s->directory.next%(0x10*s->sectors_per_cluster)) {
-	direntry_t* direntry=array_get_next(&(s->directory));
-	memset(direntry,0,sizeof(direntry_t));
-    }
-
-/* TODO: if there are more entries, bootsector has to be adjusted! */
-#define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster)
-    if (mapping_index == 0 && s->directory.next < ROOT_ENTRIES) {
-	/* root directory */
-	int cur = s->directory.next;
-	array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
-	memset(array_get(&(s->directory), cur), 0,
-		(ROOT_ENTRIES - cur) * sizeof(direntry_t));
-    }
-
-     /* reget the mapping, since s->mapping was possibly realloc()ed */
-    mapping = (mapping_t*)array_get(&(s->mapping), mapping_index);
-    first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
-	* 0x20 / s->cluster_size;
-    mapping->end = first_cluster;
-
-    direntry = (direntry_t*)array_get(&(s->directory), mapping->dir_index);
-    set_begin_of_direntry(direntry, mapping->begin);
-
-    return 0;
-}
-
-static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
-{
-    return (sector_num-s->faked_sectors)/s->sectors_per_cluster;
-}
-
-static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
-{
-    return s->faked_sectors + s->sectors_per_cluster * cluster_num;
-}
-
-static inline uint32_t sector_offset_in_cluster(BDRVVVFATState* s,off_t sector_num)
-{
-    return (sector_num-s->first_sectors_number-2*s->sectors_per_fat)%s->sectors_per_cluster;
-}
-
-#ifdef DBG
-static direntry_t* get_direntry_for_mapping(BDRVVVFATState* s,mapping_t* mapping)
-{
-    if(mapping->mode==MODE_UNDEFINED)
-	return 0;
-    return (direntry_t*)(s->directory.pointer+sizeof(direntry_t)*mapping->dir_index);
-}
-#endif
-
-static int init_directories(BDRVVVFATState* s,
-	const char* dirname)
-{
-    bootsector_t* bootsector;
-    mapping_t* mapping;
-    unsigned int i;
-    unsigned int cluster;
-
-    memset(&(s->first_sectors[0]),0,0x40*0x200);
-
-    s->cluster_size=s->sectors_per_cluster*0x200;
-    s->cluster_buffer=g_malloc(s->cluster_size);
-
-    /*
-     * The formula: sc = spf+1+spf*spc*(512*8/fat_type),
-     * where sc is sector_count,
-     * spf is sectors_per_fat,
-     * spc is sectors_per_clusters, and
-     * fat_type = 12, 16 or 32.
-     */
-    i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
-    s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
-
-    array_init(&(s->mapping),sizeof(mapping_t));
-    array_init(&(s->directory),sizeof(direntry_t));
-
-    /* add volume label */
-    {
-	direntry_t* entry=array_get_next(&(s->directory));
-	entry->attributes=0x28; /* archive | volume label */
-	memcpy(entry->name,"QEMU VVF",8);
-	memcpy(entry->extension,"AT ",3);
-    }
-
-    /* Now build FAT, and write back information into directory */
-    init_fat(s);
-
-    s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2;
-    s->cluster_count=sector2cluster(s, s->sector_count);
-
-    mapping = array_get_next(&(s->mapping));
-    mapping->begin = 0;
-    mapping->dir_index = 0;
-    mapping->info.dir.parent_mapping_index = -1;
-    mapping->first_mapping_index = -1;
-    mapping->path = g_strdup(dirname);
-    i = strlen(mapping->path);
-    if (i > 0 && mapping->path[i - 1] == '/')
-	mapping->path[i - 1] = '\0';
-    mapping->mode = MODE_DIRECTORY;
-    mapping->read_only = 0;
-    s->path = mapping->path;
-
-    for (i = 0, cluster = 0; i < s->mapping.next; i++) {
-	/* MS-DOS expects the FAT to be 0 for the root directory
-	 * (except for the media byte). */
-	/* LATER TODO: still true for FAT32? */
-	int fix_fat = (i != 0);
-	mapping = array_get(&(s->mapping), i);
-
-        if (mapping->mode & MODE_DIRECTORY) {
-	    mapping->begin = cluster;
-	    if(read_directory(s, i)) {
-		fprintf(stderr, "Could not read directory %s\n",
-			mapping->path);
-		return -1;
-	    }
-	    mapping = array_get(&(s->mapping), i);
-	} else {
-	    assert(mapping->mode == MODE_UNDEFINED);
-	    mapping->mode=MODE_NORMAL;
-	    mapping->begin = cluster;
-	    if (mapping->end > 0) {
-		direntry_t* direntry = array_get(&(s->directory),
-			mapping->dir_index);
-
-		mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
-		set_begin_of_direntry(direntry, mapping->begin);
-	    } else {
-		mapping->end = cluster + 1;
-		fix_fat = 0;
-	    }
-	}
-
-	assert(mapping->begin < mapping->end);
-
-	/* next free cluster */
-	cluster = mapping->end;
-
-	if(cluster > s->cluster_count) {
-	    fprintf(stderr,"Directory does not fit in FAT%d (capacity %s)\n",
-		    s->fat_type,
-		    s->fat_type == 12 ? s->sector_count == 2880 ? "1.44 MB"
-								: "2.88 MB"
-				      : "504MB");
-	    return -EINVAL;
-	}
-
-	/* fix fat for entry */
-	if (fix_fat) {
-	    int j;
-	    for(j = mapping->begin; j < mapping->end - 1; j++)
-		fat_set(s, j, j+1);
-	    fat_set(s, mapping->end - 1, s->max_fat_value);
-	}
-    }
-
-    mapping = array_get(&(s->mapping), 0);
-    s->sectors_of_root_directory = mapping->end * s->sectors_per_cluster;
-    s->last_cluster_of_root_directory = mapping->end;
-
-    /* the FAT signature */
-    fat_set(s,0,s->max_fat_value);
-    fat_set(s,1,s->max_fat_value);
-
-    s->current_mapping = NULL;
-
-    bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200);
-    bootsector->jump[0]=0xeb;
-    bootsector->jump[1]=0x3e;
-    bootsector->jump[2]=0x90;
-    memcpy(bootsector->name,"QEMU    ",8);
-    bootsector->sector_size=cpu_to_le16(0x200);
-    bootsector->sectors_per_cluster=s->sectors_per_cluster;
-    bootsector->reserved_sectors=cpu_to_le16(1);
-    bootsector->number_of_fats=0x2; /* number of FATs */
-    bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
-    bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
-    bootsector->media_type=(s->fat_type!=12?0xf8:s->sector_count==5760?0xf9:0xf8); /* media descriptor */
-    s->fat.pointer[0] = bootsector->media_type;
-    bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
-    bootsector->sectors_per_track=cpu_to_le16(s->bs->secs);
-    bootsector->number_of_heads=cpu_to_le16(s->bs->heads);
-    bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);
-    bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
-
-    /* LATER TODO: if FAT32, this is wrong */
-    bootsector->u.fat16.drive_number=s->fat_type==12?0:0x80; /* assume this is hda (TODO) */
-    bootsector->u.fat16.current_head=0;
-    bootsector->u.fat16.signature=0x29;
-    bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
-
-    memcpy(bootsector->u.fat16.volume_label,"QEMU VVFAT ",11);
-    memcpy(bootsector->fat_type,(s->fat_type==12?"FAT12   ":s->fat_type==16?"FAT16   ":"FAT32   "),8);
-    bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;
-
-    return 0;
-}
-
-#ifdef DEBUG
-static BDRVVVFATState *vvv = NULL;
-#endif
-
-static int enable_write_target(BDRVVVFATState *s);
-static int is_consistent(BDRVVVFATState *s);
-
-static int vvfat_open(BlockDriverState *bs, const char* dirname, int flags)
-{
-    BDRVVVFATState *s = bs->opaque;
-    int floppy = 0;
-    int i;
-
-#ifdef DEBUG
-    vvv = s;
-#endif
-
-DLOG(if (stderr == NULL) {
-    stderr = fopen("vvfat.log", "a");
-    setbuf(stderr, NULL);
-})
-
-    s->bs = bs;
-
-    s->fat_type=16;
-    /* LATER TODO: if FAT32, adjust */
-    s->sectors_per_cluster=0x10;
-    /* 504MB disk*/
-    bs->cyls=1024; bs->heads=16; bs->secs=63;
-
-    s->current_cluster=0xffffffff;
-
-    s->first_sectors_number=0x40;
-    /* read only is the default for safety */
-    bs->read_only = 1;
-    s->qcow = s->write_target = NULL;
-    s->qcow_filename = NULL;
-    s->fat2 = NULL;
-    s->downcase_short_names = 1;
-
-    if (!strstart(dirname, "fat:", NULL))
-	return -1;
-
-    if (strstr(dirname, ":floppy:")) {
-	floppy = 1;
-	s->fat_type = 12;
-	s->first_sectors_number = 1;
-	s->sectors_per_cluster=2;
-	bs->cyls = 80; bs->heads = 2; bs->secs = 36;
-    }
-
-    s->sector_count=bs->cyls*bs->heads*bs->secs;
-
-    if (strstr(dirname, ":32:")) {
-	fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");
-	s->fat_type = 32;
-    } else if (strstr(dirname, ":16:")) {
-	s->fat_type = 16;
-    } else if (strstr(dirname, ":12:")) {
-	s->fat_type = 12;
-	s->sector_count=2880;
-    }
-
-    if (strstr(dirname, ":rw:")) {
-	if (enable_write_target(s))
-	    return -1;
-	bs->read_only = 0;
-    }
-
-    i = strrchr(dirname, ':') - dirname;
-    assert(i >= 3);
-    if (dirname[i-2] == ':' && qemu_isalpha(dirname[i-1]))
-	/* workaround for DOS drive names */
-	dirname += i-1;
-    else
-	dirname += i+1;
-
-    bs->total_sectors=bs->cyls*bs->heads*bs->secs;
-
-    if(init_directories(s, dirname))
-	return -1;
-
-    s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;
-
-    if(s->first_sectors_number==0x40)
-	init_mbr(s);
-
-    /* for some reason or other, MS-DOS does not like to know about CHS... */
-    if (floppy)
-	bs->heads = bs->cyls = bs->secs = 0;
-
-    //    assert(is_consistent(s));
-    return 0;
-}
-
-static inline void vvfat_close_current_file(BDRVVVFATState *s)
-{
-    if(s->current_mapping) {
-	s->current_mapping = NULL;
-	if (s->current_fd) {
-		close(s->current_fd);
-		s->current_fd = 0;
-	}
-    }
-    s->current_cluster = -1;
-}
-
-/* mappings between index1 and index2-1 are supposed to be ordered
- * return value is the index of the last mapping for which end>cluster_num
- */
-static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
-{
-    while(1) {
-        int index3;
-	mapping_t* mapping;
-	index3=(index1+index2)/2;
-	mapping=array_get(&(s->mapping),index3);
-	assert(mapping->begin < mapping->end);
-	if(mapping->begin>=cluster_num) {
-	    assert(index2!=index3 || index2==0);
-	    if(index2==index3)
-		return index1;
-	    index2=index3;
-	} else {
-	    if(index1==index3)
-		return mapping->end<=cluster_num ? index2 : index1;
-	    index1=index3;
-	}
-	assert(index1<=index2);
-	DLOG(mapping=array_get(&(s->mapping),index1);
-	assert(mapping->begin<=cluster_num);
-	assert(index2 >= s->mapping.next ||
-		((mapping = array_get(&(s->mapping),index2)) &&
-		mapping->end>cluster_num)));
-    }
-}
-
-static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num)
-{
-    int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next);
-    mapping_t* mapping;
-    if(index>=s->mapping.next)
-        return NULL;
-    mapping=array_get(&(s->mapping),index);
-    if(mapping->begin>cluster_num)
-        return NULL;
-    assert(mapping->begin<=cluster_num && mapping->end>cluster_num);
-    return mapping;
-}
-
-/*
- * This function simply compares path == mapping->path. Since the mappings
- * are sorted by cluster, this is expensive: O(n).
- */
-static inline mapping_t* find_mapping_for_path(BDRVVVFATState* s,
-	const char* path)
-{
-    int i;
-
-    for (i = 0; i < s->mapping.next; i++) {
-	mapping_t* mapping = array_get(&(s->mapping), i);
-	if (mapping->first_mapping_index < 0 &&
-		!strcmp(path, mapping->path))
-	    return mapping;
-    }
-
-    return NULL;
-}
-
-static int open_file(BDRVVVFATState* s,mapping_t* mapping)
-{
-    if(!mapping)
-	return -1;
-    if(!s->current_mapping ||
-	    strcmp(s->current_mapping->path,mapping->path)) {
-	/* open file */
-	int fd = open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
-	if(fd<0)
-	    return -1;
-	vvfat_close_current_file(s);
-	s->current_fd = fd;
-	s->current_mapping = mapping;
-    }
-    return 0;
-}
-
-static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
-{
-    if(s->current_cluster != cluster_num) {
-	int result=0;
-	off_t offset;
-	assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
-	if(!s->current_mapping
-		|| s->current_mapping->begin>cluster_num
-		|| s->current_mapping->end<=cluster_num) {
-	    /* binary search of mappings for file */
-	    mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
-
-	    assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
-
-	    if (mapping && mapping->mode & MODE_DIRECTORY) {
-		vvfat_close_current_file(s);
-		s->current_mapping = mapping;
-read_cluster_directory:
-		offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
-		s->cluster = (unsigned char*)s->directory.pointer+offset
-			+ 0x20*s->current_mapping->info.dir.first_dir_index;
-		assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
-		assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
-		s->current_cluster = cluster_num;
-		return 0;
-	    }
-
-	    if(open_file(s,mapping))
-		return -2;
-	} else if (s->current_mapping->mode & MODE_DIRECTORY)
-	    goto read_cluster_directory;
-
-	assert(s->current_fd);
-
-	offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
-	if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
-	    return -3;
-	s->cluster=s->cluster_buffer;
-	result=read(s->current_fd,s->cluster,s->cluster_size);
-	if(result<0) {
-	    s->current_cluster = -1;
-	    return -1;
-	}
-	s->current_cluster = cluster_num;
-    }
-    return 0;
-}
-
-#ifdef DEBUG
-static void hexdump(const void* address, uint32_t len)
-{
-    const unsigned char* p = address;
-    int i, j;
-
-    for (i = 0; i < len; i += 16) {
-	for (j = 0; j < 16 && i + j < len; j++)
-	    fprintf(stderr, "%02x ", p[i + j]);
-	for (; j < 16; j++)
-	    fprintf(stderr, "   ");
-	fprintf(stderr, " ");
-	for (j = 0; j < 16 && i + j < len; j++)
-	    fprintf(stderr, "%c", (p[i + j] < ' ' || p[i + j] > 0x7f) ? '.' : p[i + j]);
-	fprintf(stderr, "\n");
-    }
-}
-
-static void print_direntry(const direntry_t* direntry)
-{
-    int j = 0;
-    char buffer[1024];
-
-    fprintf(stderr, "direntry %p: ", direntry);
-    if(!direntry)
-	return;
-    if(is_long_name(direntry)) {
-	unsigned char* c=(unsigned char*)direntry;
-	int i;
-	for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
-#define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
-	    ADD_CHAR(c[i]);
-	for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
-	    ADD_CHAR(c[i]);
-	for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
-	    ADD_CHAR(c[i]);
-	buffer[j] = 0;
-	fprintf(stderr, "%s\n", buffer);
-    } else {
-	int i;
-	for(i=0;i<11;i++)
-	    ADD_CHAR(direntry->name[i]);
-	buffer[j] = 0;
-	fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
-		buffer,
-		direntry->attributes,
-		begin_of_direntry(direntry),le32_to_cpu(direntry->size));
-    }
-}
-
-static void print_mapping(const mapping_t* mapping)
-{
-    fprintf(stderr, "mapping (%p): begin, end = %d, %d, dir_index = %d, "
-        "first_mapping_index = %d, name = %s, mode = 0x%x, " ,
-        mapping, mapping->begin, mapping->end, mapping->dir_index,
-        mapping->first_mapping_index, mapping->path, mapping->mode);
-
-    if (mapping->mode & MODE_DIRECTORY)
-	fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
-    else
-	fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
-}
-#endif
-
-static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
-                    uint8_t *buf, int nb_sectors)
-{
-    BDRVVVFATState *s = bs->opaque;
-    int i;
-
-    for(i=0;i<nb_sectors;i++,sector_num++) {
-	if (sector_num >= s->sector_count)
-	   return -1;
-	if (s->qcow) {
-	    int n;
-	    if (s->qcow->drv->bdrv_is_allocated(s->qcow,
-			sector_num, nb_sectors-i, &n)) {
-DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n));
-		if (s->qcow->drv->bdrv_read(s->qcow, sector_num, buf+i*0x200, n))
-		    return -1;
-		i += n - 1;
-		sector_num += n - 1;
-		continue;
-	    }
-DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
-	}
-	if(sector_num<s->faked_sectors) {
-	    if(sector_num<s->first_sectors_number)
-		memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
-	    else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
-		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
-	    else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
-		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
-	} else {
-	    uint32_t sector=sector_num-s->faked_sectors,
-	    sector_offset_in_cluster=(sector%s->sectors_per_cluster),
-	    cluster_num=sector/s->sectors_per_cluster;
-	    if(read_cluster(s, cluster_num) != 0) {
-		/* LATER TODO: strict: return -1; */
-		memset(buf+i*0x200,0,0x200);
-		continue;
-	    }
-	    memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
-	}
-    }
-    return 0;
-}
-
-/* LATER TODO: statify all functions */
-
-/*
- * Idea of the write support (use snapshot):
- *
- * 1. check if all data is consistent, recording renames, modifications,
- *    new files and directories (in s->commits).
- *
- * 2. if the data is not consistent, stop committing
- *
- * 3. handle renames, and create new files and directories (do not yet
- *    write their contents)
- *
- * 4. walk the directories, fixing the mapping and direntries, and marking
- *    the handled mappings as not deleted
- *
- * 5. commit the contents of the files
- *
- * 6. handle deleted files and directories
- *
- */
-
-typedef struct commit_t {
-    char* path;
-    union {
-	struct { uint32_t cluster; } rename;
-	struct { int dir_index; uint32_t modified_offset; } writeout;
-	struct { uint32_t first_cluster; } new_file;
-	struct { uint32_t cluster; } mkdir;
-    } param;
-    /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
-    enum {
-	ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
-    } action;
-} commit_t;
-
-static void clear_commits(BDRVVVFATState* s)
-{
-    int i;
-DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
-    for (i = 0; i < s->commits.next; i++) {
-	commit_t* commit = array_get(&(s->commits), i);
-	assert(commit->path || commit->action == ACTION_WRITEOUT);
-	if (commit->action != ACTION_WRITEOUT) {
-	    assert(commit->path);
-	    free(commit->path);
-	} else
-	    assert(commit->path == NULL);
-    }
-    s->commits.next = 0;
-}
-
-static void schedule_rename(BDRVVVFATState* s,
-	uint32_t cluster, char* new_path)
-{
-    commit_t* commit = array_get_next(&(s->commits));
-    commit->path = new_path;
-    commit->param.rename.cluster = cluster;
-    commit->action = ACTION_RENAME;
-}
-
-static void schedule_writeout(BDRVVVFATState* s,
-	int dir_index, uint32_t modified_offset)
-{
-    commit_t* commit = array_get_next(&(s->commits));
-    commit->path = NULL;
-    commit->param.writeout.dir_index = dir_index;
-    commit->param.writeout.modified_offset = modified_offset;
-    commit->action = ACTION_WRITEOUT;
-}
-
-static void schedule_new_file(BDRVVVFATState* s,
-	char* path, uint32_t first_cluster)
-{
-    commit_t* commit = array_get_next(&(s->commits));
-    commit->path = path;
-    commit->param.new_file.first_cluster = first_cluster;
-    commit->action = ACTION_NEW_FILE;
-}
-
-static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
-{
-    commit_t* commit = array_get_next(&(s->commits));
-    commit->path = path;
-    commit->param.mkdir.cluster = cluster;
-    commit->action = ACTION_MKDIR;
-}
-
-typedef struct {
-    /*
-     * Since the sequence number is at most 0x3f, and the filename
-     * length is at most 13 times the sequence number, the maximal
-     * filename length is 0x3f * 13 bytes.
-     */
-    unsigned char name[0x3f * 13 + 1];
-    int checksum, len;
-    int sequence_number;
-} long_file_name;
-
-static void lfn_init(long_file_name* lfn)
-{
-   lfn->sequence_number = lfn->len = 0;
-   lfn->checksum = 0x100;
-}
-
-/* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
-static int parse_long_name(long_file_name* lfn,
-	const direntry_t* direntry)
-{
-    int i, j, offset;
-    const unsigned char* pointer = (const unsigned char*)direntry;
-
-    if (!is_long_name(direntry))
-	return 1;
-
-    if (pointer[0] & 0x40) {
-	lfn->sequence_number = pointer[0] & 0x3f;
-	lfn->checksum = pointer[13];
-	lfn->name[0] = 0;
-	lfn->name[lfn->sequence_number * 13] = 0;
-    } else if ((pointer[0] & 0x3f) != --lfn->sequence_number)
-	return -1;
-    else if (pointer[13] != lfn->checksum)
-	return -2;
-    else if (pointer[12] || pointer[26] || pointer[27])
-	return -3;
-
-    offset = 13 * (lfn->sequence_number - 1);
-    for (i = 0, j = 1; i < 13; i++, j+=2) {
-	if (j == 11)
-	    j = 14;
-	else if (j == 26)
-	    j = 28;
-
-	if (pointer[j+1] == 0)
-	    lfn->name[offset + i] = pointer[j];
-	else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
-	    return -4;
-	else
-	    lfn->name[offset + i] = 0;
-    }
-
-    if (pointer[0] & 0x40)
-	lfn->len = offset + strlen((char*)lfn->name + offset);
-
-    return 0;
-}
-
-/* returns 0 if successful, >0 if no short_name, and <0 on error */
-static int parse_short_name(BDRVVVFATState* s,
-	long_file_name* lfn, direntry_t* direntry)
-{
-    int i, j;
-
-    if (!is_short_name(direntry))
-	return 1;
-
-    for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
-    for (i = 0; i <= j; i++) {
-	if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
-	    return -1;
-	else if (s->downcase_short_names)
-	    lfn->name[i] = qemu_tolower(direntry->name[i]);
-	else
-	    lfn->name[i] = direntry->name[i];
-    }
-
-    for (j = 2; j >= 0 && direntry->extension[j] == ' '; j--);
-    if (j >= 0) {
-	lfn->name[i++] = '.';
-	lfn->name[i + j + 1] = '\0';
-	for (;j >= 0; j--) {
-	    if (direntry->extension[j] <= ' ' || direntry->extension[j] > 0x7f)
-		return -2;
-	    else if (s->downcase_short_names)
-		lfn->name[i + j] = qemu_tolower(direntry->extension[j]);
-	    else
-		lfn->name[i + j] = direntry->extension[j];
-	}
-    } else
-	lfn->name[i + j + 1] = '\0';
-
-    lfn->len = strlen((char*)lfn->name);
-
-    return 0;
-}
-
-static inline uint32_t modified_fat_get(BDRVVVFATState* s,
-	unsigned int cluster)
-{
-    if (cluster < s->last_cluster_of_root_directory) {
-	if (cluster + 1 == s->last_cluster_of_root_directory)
-	    return s->max_fat_value;
-	else
-	    return cluster + 1;
-    }
-
-    if (s->fat_type==32) {
-        uint32_t* entry=((uint32_t*)s->fat2)+cluster;
-        return le32_to_cpu(*entry);
-    } else if (s->fat_type==16) {
-        uint16_t* entry=((uint16_t*)s->fat2)+cluster;
-        return le16_to_cpu(*entry);
-    } else {
-        const uint8_t* x=s->fat2+cluster*3/2;
-        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
-    }
-}
-
-static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num)
-{
-    int was_modified = 0;
-    int i, dummy;
-
-    if (s->qcow == NULL)
-	return 0;
-
-    for (i = 0; !was_modified && i < s->sectors_per_cluster; i++)
-	was_modified = s->qcow->drv->bdrv_is_allocated(s->qcow,
-		cluster2sector(s, cluster_num) + i, 1, &dummy);
-
-    return was_modified;
-}
-
-static const char* get_basename(const char* path)
-{
-    char* basename = strrchr(path, '/');
-    if (basename == NULL)
-	return path;
-    else
-	return basename + 1; /* strip '/' */
-}
-
-/*
- * The array s->used_clusters holds the states of the clusters. If it is
- * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
- * was modified, bit 3 is set.
- * If any cluster is allocated, but not part of a file or directory, this
- * driver refuses to commit.
- */
-typedef enum {
-     USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
-} used_t;
-
-/*
- * get_cluster_count_for_direntry() not only determines how many clusters
- * are occupied by direntry, but also if it was renamed or modified.
- *
- * A file is thought to be renamed *only* if there already was a file with
- * exactly the same first cluster, but a different name.
- *
- * Further, the files/directories handled by this function are
- * assumed to be *not* deleted (and *only* those).
- */
-static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
-	direntry_t* direntry, const char* path)
-{
-    /*
-     * This is a little bit tricky:
-     * IF the guest OS just inserts a cluster into the file chain,
-     * and leaves the rest alone, (i.e. the original file had clusters
-     * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
-     *
-     * - do_commit will write the cluster into the file at the given
-     *   offset, but
-     *
-     * - the cluster which is overwritten should be moved to a later
-     *   position in the file.
-     *
-     * I am not aware that any OS does something as braindead, but this
-     * situation could happen anyway when not committing for a long time.
-     * Just to be sure that this does not bite us, detect it, and copy the
-     * contents of the clusters to-be-overwritten into the qcow.
-     */
-    int copy_it = 0;
-    int was_modified = 0;
-    int32_t ret = 0;
-
-    uint32_t cluster_num = begin_of_direntry(direntry);
-    uint32_t offset = 0;
-    int first_mapping_index = -1;
-    mapping_t* mapping = NULL;
-    const char* basename2 = NULL;
-
-    vvfat_close_current_file(s);
-
-    /* the root directory */
-    if (cluster_num == 0)
-	return 0;
-
-    /* write support */
-    if (s->qcow) {
-	basename2 = get_basename(path);
-
-	mapping = find_mapping_for_cluster(s, cluster_num);
-
-	if (mapping) {
-	    const char* basename;
-
-	    assert(mapping->mode & MODE_DELETED);
-	    mapping->mode &= ~MODE_DELETED;
-
-	    basename = get_basename(mapping->path);
-
-	    assert(mapping->mode & MODE_NORMAL);
-
-	    /* rename */
-	    if (strcmp(basename, basename2))
-		schedule_rename(s, cluster_num, g_strdup(path));
-	} else if (is_file(direntry))
-	    /* new file */
-	    schedule_new_file(s, g_strdup(path), cluster_num);
-	else {
-            abort();
-	    return 0;
-	}
-    }
-
-    while(1) {
-	if (s->qcow) {
-	    if (!copy_it && cluster_was_modified(s, cluster_num)) {
-		if (mapping == NULL ||
-			mapping->begin > cluster_num ||
-			mapping->end <= cluster_num)
-		mapping = find_mapping_for_cluster(s, cluster_num);
-
-
-		if (mapping &&
-			(mapping->mode & MODE_DIRECTORY) == 0) {
-
-		    /* was modified in qcow */
-		    if (offset != mapping->info.file.offset + s->cluster_size
-			    * (cluster_num - mapping->begin)) {
-			/* offset of this cluster in file chain has changed */
-                        abort();
-			copy_it = 1;
-		    } else if (offset == 0) {
-			const char* basename = get_basename(mapping->path);
-
-			if (strcmp(basename, basename2))
-			    copy_it = 1;
-			first_mapping_index = array_index(&(s->mapping), mapping);
-		    }
-
-		    if (mapping->first_mapping_index != first_mapping_index
-			    && mapping->info.file.offset > 0) {
-                        abort();
-			copy_it = 1;
-		    }
-
-		    /* need to write out? */
-		    if (!was_modified && is_file(direntry)) {
-			was_modified = 1;
-			schedule_writeout(s, mapping->dir_index, offset);
-		    }
-		}
-	    }
-
-	    if (copy_it) {
-		int i, dummy;
-		/*
-		 * This is horribly inefficient, but that is okay, since
-		 * it is rarely executed, if at all.
-		 */
-		int64_t offset = cluster2sector(s, cluster_num);
-
-		vvfat_close_current_file(s);
-		for (i = 0; i < s->sectors_per_cluster; i++)
-		    if (!s->qcow->drv->bdrv_is_allocated(s->qcow,
-				offset + i, 1, &dummy)) {
-			if (vvfat_read(s->bs,
-				    offset, s->cluster_buffer, 1))
-			    return -1;
-			if (s->qcow->drv->bdrv_write(s->qcow,
-				    offset, s->cluster_buffer, 1))
-			    return -2;
-		    }
-	    }
-	}
-
-	ret++;
-	if (s->used_clusters[cluster_num] & USED_ANY)
-	    return 0;
-	s->used_clusters[cluster_num] = USED_FILE;
-
-	cluster_num = modified_fat_get(s, cluster_num);
-
-	if (fat_eof(s, cluster_num))
-	    return ret;
-	else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
-	    return -1;
-
-	offset += s->cluster_size;
-    }
-}
-
-/*
- * This function looks at the modified data (qcow).
- * It returns 0 upon inconsistency or error, and the number of clusters
- * used by the directory, its subdirectories and their files.
- */
-static int check_directory_consistency(BDRVVVFATState *s,
-	int cluster_num, const char* path)
-{
-    int ret = 0;
-    unsigned char* cluster = g_malloc(s->cluster_size);
-    direntry_t* direntries = (direntry_t*)cluster;
-    mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
-
-    long_file_name lfn;
-    int path_len = strlen(path);
-    char path2[PATH_MAX];
-
-    assert(path_len < PATH_MAX); /* len was tested before! */
-    pstrcpy(path2, sizeof(path2), path);
-    path2[path_len] = '/';
-    path2[path_len + 1] = '\0';
-
-    if (mapping) {
-	const char* basename = get_basename(mapping->path);
-	const char* basename2 = get_basename(path);
-
-	assert(mapping->mode & MODE_DIRECTORY);
-
-	assert(mapping->mode & MODE_DELETED);
-	mapping->mode &= ~MODE_DELETED;
-
-	if (strcmp(basename, basename2))
-	    schedule_rename(s, cluster_num, g_strdup(path));
-    } else
-	/* new directory */
-	schedule_mkdir(s, cluster_num, g_strdup(path));
-
-    lfn_init(&lfn);
-    do {
-	int i;
-	int subret = 0;
-
-	ret++;
-
-	if (s->used_clusters[cluster_num] & USED_ANY) {
-	    fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
-	    return 0;
-	}
-	s->used_clusters[cluster_num] = USED_DIRECTORY;
-
-DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
-	subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
-		s->sectors_per_cluster);
-	if (subret) {
-	    fprintf(stderr, "Error fetching direntries\n");
-	fail:
-	    free(cluster);
-	    return 0;
-	}
-
-	for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
-	    int cluster_count = 0;
-
-DLOG(fprintf(stderr, "check direntry %d: \n", i); print_direntry(direntries + i));
-	    if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
-		    is_free(direntries + i))
-		continue;
-
-	    subret = parse_long_name(&lfn, direntries + i);
-	    if (subret < 0) {
-		fprintf(stderr, "Error in long name\n");
-		goto fail;
-	    }
-	    if (subret == 0 || is_free(direntries + i))
-		continue;
-
-	    if (fat_chksum(direntries+i) != lfn.checksum) {
-		subret = parse_short_name(s, &lfn, direntries + i);
-		if (subret < 0) {
-		    fprintf(stderr, "Error in short name (%d)\n", subret);
-		    goto fail;
-		}
-		if (subret > 0 || !strcmp((char*)lfn.name, ".")
-			|| !strcmp((char*)lfn.name, ".."))
-		    continue;
-	    }
-	    lfn.checksum = 0x100; /* cannot use long name twice */
-
-	    if (path_len + 1 + lfn.len >= PATH_MAX) {
-		fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
-		goto fail;
-	    }
-            pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
-                    (char*)lfn.name);
-
-	    if (is_directory(direntries + i)) {
-		if (begin_of_direntry(direntries + i) == 0) {
-		    DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
-		    goto fail;
-		}
-		cluster_count = check_directory_consistency(s,
-			begin_of_direntry(direntries + i), path2);
-		if (cluster_count == 0) {
-		    DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
-		    goto fail;
-		}
-	    } else if (is_file(direntries + i)) {
-		/* check file size with FAT */
-		cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
-		if (cluster_count !=
-			(le32_to_cpu(direntries[i].size) + s->cluster_size
-			 - 1) / s->cluster_size) {
-		    DLOG(fprintf(stderr, "Cluster count mismatch\n"));
-		    goto fail;
-		}
-	    } else
-                abort(); /* cluster_count = 0; */
-
-	    ret += cluster_count;
-	}
-
-	cluster_num = modified_fat_get(s, cluster_num);
-    } while(!fat_eof(s, cluster_num));
-
-    free(cluster);
-    return ret;
-}
-
-/* returns 1 on success */
-static int is_consistent(BDRVVVFATState* s)
-{
-    int i, check;
-    int used_clusters_count = 0;
-
-DLOG(checkpoint());
-    /*
-     * - get modified FAT
-     * - compare the two FATs (TODO)
-     * - get buffer for marking used clusters
-     * - recurse direntries from root (using bs->bdrv_read to make
-     *    sure to get the new data)
-     *   - check that the FAT agrees with the size
-     *   - count the number of clusters occupied by this directory and
-     *     its files
-     * - check that the cumulative used cluster count agrees with the
-     *   FAT
-     * - if all is fine, return number of used clusters
-     */
-    if (s->fat2 == NULL) {
-	int size = 0x200 * s->sectors_per_fat;
-	s->fat2 = g_malloc(size);
-	memcpy(s->fat2, s->fat.pointer, size);
-    }
-    check = vvfat_read(s->bs,
-	    s->first_sectors_number, s->fat2, s->sectors_per_fat);
-    if (check) {
-	fprintf(stderr, "Could not copy fat\n");
-	return 0;
-    }
-    assert (s->used_clusters);
-    for (i = 0; i < sector2cluster(s, s->sector_count); i++)
-	s->used_clusters[i] &= ~USED_ANY;
-
-    clear_commits(s);
-
-    /* mark every mapped file/directory as deleted.
-     * (check_directory_consistency() will unmark those still present). */
-    if (s->qcow)
-	for (i = 0; i < s->mapping.next; i++) {
-	    mapping_t* mapping = array_get(&(s->mapping), i);
-	    if (mapping->first_mapping_index < 0)
-		mapping->mode |= MODE_DELETED;
-	}
-
-    used_clusters_count = check_directory_consistency(s, 0, s->path);
-    if (used_clusters_count <= 0) {
-	DLOG(fprintf(stderr, "problem in directory\n"));
-	return 0;
-    }
-
-    check = s->last_cluster_of_root_directory;
-    for (i = check; i < sector2cluster(s, s->sector_count); i++) {
-	if (modified_fat_get(s, i)) {
-	    if(!s->used_clusters[i]) {
-		DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
-		return 0;
-	    }
-	    check++;
-	}
-
-	if (s->used_clusters[i] == USED_ALLOCATED) {
-	    /* allocated, but not used... */
-	    DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
-	    return 0;
-	}
-    }
-
-    if (check != used_clusters_count)
-	return 0;
-
-    return used_clusters_count;
-}
-
-static inline void adjust_mapping_indices(BDRVVVFATState* s,
-	int offset, int adjust)
-{
-    int i;
-
-    for (i = 0; i < s->mapping.next; i++) {
-	mapping_t* mapping = array_get(&(s->mapping), i);
-
-#define ADJUST_MAPPING_INDEX(name) \
-	if (mapping->name >= offset) \
-	    mapping->name += adjust
-
-	ADJUST_MAPPING_INDEX(first_mapping_index);
-	if (mapping->mode & MODE_DIRECTORY)
-	    ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
-    }
-}
-
-/* insert or update mapping */
-static mapping_t* insert_mapping(BDRVVVFATState* s,
-	uint32_t begin, uint32_t end)
-{
-    /*
-     * - find mapping where mapping->begin >= begin,
-     * - if mapping->begin > begin: insert
-     *   - adjust all references to mappings!
-     * - else: adjust
-     * - replace name
-     */
-    int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
-    mapping_t* mapping = NULL;
-    mapping_t* first_mapping = array_get(&(s->mapping), 0);
-
-    if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
-	    && mapping->begin < begin) {
-	mapping->end = begin;
-	index++;
-	mapping = array_get(&(s->mapping), index);
-    }
-    if (index >= s->mapping.next || mapping->begin > begin) {
-	mapping = array_insert(&(s->mapping), index, 1);
-	mapping->path = NULL;
-	adjust_mapping_indices(s, index, +1);
-    }
-
-    mapping->begin = begin;
-    mapping->end = end;
-
-DLOG(mapping_t* next_mapping;
-assert(index + 1 >= s->mapping.next ||
-((next_mapping = array_get(&(s->mapping), index + 1)) &&
- next_mapping->begin >= end)));
-
-    if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
-	s->current_mapping = array_get(&(s->mapping),
-		s->current_mapping - first_mapping);
-
-    return mapping;
-}
-
-static int remove_mapping(BDRVVVFATState* s, int mapping_index)
-{
-    mapping_t* mapping = array_get(&(s->mapping), mapping_index);
-    mapping_t* first_mapping = array_get(&(s->mapping), 0);
-
-    /* free mapping */
-    if (mapping->first_mapping_index < 0)
-	free(mapping->path);
-
-    /* remove from s->mapping */
-    array_remove(&(s->mapping), mapping_index);
-
-    /* adjust all references to mappings */
-    adjust_mapping_indices(s, mapping_index, -1);
-
-    if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
-	s->current_mapping = array_get(&(s->mapping),
-		s->current_mapping - first_mapping);
-
-    return 0;
-}
-
-static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
-{
-    int i;
-    for (i = 0; i < s->mapping.next; i++) {
-	mapping_t* mapping = array_get(&(s->mapping), i);
-	if (mapping->dir_index >= offset)
-	    mapping->dir_index += adjust;
-	if ((mapping->mode & MODE_DIRECTORY) &&
-		mapping->info.dir.first_dir_index >= offset)
-	    mapping->info.dir.first_dir_index += adjust;
-    }
-}
-
-static direntry_t* insert_direntries(BDRVVVFATState* s,
-	int dir_index, int count)
-{
-    /*
-     * make room in s->directory,
-     * adjust_dirindices
-     */
-    direntry_t* result = array_insert(&(s->directory), dir_index, count);
-    if (result == NULL)
-	return NULL;
-    adjust_dirindices(s, dir_index, count);
-    return result;
-}
-
-static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
-{
-    int ret = array_remove_slice(&(s->directory), dir_index, count);
-    if (ret)
-	return ret;
-    adjust_dirindices(s, dir_index, -count);
-    return 0;
-}
-
-/*
- * Adapt the mappings of the cluster chain starting at first cluster
- * (i.e. if a file starts at first_cluster, the chain is followed according
- * to the modified fat, and the corresponding entries in s->mapping are
- * adjusted)
- */
-static int commit_mappings(BDRVVVFATState* s,
-	uint32_t first_cluster, int dir_index)
-{
-    mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
-    direntry_t* direntry = array_get(&(s->directory), dir_index);
-    uint32_t cluster = first_cluster;
-
-    vvfat_close_current_file(s);
-
-    assert(mapping);
-    assert(mapping->begin == first_cluster);
-    mapping->first_mapping_index = -1;
-    mapping->dir_index = dir_index;
-    mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
-	MODE_DIRECTORY : MODE_NORMAL;
-
-    while (!fat_eof(s, cluster)) {
-	uint32_t c, c1;
-
-	for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
-		c = c1, c1 = modified_fat_get(s, c1));
-
-	c++;
-	if (c > mapping->end) {
-	    int index = array_index(&(s->mapping), mapping);
-	    int i, max_i = s->mapping.next - index;
-	    for (i = 1; i < max_i && mapping[i].begin < c; i++);
-	    while (--i > 0)
-		remove_mapping(s, index + 1);
-	}
-	assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
-		|| mapping[1].begin >= c);
-	mapping->end = c;
-
-	if (!fat_eof(s, c1)) {
-	    int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
-	    mapping_t* next_mapping = i >= s->mapping.next ? NULL :
-		array_get(&(s->mapping), i);
-
-	    if (next_mapping == NULL || next_mapping->begin > c1) {
-		int i1 = array_index(&(s->mapping), mapping);
-
-		next_mapping = insert_mapping(s, c1, c1+1);
-
-		if (c1 < c)
-		    i1++;
-		mapping = array_get(&(s->mapping), i1);
-	    }
-
-	    next_mapping->dir_index = mapping->dir_index;
-	    next_mapping->first_mapping_index =
-		mapping->first_mapping_index < 0 ?
-		array_index(&(s->mapping), mapping) :
-		mapping->first_mapping_index;
-	    next_mapping->path = mapping->path;
-	    next_mapping->mode = mapping->mode;
-	    next_mapping->read_only = mapping->read_only;
-	    if (mapping->mode & MODE_DIRECTORY) {
-		next_mapping->info.dir.parent_mapping_index =
-			mapping->info.dir.parent_mapping_index;
-		next_mapping->info.dir.first_dir_index =
-			mapping->info.dir.first_dir_index +
-			0x10 * s->sectors_per_cluster *
-			(mapping->end - mapping->begin);
-	    } else
-		next_mapping->info.file.offset = mapping->info.file.offset +
-			mapping->end - mapping->begin;
-
-	    mapping = next_mapping;
-	}
-
-	cluster = c1;
-    }
-
-    return 0;
-}
-
-static int commit_direntries(BDRVVVFATState* s,
-	int dir_index, int parent_mapping_index)
-{
-    direntry_t* direntry = array_get(&(s->directory), dir_index);
-    uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
-    mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
-
-    int factor = 0x10 * s->sectors_per_cluster;
-    int old_cluster_count, new_cluster_count;
-    int current_dir_index = mapping->info.dir.first_dir_index;
-    int first_dir_index = current_dir_index;
-    int ret, i;
-    uint32_t c;
-
-DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapping->path, parent_mapping_index));
-
-    assert(direntry);
-    assert(mapping);
-    assert(mapping->begin == first_cluster);
-    assert(mapping->info.dir.first_dir_index < s->directory.next);
-    assert(mapping->mode & MODE_DIRECTORY);
-    assert(dir_index == 0 || is_directory(direntry));
-
-    mapping->info.dir.parent_mapping_index = parent_mapping_index;
-
-    if (first_cluster == 0) {
-	old_cluster_count = new_cluster_count =
-	    s->last_cluster_of_root_directory;
-    } else {
-	for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
-		c = fat_get(s, c))
-	    old_cluster_count++;
-
-	for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
-		c = modified_fat_get(s, c))
-	    new_cluster_count++;
-    }
-
-    if (new_cluster_count > old_cluster_count) {
-	if (insert_direntries(s,
-		current_dir_index + factor * old_cluster_count,
-		factor * (new_cluster_count - old_cluster_count)) == NULL)
-	    return -1;
-    } else if (new_cluster_count < old_cluster_count)
-	remove_direntries(s,
-		current_dir_index + factor * new_cluster_count,
-		factor * (old_cluster_count - new_cluster_count));
-
-    for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
-	void* direntry = array_get(&(s->directory), current_dir_index);
-	int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
-		s->sectors_per_cluster);
-	if (ret)
-	    return ret;
-	assert(!strncmp(s->directory.pointer, "QEMU", 4));
-	current_dir_index += factor;
-    }
-
-    ret = commit_mappings(s, first_cluster, dir_index);
-    if (ret)
-	return ret;
-
-    /* recurse */
-    for (i = 0; i < factor * new_cluster_count; i++) {
-	direntry = array_get(&(s->directory), first_dir_index + i);
-	if (is_directory(direntry) && !is_dot(direntry)) {
-	    mapping = find_mapping_for_cluster(s, first_cluster);
-	    assert(mapping->mode & MODE_DIRECTORY);
-	    ret = commit_direntries(s, first_dir_index + i,
-		array_index(&(s->mapping), mapping));
-	    if (ret)
-		return ret;
-	}
-    }
-
-    return 0;
-}
-
-/* commit one file (adjust contents, adjust mapping),
-   return first_mapping_index */
-static int commit_one_file(BDRVVVFATState* s,
-	int dir_index, uint32_t offset)
-{
-    direntry_t* direntry = array_get(&(s->directory), dir_index);
-    uint32_t c = begin_of_direntry(direntry);
-    uint32_t first_cluster = c;
-    mapping_t* mapping = find_mapping_for_cluster(s, c);
-    uint32_t size = filesize_of_direntry(direntry);
-    char* cluster = g_malloc(s->cluster_size);
-    uint32_t i;
-    int fd = 0;
-
-    assert(offset < size);
-    assert((offset % s->cluster_size) == 0);
-
-    for (i = s->cluster_size; i < offset; i += s->cluster_size)
-	c = modified_fat_get(s, c);
-
-    fd = open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
-    if (fd < 0) {
-	fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
-		strerror(errno), errno);
-	return fd;
-    }
-    if (offset > 0)
-	if (lseek(fd, offset, SEEK_SET) != offset)
-	    return -3;
-
-    while (offset < size) {
-	uint32_t c1;
-	int rest_size = (size - offset > s->cluster_size ?
-		s->cluster_size : size - offset);
-	int ret;
-
-	c1 = modified_fat_get(s, c);
-
-	assert((size - offset == 0 && fat_eof(s, c)) ||
-		(size > offset && c >=2 && !fat_eof(s, c)));
-
-	ret = vvfat_read(s->bs, cluster2sector(s, c),
-	    (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
-
-	if (ret < 0)
-	    return ret;
-
-	if (write(fd, cluster, rest_size) < 0)
-	    return -2;
-
-	offset += rest_size;
-	c = c1;
-    }
-
-    if (ftruncate(fd, size)) {
-        perror("ftruncate()");
-        close(fd);
-        return -4;
-    }
-    close(fd);
-
-    return commit_mappings(s, first_cluster, dir_index);
-}
-
-#ifdef DEBUG
-/* test, if all mappings point to valid direntries */
-static void check1(BDRVVVFATState* s)
-{
-    int i;
-    for (i = 0; i < s->mapping.next; i++) {
-	mapping_t* mapping = array_get(&(s->mapping), i);
-	if (mapping->mode & MODE_DELETED) {
-	    fprintf(stderr, "deleted\n");
-	    continue;
-	}
-	assert(mapping->dir_index >= 0);
-	assert(mapping->dir_index < s->directory.next);
-	direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
-	assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
-	if (mapping->mode & MODE_DIRECTORY) {
-	    assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
-	    assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
-	}
-    }
-}
-
-/* test, if all direntries have mappings */
-static void check2(BDRVVVFATState* s)
-{
-    int i;
-    int first_mapping = -1;
-
-    for (i = 0; i < s->directory.next; i++) {
-	direntry_t* direntry = array_get(&(s->directory), i);
-
-	if (is_short_name(direntry) && begin_of_direntry(direntry)) {
-	    mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
-	    assert(mapping);
-	    assert(mapping->dir_index == i || is_dot(direntry));
-	    assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
-	}
-
-	if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
-	    /* cluster start */
-	    int j, count = 0;
-
-	    for (j = 0; j < s->mapping.next; j++) {
-		mapping_t* mapping = array_get(&(s->mapping), j);
-		if (mapping->mode & MODE_DELETED)
-		    continue;
-		if (mapping->mode & MODE_DIRECTORY) {
-		    if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
-			assert(++count == 1);
-			if (mapping->first_mapping_index == -1)
-			    first_mapping = array_index(&(s->mapping), mapping);
-			else
-			    assert(first_mapping == mapping->first_mapping_index);
-			if (mapping->info.dir.parent_mapping_index < 0)
-			    assert(j == 0);
-			else {
-			    mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
-			    assert(parent->mode & MODE_DIRECTORY);
-			    assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
-			}
-		    }
-		}
-	    }
-	    if (count == 0)
-		first_mapping = -1;
-	}
-    }
-}
-#endif
-
-static int handle_renames_and_mkdirs(BDRVVVFATState* s)
-{
-    int i;
-
-#ifdef DEBUG
-    fprintf(stderr, "handle_renames\n");
-    for (i = 0; i < s->commits.next; i++) {
-	commit_t* commit = array_get(&(s->commits), i);
-	fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
-    }
-#endif
-
-    for (i = 0; i < s->commits.next;) {
-	commit_t* commit = array_get(&(s->commits), i);
-	if (commit->action == ACTION_RENAME) {
-	    mapping_t* mapping = find_mapping_for_cluster(s,
-		    commit->param.rename.cluster);
-	    char* old_path = mapping->path;
-
-	    assert(commit->path);
-	    mapping->path = commit->path;
-	    if (rename(old_path, mapping->path))
-		return -2;
-
-	    if (mapping->mode & MODE_DIRECTORY) {
-		int l1 = strlen(mapping->path);
-		int l2 = strlen(old_path);
-		int diff = l1 - l2;
-		direntry_t* direntry = array_get(&(s->directory),
-			mapping->info.dir.first_dir_index);
-		uint32_t c = mapping->begin;
-		int i = 0;
-
-		/* recurse */
-		while (!fat_eof(s, c)) {
-		    do {
-			direntry_t* d = direntry + i;
-
-			if (is_file(d) || (is_directory(d) && !is_dot(d))) {
-			    mapping_t* m = find_mapping_for_cluster(s,
-				    begin_of_direntry(d));
-			    int l = strlen(m->path);
-			    char* new_path = g_malloc(l + diff + 1);
-
-			    assert(!strncmp(m->path, mapping->path, l2));
-
-                            pstrcpy(new_path, l + diff + 1, mapping->path);
-                            pstrcpy(new_path + l1, l + diff + 1 - l1,
-                                    m->path + l2);
-
-			    schedule_rename(s, m->begin, new_path);
-			}
-			i++;
-		    } while((i % (0x10 * s->sectors_per_cluster)) != 0);
-		    c = fat_get(s, c);
-		}
-	    }
-
-	    free(old_path);
-	    array_remove(&(s->commits), i);
-	    continue;
-	} else if (commit->action == ACTION_MKDIR) {
-	    mapping_t* mapping;
-	    int j, parent_path_len;
-
-#ifdef __MINGW32__
-            if (mkdir(commit->path))
-                return -5;
-#else
-            if (mkdir(commit->path, 0755))
-                return -5;
-#endif
-
-	    mapping = insert_mapping(s, commit->param.mkdir.cluster,
-		    commit->param.mkdir.cluster + 1);
-	    if (mapping == NULL)
-		return -6;
-
-	    mapping->mode = MODE_DIRECTORY;
-	    mapping->read_only = 0;
-	    mapping->path = commit->path;
-	    j = s->directory.next;
-	    assert(j);
-	    insert_direntries(s, s->directory.next,
-		    0x10 * s->sectors_per_cluster);
-	    mapping->info.dir.first_dir_index = j;
-
-	    parent_path_len = strlen(commit->path)
-		- strlen(get_basename(commit->path)) - 1;
-	    for (j = 0; j < s->mapping.next; j++) {
-		mapping_t* m = array_get(&(s->mapping), j);
-		if (m->first_mapping_index < 0 && m != mapping &&
-			!strncmp(m->path, mapping->path, parent_path_len) &&
-			strlen(m->path) == parent_path_len)
-		    break;
-	    }
-	    assert(j < s->mapping.next);
-	    mapping->info.dir.parent_mapping_index = j;
-
-	    array_remove(&(s->commits), i);
-	    continue;
-	}
-
-	i++;
-    }
-    return 0;
-}
-
-/*
- * TODO: make sure that the short name is not matching *another* file
- */
-static int handle_commits(BDRVVVFATState* s)
-{
-    int i, fail = 0;
-
-    vvfat_close_current_file(s);
-
-    for (i = 0; !fail && i < s->commits.next; i++) {
-	commit_t* commit = array_get(&(s->commits), i);
-	switch(commit->action) {
-	case ACTION_RENAME: case ACTION_MKDIR:
-            abort();
-	    fail = -2;
-	    break;
-	case ACTION_WRITEOUT: {
-#ifndef NDEBUG
-            /* these variables are only used by assert() below */
-	    direntry_t* entry = array_get(&(s->directory),
-		    commit->param.writeout.dir_index);
-	    uint32_t begin = begin_of_direntry(entry);
-	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
-#endif
-
-	    assert(mapping);
-	    assert(mapping->begin == begin);
-	    assert(commit->path == NULL);
-
-	    if (commit_one_file(s, commit->param.writeout.dir_index,
-			commit->param.writeout.modified_offset))
-		fail = -3;
-
-	    break;
-	}
-	case ACTION_NEW_FILE: {
-	    int begin = commit->param.new_file.first_cluster;
-	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
-	    direntry_t* entry;
-	    int i;
-
-	    /* find direntry */
-	    for (i = 0; i < s->directory.next; i++) {
-		entry = array_get(&(s->directory), i);
-		if (is_file(entry) && begin_of_direntry(entry) == begin)
-		    break;
-	    }
-
-	    if (i >= s->directory.next) {
-		fail = -6;
-		continue;
-	    }
-
-	    /* make sure there exists an initial mapping */
-	    if (mapping && mapping->begin != begin) {
-		mapping->end = begin;
-		mapping = NULL;
-	    }
-	    if (mapping == NULL) {
-		mapping = insert_mapping(s, begin, begin+1);
-	    }
-	    /* most members will be fixed in commit_mappings() */
-	    assert(commit->path);
-	    mapping->path = commit->path;
-	    mapping->read_only = 0;
-	    mapping->mode = MODE_NORMAL;
-	    mapping->info.file.offset = 0;
-
-	    if (commit_one_file(s, i, 0))
-		fail = -7;
-
-	    break;
-	}
-	default:
-            abort();
-	}
-    }
-    if (i > 0 && array_remove_slice(&(s->commits), 0, i))
-	return -1;
-    return fail;
-}
-
-static int handle_deletes(BDRVVVFATState* s)
-{
-    int i, deferred = 1, deleted = 1;
-
-    /* delete files corresponding to mappings marked as deleted */
-    /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
-    while (deferred && deleted) {
-	deferred = 0;
-	deleted = 0;
-
-	for (i = 1; i < s->mapping.next; i++) {
-	    mapping_t* mapping = array_get(&(s->mapping), i);
-	    if (mapping->mode & MODE_DELETED) {
-		direntry_t* entry = array_get(&(s->directory),
-			mapping->dir_index);
-
-		if (is_free(entry)) {
-		    /* remove file/directory */
-		    if (mapping->mode & MODE_DIRECTORY) {
-			int j, next_dir_index = s->directory.next,
-			first_dir_index = mapping->info.dir.first_dir_index;
-
-			if (rmdir(mapping->path) < 0) {
-			    if (errno == ENOTEMPTY) {
-				deferred++;
-				continue;
-			    } else
-				return -5;
-			}
-
-			for (j = 1; j < s->mapping.next; j++) {
-			    mapping_t* m = array_get(&(s->mapping), j);
-			    if (m->mode & MODE_DIRECTORY &&
-				    m->info.dir.first_dir_index >
-				    first_dir_index &&
-				    m->info.dir.first_dir_index <
-				    next_dir_index)
-				next_dir_index =
-				    m->info.dir.first_dir_index;
-			}
-			remove_direntries(s, first_dir_index,
-				next_dir_index - first_dir_index);
-
-			deleted++;
-		    }
-		} else {
-		    if (unlink(mapping->path))
-			return -4;
-		    deleted++;
-		}
-		DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
-		remove_mapping(s, i);
-	    }
-	}
-    }
-
-    return 0;
-}
-
-/*
- * synchronize mapping with new state:
- *
- * - copy FAT (with bdrv_read)
- * - mark all filenames corresponding to mappings as deleted
- * - recurse direntries from root (using bs->bdrv_read)
- * - delete files corresponding to mappings marked as deleted
- */
-static int do_commit(BDRVVVFATState* s)
-{
-    int ret = 0;
-
-    /* the real meat are the commits. Nothing to do? Move along! */
-    if (s->commits.next == 0)
-	return 0;
-
-    vvfat_close_current_file(s);
-
-    ret = handle_renames_and_mkdirs(s);
-    if (ret) {
-	fprintf(stderr, "Error handling renames (%d)\n", ret);
-        abort();
-	return ret;
-    }
-
-    /* copy FAT (with bdrv_read) */
-    memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
-
-    /* recurse direntries from root (using bs->bdrv_read) */
-    ret = commit_direntries(s, 0, -1);
-    if (ret) {
-	fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
-        abort();
-	return ret;
-    }
-
-    ret = handle_commits(s);
-    if (ret) {
-	fprintf(stderr, "Error handling commits (%d)\n", ret);
-        abort();
-	return ret;
-    }
-
-    ret = handle_deletes(s);
-    if (ret) {
-	fprintf(stderr, "Error deleting\n");
-        abort();
-	return ret;
-    }
-
-    s->qcow->drv->bdrv_make_empty(s->qcow);
-
-    memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
-
-DLOG(checkpoint());
-    return 0;
-}
-
-static int try_commit(BDRVVVFATState* s)
-{
-    vvfat_close_current_file(s);
-DLOG(checkpoint());
-    if(!is_consistent(s))
-	return -1;
-    return do_commit(s);
-}
-
-static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
-                    const uint8_t *buf, int nb_sectors)
-{
-    BDRVVVFATState *s = bs->opaque;
-    int i, ret;
-
-DLOG(checkpoint());
-
-    vvfat_close_current_file(s);
-
-    /*
-     * Some sanity checks:
-     * - do not allow writing to the boot sector
-     * - do not allow to write non-ASCII filenames
-     */
-
-    if (sector_num < s->first_sectors_number)
-	return -1;
-
-    for (i = sector2cluster(s, sector_num);
-	    i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
-	mapping_t* mapping = find_mapping_for_cluster(s, i);
-	if (mapping) {
-	    if (mapping->read_only) {
-		fprintf(stderr, "Tried to write to write-protected file %s\n",
-			mapping->path);
-		return -1;
-	    }
-
-	    if (mapping->mode & MODE_DIRECTORY) {
-		int begin = cluster2sector(s, i);
-		int end = begin + s->sectors_per_cluster, k;
-		int dir_index;
-		const direntry_t* direntries;
-		long_file_name lfn;
-
-		lfn_init(&lfn);
-
-		if (begin < sector_num)
-		    begin = sector_num;
-		if (end > sector_num + nb_sectors)
-		    end = sector_num + nb_sectors;
-		dir_index  = mapping->dir_index +
-		    0x10 * (begin - mapping->begin * s->sectors_per_cluster);
-		direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
-
-		for (k = 0; k < (end - begin) * 0x10; k++) {
-		    /* do not allow non-ASCII filenames */
-		    if (parse_long_name(&lfn, direntries + k) < 0) {
-			fprintf(stderr, "Warning: non-ASCII filename\n");
-			return -1;
-		    }
-		    /* no access to the direntry of a read-only file */
-		    else if (is_short_name(direntries+k) &&
-			    (direntries[k].attributes & 1)) {
-			if (memcmp(direntries + k,
-				    array_get(&(s->directory), dir_index + k),
-				    sizeof(direntry_t))) {
-			    fprintf(stderr, "Warning: tried to write to write-protected file\n");
-			    return -1;
-			}
-		    }
-		}
-	    }
-	    i = mapping->end;
-	} else
-	    i++;
-    }
-
-    /*
-     * Use qcow backend. Commit later.
-     */
-DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
-    ret = s->qcow->drv->bdrv_write(s->qcow, sector_num, buf, nb_sectors);
-    if (ret < 0) {
-	fprintf(stderr, "Error writing to qcow backend\n");
-	return ret;
-    }
-
-    for (i = sector2cluster(s, sector_num);
-	    i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
-	if (i >= 0)
-	    s->used_clusters[i] |= USED_ALLOCATED;
-
-DLOG(checkpoint());
-    /* TODO: add timeout */
-    try_commit(s);
-
-DLOG(checkpoint());
-    return 0;
-}
-
-static int vvfat_is_allocated(BlockDriverState *bs,
-	int64_t sector_num, int nb_sectors, int* n)
-{
-    BDRVVVFATState* s = bs->opaque;
-    *n = s->sector_count - sector_num;
-    if (*n > nb_sectors)
-	*n = nb_sectors;
-    else if (*n < 0)
-	return 0;
-    return 1;
-}
-
-static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
-	const uint8_t* buffer, int nb_sectors) {
-    BDRVVVFATState* s = bs->opaque;
-    return try_commit(s);
-}
-
-static void write_target_close(BlockDriverState *bs) {
-    BDRVVVFATState* s = bs->opaque;
-    bdrv_delete(s->qcow);
-    free(s->qcow_filename);
-}
-
-static BlockDriver vvfat_write_target = {
-    .format_name        = "vvfat_write_target",
-    .bdrv_write         = write_target_commit,
-    .bdrv_close         = write_target_close,
-};
-
-static int enable_write_target(BDRVVVFATState *s)
-{
-    BlockDriver *bdrv_qcow;
-    QEMUOptionParameter *options;
-    int size = sector2cluster(s, s->sector_count);
-    s->used_clusters = calloc(size, 1);
-
-    array_init(&(s->commits), sizeof(commit_t));
-
-    s->qcow_filename = g_malloc(1024);
-    get_tmp_filename(s->qcow_filename, 1024);
-
-    bdrv_qcow = bdrv_find_format("qcow");
-    options = parse_option_parameters("", bdrv_qcow->create_options, NULL);
-    set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
-    set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");
-
-    if (bdrv_create(bdrv_qcow, s->qcow_filename, options) < 0)
-	return -1;
-    s->qcow = bdrv_new("");
-    if (s->qcow == NULL ||
-        bdrv_open(s->qcow, s->qcow_filename, BDRV_O_RDWR, bdrv_qcow) < 0)
-    {
-	return -1;
-    }
-
-#ifndef _WIN32
-    unlink(s->qcow_filename);
-#endif
-
-    s->bs->backing_hd = calloc(sizeof(BlockDriverState), 1);
-    s->bs->backing_hd->drv = &vvfat_write_target;
-    s->bs->backing_hd->opaque = s;
-
-    return 0;
-}
-
-static void vvfat_close(BlockDriverState *bs)
-{
-    BDRVVVFATState *s = bs->opaque;
-
-    vvfat_close_current_file(s);
-    array_free(&(s->fat));
-    array_free(&(s->directory));
-    array_free(&(s->mapping));
-    if(s->cluster_buffer)
-        free(s->cluster_buffer);
-}
-
-static BlockDriver bdrv_vvfat = {
-    .format_name	= "vvfat",
-    .instance_size	= sizeof(BDRVVVFATState),
-    .bdrv_file_open	= vvfat_open,
-    .bdrv_read		= vvfat_read,
-    .bdrv_write		= vvfat_write,
-    .bdrv_close		= vvfat_close,
-    .bdrv_is_allocated	= vvfat_is_allocated,
-    .protocol_name	= "fat",
-};
-
-static void bdrv_vvfat_init(void)
-{
-    bdrv_register(&bdrv_vvfat);
-}
-
-block_init(bdrv_vvfat_init);
-
-#ifdef DEBUG
-static void checkpoint(void) {
-    assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
-    check1(vvv);
-    check2(vvv);
-    assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
-#if 0
-    if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)
-	fprintf(stderr, "Nonono!\n");
-    mapping_t* mapping;
-    direntry_t* direntry;
-    assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);
-    assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);
-    if (vvv->mapping.next<47)
-	return;
-    assert((mapping = array_get(&(vvv->mapping), 47)));
-    assert(mapping->dir_index < vvv->directory.next);
-    direntry = array_get(&(vvv->directory), mapping->dir_index);
-    assert(!memcmp(direntry->name, "USB     H  ", 11) || direntry->name[0]==0);
-#endif
-    return;
-    /* avoid compiler warnings: */
-    hexdump(NULL, 100);
-    remove_mapping(vvv, 0);
-    print_mapping(NULL);
-    print_direntry(NULL);
-}
-#endif
diff --git a/blockdev.c b/blockdev.c
index 08fdf57..5a024c9 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -567,6 +567,8 @@
     return 0;
 }
 
+#ifndef CONFIG_ANDROID
+// Monitor support disabled on Android.
 int do_change_block(Monitor *mon, const char *device,
                     const char *filename, const char *fmt)
 {
@@ -592,8 +594,9 @@
     bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR;
     bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0;
     if (bdrv_open(bs, filename, bdrv_flags, drv) < 0) {
-        qerror_report(QERR_OPEN_FILE_FAILED, filename);
+        qerror_report(QERR_IO_ERROR);
         return -1;
     }
     return monitor_read_bdrv_key_start(mon, bs, NULL, NULL);
 }
+#endif
diff --git a/bt-host.c b/bt-host.c
index f80e685..26cb22c 100644
--- a/bt-host.c
+++ b/bt-host.c
@@ -171,7 +171,7 @@
     hci_filter_all_ptypes(&flt);
     hci_filter_all_events(&flt);
 
-    if (setsockopt(fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
+    if (qemu_setsockopt(fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
         fprintf(stderr, "qemu: Can't set HCI filter on socket (%i)\n", errno);
         return 0;
     }
diff --git a/buffered_file.c b/buffered_file.c
index a16da03..a6e93a6 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -250,6 +250,14 @@
     s->put_ready(s->opaque);
 }
 
+static const QEMUFileOps buffered_file_ops = {
+    .put_buffer = buffered_put_buffer,
+    .close = buffered_close,
+    .rate_limit = buffered_rate_limit,
+    .set_rate_limit = buffered_set_rate_limit,
+    .get_rate_limit = buffered_get_rate_limit,
+};
+
 QEMUFile *qemu_fopen_ops_buffered(void *opaque,
                                   size_t bytes_per_sec,
                                   BufferedPutFunc *put_buffer,
@@ -268,11 +276,7 @@
     s->wait_for_unfreeze = wait_for_unfreeze;
     s->close = close;
 
-    s->file = qemu_fopen_ops(s, buffered_put_buffer, NULL,
-                             buffered_close, buffered_rate_limit,
-                             buffered_set_rate_limit,
-			     buffered_get_rate_limit);
-
+    s->file = qemu_fopen_ops(s, &buffered_file_ops);
     s->timer = qemu_new_timer_ms(rt_clock, buffered_rate_tick, s);
 
     qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 100);
diff --git a/cpu-exec.c b/cpu-exec.c
index 79172a2..d658576 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -51,7 +51,7 @@
 //#define CONFIG_DEBUG_EXEC
 //#define DEBUG_SIGNAL
 
-int qemu_cpu_has_work(CPUState *env)
+int qemu_cpu_has_work(CPUOldState *env)
 {
     return cpu_has_work(env);
 }
@@ -65,7 +65,7 @@
 /* exit the current TB from a signal handler. The host registers are
    restored in a state compatible with the CPU emulator
  */
-void cpu_resume_from_signal(CPUState *env1, void *puc)
+void cpu_resume_from_signal(CPUArchState *env1, void *puc)
 {
 #if !defined(CONFIG_SOFTMMU)
 #ifdef __linux__
@@ -206,7 +206,7 @@
     return old_handler;
 }
 
-static void cpu_handle_debug_exception(CPUState *env)
+static void cpu_handle_debug_exception(CPUOldState *env)
 {
     CPUWatchpoint *wp;
 
@@ -230,7 +230,7 @@
  * be emulated in qemu because MMIO is emulated for only one
  * instruction now and then back to the HAX kernel module.
  */
-int need_handle_intr_request(CPUState *env)
+int need_handle_intr_request(CPUOldState *env)
 {
 #ifdef CONFIG_HAX
     if (!hax_enabled() || hax_vcpu_emulation_mode(env))
@@ -241,7 +241,7 @@
 #endif
 }
 
-int cpu_exec(CPUState *env1)
+int cpu_exec(CPUOldState *env1)
 {
     volatile host_reg_t saved_env_reg;
     int ret, interrupt_request;
diff --git a/cpus.c b/cpus.c
index d76f94a..88294c2 100644
--- a/cpus.c
+++ b/cpus.c
@@ -23,8 +23,11 @@
  */
 #include "config-host.h"
 
+#include "cpu.h"
+#include "exec/exec-all.h"
 #include "monitor/monitor.h"
 #include "sysemu/sysemu.h"
+#include "exec/exec-all.h"
 #include "exec/gdbstub.h"
 #include "sysemu/dma.h"
 #include "sysemu/kvm.h"
@@ -33,14 +36,14 @@
 
 #include "sysemu/cpus.h"
 
-static CPUState *cur_cpu;
-static CPUState *next_cpu;
+static CPUOldState *cur_cpu;
+static CPUOldState *next_cpu;
 
 /***********************************************************/
 void hw_error(const char *fmt, ...)
 {
     va_list ap;
-    CPUState *env;
+    CPUOldState *env;
 
     va_start(ap, fmt);
     fprintf(stderr, "qemu: hardware error: ");
@@ -68,7 +71,7 @@
     }
 }
 
-static int cpu_can_run(CPUState *env)
+static int cpu_can_run(CPUOldState *env)
 {
     if (env->stop)
         return 0;
@@ -77,7 +80,7 @@
     return 1;
 }
 
-static int cpu_has_work(CPUState *env)
+static int cpu_has_work(CPUOldState *env)
 {
     if (env->stop)
         return 1;
@@ -92,7 +95,7 @@
 
 int tcg_has_work(void)
 {
-    CPUState *env;
+    CPUOldState *env;
 
     for (env = first_cpu; env != NULL; env = env->next_cpu)
         if (cpu_has_work(env))
@@ -100,96 +103,9 @@
     return 0;
 }
 
-#ifndef _WIN32
-static int io_thread_fd = -1;
-
-#if 0
-static void qemu_event_increment(void)
-{
-    static const char byte = 0;
-
-    if (io_thread_fd == -1)
-        return;
-
-    write(io_thread_fd, &byte, sizeof(byte));
-}
-#endif
-
-static void qemu_event_read(void *opaque)
-{
-    int fd = (unsigned long)opaque;
-    ssize_t len;
-
-    /* Drain the notify pipe */
-    do {
-        char buffer[512];
-        len = read(fd, buffer, sizeof(buffer));
-    } while ((len == -1 && errno == EINTR) || len > 0);
-}
-
-static int qemu_event_init(void)
-{
-    int err;
-    int fds[2];
-
-    err = pipe(fds);
-    if (err == -1)
-        return -errno;
-
-    err = fcntl_setfl(fds[0], O_NONBLOCK);
-    if (err < 0)
-        goto fail;
-
-    err = fcntl_setfl(fds[1], O_NONBLOCK);
-    if (err < 0)
-        goto fail;
-
-    qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
-                         (void *)(unsigned long)fds[0]);
-
-    io_thread_fd = fds[1];
-    return 0;
-
-fail:
-    close(fds[0]);
-    close(fds[1]);
-    return err;
-}
-#else
-HANDLE qemu_event_handle;
-
-static void dummy_event_handler(void *opaque)
-{
-}
-
-static int qemu_event_init(void)
-{
-    qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
-    if (!qemu_event_handle) {
-        perror("Failed CreateEvent");
-        return -1;
-    }
-    qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
-    return 0;
-}
-
-#if 0
-static void qemu_event_increment(void)
-{
-    SetEvent(qemu_event_handle);
-}
-#endif
-#endif
-
-#ifndef CONFIG_IOTHREAD
-int qemu_init_main_loop(void)
-{
-    return qemu_event_init();
-}
-
 void qemu_init_vcpu(void *_env)
 {
-    CPUState *env = _env;
+    CPUOldState *env = _env;
 
     if (kvm_enabled())
         kvm_init_vcpu(env);
@@ -218,16 +134,17 @@
     return;
 }
 
+// In main-loop.c
+#ifdef _WIN32
+extern HANDLE qemu_event_handle;
+#endif
+
 void qemu_notify_event(void)
 {
-    CPUState *env = cpu_single_env;
+    CPUOldState *env = cpu_single_env;
 
     if (env) {
         cpu_exit(env);
-#ifdef USE_KQEMU
-        if (env->kqemu_enabled)
-            kqemu_cpu_interrupt(env);
-#endif
     /*
      * This is mainly for the Windows host, where the timer may be in
      * a different thread with vcpu. Thus the timer function needs to
@@ -264,331 +181,12 @@
     do_vm_stop(reason);
 }
 
-#else /* CONFIG_IOTHREAD */
-
-#include "qemu/thread.h"
-
-QemuMutex qemu_global_mutex;
-static QemuMutex qemu_fair_mutex;
-
-static QemuThread io_thread;
-
-static QemuThread *tcg_cpu_thread;
-static QemuCond *tcg_halt_cond;
-
-static int qemu_system_ready;
-/* cpu creation */
-static QemuCond qemu_cpu_cond;
-/* system init */
-static QemuCond qemu_system_cond;
-static QemuCond qemu_pause_cond;
-
-static void block_io_signals(void);
-static void unblock_io_signals(void);
-static int tcg_has_work(void);
-
-int qemu_init_main_loop(void)
+static int qemu_cpu_exec(CPUOldState *env)
 {
     int ret;
 
-    ret = qemu_event_init();
-    if (ret)
-        return ret;
-
-    qemu_cond_init(&qemu_pause_cond);
-    qemu_mutex_init(&qemu_fair_mutex);
-    qemu_mutex_init(&qemu_global_mutex);
-    qemu_mutex_lock(&qemu_global_mutex);
-
-    unblock_io_signals();
-    qemu_thread_self(&io_thread);
-
-    return 0;
-}
-
-static void qemu_wait_io_event(CPUState *env)
-{
-    while (!tcg_has_work())
-        qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
-
-    qemu_mutex_unlock(&qemu_global_mutex);
-
-    /*
-     * Users of qemu_global_mutex can be starved, having no chance
-     * to acquire it since this path will get to it first.
-     * So use another lock to provide fairness.
-     */
-    qemu_mutex_lock(&qemu_fair_mutex);
-    qemu_mutex_unlock(&qemu_fair_mutex);
-
-    qemu_mutex_lock(&qemu_global_mutex);
-    if (env->stop) {
-        env->stop = 0;
-        env->stopped = 1;
-        qemu_cond_signal(&qemu_pause_cond);
-    }
-}
-
-static int qemu_cpu_exec(CPUState *env);
-
-static void *kvm_cpu_thread_fn(void *arg)
-{
-    CPUState *env = arg;
-
-    block_io_signals();
-    qemu_thread_self(env->thread);
-
-    /* signal CPU creation */
-    qemu_mutex_lock(&qemu_global_mutex);
-    env->created = 1;
-    qemu_cond_signal(&qemu_cpu_cond);
-
-    /* and wait for machine initialization */
-    while (!qemu_system_ready)
-        qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
-
-    while (1) {
-        if (cpu_can_run(env))
-            qemu_cpu_exec(env);
-        qemu_wait_io_event(env);
-    }
-
-    return NULL;
-}
-
-static void tcg_cpu_exec(void);
-
-static void *tcg_cpu_thread_fn(void *arg)
-{
-    CPUState *env = arg;
-
-    block_io_signals();
-    qemu_thread_self(env->thread);
-
-    /* signal CPU creation */
-    qemu_mutex_lock(&qemu_global_mutex);
-    for (env = first_cpu; env != NULL; env = env->next_cpu)
-        env->created = 1;
-    qemu_cond_signal(&qemu_cpu_cond);
-
-    /* and wait for machine initialization */
-    while (!qemu_system_ready)
-        qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
-
-    while (1) {
-        tcg_cpu_exec();
-        qemu_wait_io_event(cur_cpu);
-    }
-
-    return NULL;
-}
-
-void qemu_cpu_kick(void *_env)
-{
-    CPUState *env = _env;
-    qemu_cond_broadcast(env->halt_cond);
-    if (kvm_enabled() || hax_enabled())
-        qemu_thread_signal(env->thread, SIGUSR1);
-}
-
-int qemu_cpu_self(void *env)
-{
-    return (cpu_single_env != NULL);
-}
-
-static void cpu_signal(int sig)
-{
-    if (cpu_single_env)
-        cpu_exit(cpu_single_env);
-}
-
-static void block_io_signals(void)
-{
-    sigset_t set;
-    struct sigaction sigact;
-
-    sigemptyset(&set);
-    sigaddset(&set, SIGUSR2);
-    sigaddset(&set, SIGIO);
-    sigaddset(&set, SIGALRM);
-    pthread_sigmask(SIG_BLOCK, &set, NULL);
-
-    sigemptyset(&set);
-    sigaddset(&set, SIGUSR1);
-    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-
-    memset(&sigact, 0, sizeof(sigact));
-    sigact.sa_handler = cpu_signal;
-    sigaction(SIGUSR1, &sigact, NULL);
-}
-
-static void unblock_io_signals(void)
-{
-    sigset_t set;
-
-    sigemptyset(&set);
-    sigaddset(&set, SIGUSR2);
-    sigaddset(&set, SIGIO);
-    sigaddset(&set, SIGALRM);
-    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-
-    sigemptyset(&set);
-    sigaddset(&set, SIGUSR1);
-    pthread_sigmask(SIG_BLOCK, &set, NULL);
-}
-
-static void qemu_signal_lock(unsigned int msecs)
-{
-    qemu_mutex_lock(&qemu_fair_mutex);
-
-    while (qemu_mutex_trylock(&qemu_global_mutex)) {
-        qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
-        if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
-            break;
-    }
-    qemu_mutex_unlock(&qemu_fair_mutex);
-}
-
-void qemu_mutex_lock_iothread(void)
-{
-    if (kvm_enabled() || hax_enabled()) {
-        qemu_mutex_lock(&qemu_fair_mutex);
-        qemu_mutex_lock(&qemu_global_mutex);
-        qemu_mutex_unlock(&qemu_fair_mutex);
-    } else
-        qemu_signal_lock(100);
-}
-
-void qemu_mutex_unlock_iothread(void)
-{
-    qemu_mutex_unlock(&qemu_global_mutex);
-}
-
-static int all_vcpus_paused(void)
-{
-    CPUState *penv = first_cpu;
-
-    while (penv) {
-        if (!penv->stopped)
-            return 0;
-        penv = (CPUState *)penv->next_cpu;
-    }
-
-    return 1;
-}
-
-void pause_all_vcpus(void)
-{
-    CPUState *penv = first_cpu;
-
-    while (penv) {
-        penv->stop = 1;
-        qemu_thread_signal(penv->thread, SIGUSR1);
-        qemu_cpu_kick(penv);
-        penv = (CPUState *)penv->next_cpu;
-    }
-
-    while (!all_vcpus_paused()) {
-        qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
-        penv = first_cpu;
-        while (penv) {
-            qemu_thread_signal(penv->thread, SIGUSR1);
-            penv = (CPUState *)penv->next_cpu;
-        }
-    }
-}
-
-void resume_all_vcpus(void)
-{
-    CPUState *penv = first_cpu;
-
-    while (penv) {
-        penv->stop = 0;
-        penv->stopped = 0;
-        qemu_thread_signal(penv->thread, SIGUSR1);
-        qemu_cpu_kick(penv);
-        penv = (CPUState *)penv->next_cpu;
-    }
-}
-
-static void tcg_init_vcpu(void *_env)
-{
-    CPUState *env = _env;
-    /* share a single thread for all cpus with TCG */
-    if (!tcg_cpu_thread) {
-        env->thread = g_malloc0(sizeof(QemuThread));
-        env->halt_cond = g_malloc0(sizeof(QemuCond));
-        qemu_cond_init(env->halt_cond);
-        qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
-        while (env->created == 0)
-            qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
-        tcg_cpu_thread = env->thread;
-        tcg_halt_cond = env->halt_cond;
-    } else {
-        env->thread = tcg_cpu_thread;
-        env->halt_cond = tcg_halt_cond;
-    }
-}
-
-static void kvm_start_vcpu(CPUState *env)
-{
-#if 0
-    kvm_init_vcpu(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, kvm_cpu_thread_fn, env);
-    while (env->created == 0)
-        qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
-#endif
-}
-
-void qemu_init_vcpu(void *_env)
-{
-    CPUState *env = _env;
-
-    if (kvm_enabled())
-        kvm_start_vcpu(env);
-    else
-        tcg_init_vcpu(env);
-}
-
-void qemu_notify_event(void)
-{
-    qemu_event_increment();
-}
-
-void vm_stop(int reason)
-{
-    QemuThread me;
-    qemu_thread_self(&me);
-
-    if (!qemu_thread_equal(&me, &io_thread)) {
-        qemu_system_vmstop_request(reason);
-        /*
-         * FIXME: should not return to device code in case
-         * vm_stop() has been requested.
-         */
-        if (cpu_single_env) {
-            cpu_exit(cpu_single_env);
-            cpu_single_env->stop = 1;
-        }
-        return;
-    }
-    do_vm_stop(reason);
-}
-
-#endif
-
-static int qemu_cpu_exec(CPUState *env)
-{
-    int ret;
 #ifdef CONFIG_PROFILER
-    int64_t ti;
-#endif
-
-#ifdef CONFIG_PROFILER
-    ti = profile_getclock();
+    int64_t ti = profile_getclock();
 #endif
     if (use_icount) {
         int64_t count;
@@ -605,14 +203,6 @@
         env->icount_decr.u16.low = decr;
         env->icount_extra = count;
     }
-#ifdef CONFIG_TRACE
-    if (tbflush_requested) {
-        tbflush_requested = 0;
-        tb_flush(env);
-        return EXCP_INTERRUPT;
-    }
-#endif
-
 
     ret = cpu_exec(env);
 #ifdef CONFIG_PROFILER
@@ -636,7 +226,7 @@
     if (next_cpu == NULL)
         next_cpu = first_cpu;
     for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
-        CPUState *env = cur_cpu = next_cpu;
+        CPUOldState *env = cur_cpu = next_cpu;
 
         if (!vm_running)
             break;
@@ -653,3 +243,18 @@
     }
 }
 
+/* Return the virtual CPU time, based on the instruction counter.  */
+int64_t cpu_get_icount(void)
+{
+    int64_t icount;
+    CPUOldState *env = cpu_single_env;;
+
+    icount = qemu_icount;
+    if (env) {
+        if (!can_do_io(env)) {
+            fprintf(stderr, "Bad clock read\n");
+        }
+        icount -= (env->icount_decr.u16.low + env->icount_extra);
+    }
+    return qemu_icount_bias + (icount << icount_time_shift);
+}
diff --git a/cputlb.c b/cputlb.c
new file mode 100644
index 0000000..f175fa3
--- /dev/null
+++ b/cputlb.c
@@ -0,0 +1,305 @@
+/*
+ *  Common CPU TLB handling
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "exec/cputlb.h"
+
+#ifdef CONFIG_MEMCHECK
+#include "memcheck/memcheck_api.h"
+#endif
+
+/* statistics */
+int tlb_flush_count;
+
+static const CPUTLBEntry s_cputlb_empty_entry = {
+    .addr_read  = -1,
+    .addr_write = -1,
+    .addr_code  = -1,
+    .addend     = -1,
+};
+
+/* NOTE: if flush_global is true, also flush global entries (not
+   implemented yet) */
+void tlb_flush(CPUArchState *env, int flush_global)
+{
+    int i;
+
+#if defined(DEBUG_TLB)
+    printf("tlb_flush:\n");
+#endif
+    /* must reset current TB so that interrupts cannot modify the
+       links while we are modifying them */
+    env->current_tb = NULL;
+
+    for (i = 0; i < CPU_TLB_SIZE; i++) {
+        int mmu_idx;
+
+        for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
+            env->tlb_table[mmu_idx][i] = s_cputlb_empty_entry;
+        }
+    }
+
+    memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
+    tlb_flush_count++;
+}
+
+static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
+{
+    if (addr == (tlb_entry->addr_read &
+                 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
+        addr == (tlb_entry->addr_write &
+                 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
+        addr == (tlb_entry->addr_code &
+                 (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
+        *tlb_entry = s_cputlb_empty_entry;
+    }
+}
+
+void tlb_flush_page(CPUArchState *env, target_ulong addr)
+{
+    int i;
+    int mmu_idx;
+
+#if defined(DEBUG_TLB)
+    printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr);
+#endif
+    /* must reset current TB so that interrupts cannot modify the
+       links while we are modifying them */
+    env->current_tb = NULL;
+
+    addr &= TARGET_PAGE_MASK;
+    i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+    for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
+        tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr);
+    }
+
+    tb_flush_jmp_cache(env, addr);
+}
+
+/* update the TLBs so that writes to code in the virtual page 'addr'
+   can be detected */
+void tlb_protect_code(ram_addr_t ram_addr)
+{
+    cpu_physical_memory_reset_dirty(ram_addr,
+                                    ram_addr + TARGET_PAGE_SIZE,
+                                    CODE_DIRTY_FLAG);
+}
+
+/* update the TLB so that writes in physical page 'phys_addr' are no longer
+   tested for self modifying code */
+void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
+                             target_ulong vaddr)
+{
+    cpu_physical_memory_set_dirty_flags(ram_addr, CODE_DIRTY_FLAG);
+}
+
+void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
+                           uintptr_t start, uintptr_t length)
+{
+    uintptr_t addr;
+    if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
+        addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
+        if ((addr - start) < length) {
+            tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | TLB_NOTDIRTY;
+        }
+    }
+}
+
+static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr)
+{
+    if (tlb_entry->addr_write == (vaddr | TLB_NOTDIRTY))
+        tlb_entry->addr_write = vaddr;
+}
+
+/* update the TLB corresponding to virtual page vaddr
+   so that it is no longer dirty */
+void tlb_set_dirty(CPUArchState *env, target_ulong vaddr)
+{
+    int i;
+    int mmu_idx;
+
+    vaddr &= TARGET_PAGE_MASK;
+    i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+    for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++)
+        tlb_set_dirty1(&env->tlb_table[mmu_idx][i], vaddr);
+}
+
+/* add a new TLB entry. At most one entry for a given virtual address
+   is permitted. Return 0 if OK or 2 if the page could not be mapped
+   (can only happen in non SOFTMMU mode for I/O pages or pages
+   conflicting with the host address space). */
+int tlb_set_page_exec(CPUArchState *env, target_ulong vaddr,
+                      hwaddr paddr, int prot,
+                      int mmu_idx, int is_softmmu)
+{
+    PhysPageDesc *p;
+    unsigned long pd;
+    unsigned int index;
+    target_ulong address;
+    target_ulong code_address;
+    ptrdiff_t addend;
+    int ret;
+    CPUTLBEntry *te;
+    CPUWatchpoint *wp;
+    hwaddr iotlb;
+
+    p = phys_page_find(paddr >> TARGET_PAGE_BITS);
+    if (!p) {
+        pd = IO_MEM_UNASSIGNED;
+    } else {
+        pd = p->phys_offset;
+    }
+#if defined(DEBUG_TLB)
+    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",
+           vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);
+#endif
+
+    ret = 0;
+    address = vaddr;
+    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
+        /* IO memory case (romd handled later) */
+        address |= TLB_MMIO;
+    }
+    addend = (ptrdiff_t)qemu_get_ram_ptr(pd & TARGET_PAGE_MASK);
+    if ((pd & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
+        /* Normal RAM.  */
+        iotlb = pd & TARGET_PAGE_MASK;
+        if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM)
+            iotlb |= IO_MEM_NOTDIRTY;
+        else
+            iotlb |= IO_MEM_ROM;
+    } else {
+        /* IO handlers are currently passed a physical address.
+           It would be nice to pass an offset from the base address
+           of that region.  This would avoid having to special case RAM,
+           and avoid full address decoding in every device.
+           We can't use the high bits of pd for this because
+           IO_MEM_ROMD uses these as a ram address.  */
+        iotlb = (pd & ~TARGET_PAGE_MASK);
+        if (p) {
+            iotlb += p->region_offset;
+        } else {
+            iotlb += paddr;
+        }
+    }
+
+    code_address = address;
+    /* Make accesses to pages with watchpoints go via the
+       watchpoint trap routines.  */
+    QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+        if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) {
+            iotlb = io_mem_watch + paddr;
+            /* TODO: The memory case can be optimized by not trapping
+               reads of pages with a write breakpoint.  */
+            address |= TLB_MMIO;
+        }
+    }
+
+    index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+    env->iotlb[mmu_idx][index] = iotlb - vaddr;
+    te = &env->tlb_table[mmu_idx][index];
+    te->addend = addend - vaddr;
+    if (prot & PAGE_READ) {
+        te->addr_read = address;
+    } else {
+        te->addr_read = -1;
+    }
+
+    if (prot & PAGE_EXEC) {
+        te->addr_code = code_address;
+    } else {
+        te->addr_code = -1;
+    }
+    if (prot & PAGE_WRITE) {
+        if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
+            (pd & IO_MEM_ROMD)) {
+            /* Write access calls the I/O callback.  */
+            te->addr_write = address | TLB_MMIO;
+        } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
+                   !cpu_physical_memory_is_dirty(pd)) {
+            te->addr_write = address | TLB_NOTDIRTY;
+        } else {
+            te->addr_write = address;
+        }
+    } else {
+        te->addr_write = -1;
+    }
+
+#ifdef CONFIG_MEMCHECK
+    /*
+     * If we have memchecker running, we need to make sure that page, cached
+     * into TLB as the result of this operation will comply with our requirement
+     * to cause __ld/__stx_mmu being called for memory access on the pages
+     * containing memory blocks that require access violation checks.
+     *
+     * We need to check with memory checker if we should invalidate this page
+     * iff:
+     *  - Memchecking is enabled.
+     *  - Page that's been cached belongs to the user space.
+     *  - Request to cache this page didn't come from softmmu. We're covered
+     *    there, because after page was cached here we will invalidate it in
+     *    the __ld/__stx_mmu wrapper.
+     *  - Cached page belongs to RAM, not I/O area.
+     *  - Page is cached for read, or write access.
+     */
+    if (memcheck_instrument_mmu && mmu_idx == 1 && !is_softmmu &&
+        (pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
+        (prot & (PAGE_READ | PAGE_WRITE)) &&
+        memcheck_is_checked(vaddr & TARGET_PAGE_MASK, TARGET_PAGE_SIZE)) {
+        if (prot & PAGE_READ) {
+            te->addr_read ^= TARGET_PAGE_MASK;
+        }
+        if (prot & PAGE_WRITE) {
+            te->addr_write ^= TARGET_PAGE_MASK;
+        }
+    }
+#endif  // CONFIG_MEMCHECK
+
+    return ret;
+}
+
+int tlb_set_page(CPUArchState *env1, target_ulong vaddr,
+                 hwaddr paddr, int prot,
+                 int mmu_idx, int is_softmmu)
+{
+    if (prot & PAGE_READ)
+        prot |= PAGE_EXEC;
+    return tlb_set_page_exec(env1, vaddr, paddr, prot, mmu_idx, is_softmmu);
+}
+
+#define MMUSUFFIX _cmmu
+#define GETPC() NULL
+#define env cpu_single_env
+#define SOFTMMU_CODE_ACCESS
+
+#define SHIFT 0
+#include "exec/softmmu_template.h"
+
+#define SHIFT 1
+#include "exec/softmmu_template.h"
+
+#define SHIFT 2
+#include "exec/softmmu_template.h"
+
+#define SHIFT 3
+#include "exec/softmmu_template.h"
+
+#undef env
diff --git a/device_tree.c b/device_tree.c
deleted file mode 100644
index 2e941b8..0000000
--- a/device_tree.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Functions to help device tree manipulation using libfdt.
- * It also provides functions to read entries from device tree proc
- * interface.
- *
- * Copyright 2008 IBM Corporation.
- * Authors: Jerone Young <jyoung5@us.ibm.com>
- *          Hollis Blanchard <hollisb@us.ibm.com>
- *
- * This work is licensed under the GNU GPL license version 2 or later.
- *
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include "config.h"
-#include "qemu-common.h"
-#include "sysemu/device_tree.h"
-#include "hw/loader.h"
-
-#include <libfdt.h>
-
-void *load_device_tree(const char *filename_path, int *sizep)
-{
-    int dt_size;
-    int dt_file_load_size;
-    int ret;
-    void *fdt = NULL;
-
-    *sizep = 0;
-    dt_size = get_image_size(filename_path);
-    if (dt_size < 0) {
-        printf("Unable to get size of device tree file '%s'\n",
-            filename_path);
-        goto fail;
-    }
-
-    /* Expand to 2x size to give enough room for manipulation.  */
-    dt_size *= 2;
-    /* First allocate space in qemu for device tree */
-    fdt = g_malloc0(dt_size);
-
-    dt_file_load_size = load_image(filename_path, fdt);
-    if (dt_file_load_size < 0) {
-        printf("Unable to open device tree file '%s'\n",
-               filename_path);
-        goto fail;
-    }
-
-    ret = fdt_open_into(fdt, fdt, dt_size);
-    if (ret) {
-        printf("Unable to copy device tree in memory\n");
-        goto fail;
-    }
-
-    /* Check sanity of device tree */
-    if (fdt_check_header(fdt)) {
-        printf ("Device tree file loaded into memory is invalid: %s\n",
-            filename_path);
-        goto fail;
-    }
-    *sizep = dt_size;
-    return fdt;
-
-fail:
-    g_free(fdt);
-    return NULL;
-}
-
-int qemu_devtree_setprop(void *fdt, const char *node_path,
-                         const char *property, void *val_array, int size)
-{
-    int offset;
-
-    offset = fdt_path_offset(fdt, node_path);
-    if (offset < 0)
-        return offset;
-
-    return fdt_setprop(fdt, offset, property, val_array, size);
-}
-
-int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
-                              const char *property, uint32_t val)
-{
-    int offset;
-
-    offset = fdt_path_offset(fdt, node_path);
-    if (offset < 0)
-        return offset;
-
-    return fdt_setprop_cell(fdt, offset, property, val);
-}
-
-int qemu_devtree_setprop_string(void *fdt, const char *node_path,
-                                const char *property, const char *string)
-{
-    int offset;
-
-    offset = fdt_path_offset(fdt, node_path);
-    if (offset < 0)
-        return offset;
-
-    return fdt_setprop_string(fdt, offset, property, string);
-}
diff --git a/disas.c b/disas.c
index 93f11c6..eb87c39 100644
--- a/disas.c
+++ b/disas.c
@@ -5,9 +5,13 @@
 #include <errno.h>
 
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "disas/disas.h"
 
+typedef struct CPUDebug {
+    struct disassemble_info info;
+    CPUArchState *env;
+} CPUDebug;
+
 /* Filled in by elfload.c.  Simplistic, but will do for now. */
 struct syminfo *syminfos = NULL;
 
@@ -33,7 +37,9 @@
                     int length,
                     struct disassemble_info *info)
 {
-    cpu_memory_rw_debug(cpu_single_env, memaddr, myaddr, length, 0);
+    CPUDebug *s = container_of(info, CPUDebug, info);
+
+    cpu_memory_rw_debug(s->env, memaddr, myaddr, length, 0);
     return 0;
 }
 
@@ -52,7 +58,7 @@
 			   "Address 0x%" PRIx64 " is out of bounds.\n", memaddr);
 }
 
-/* This could be in a separate file, to save miniscule amounts of space
+/* This could be in a separate file, to save minuscule amounts of space
    in statically linked executables.  */
 
 /* Just print the address is hex.  This is included for completeness even
@@ -65,6 +71,22 @@
     (*info->fprintf_func) (info->stream, "0x%" PRIx64, addr);
 }
 
+/* Print address in hex, truncated to the width of a target virtual address. */
+static void
+generic_print_target_address(bfd_vma addr, struct disassemble_info *info)
+{
+    uint64_t mask = ~0ULL >> (64 - TARGET_VIRT_ADDR_SPACE_BITS);
+    generic_print_address(addr & mask, info);
+}
+
+/* Print address in hex, truncated to the width of a host virtual address. */
+static void
+generic_print_host_address(bfd_vma addr, struct disassemble_info *info)
+{
+    uint64_t mask = ~0ULL >> (64 - (sizeof(void *) * 8));
+    generic_print_address(addr & mask, info);
+}
+
 /* Just return the given address.  */
 
 int
@@ -136,62 +158,105 @@
 }
 #endif
 
+static int print_insn_objdump(bfd_vma pc, disassemble_info *info,
+                              const char *prefix)
+{
+    int i, n = info->buffer_length;
+    uint8_t *buf = g_malloc(n);
+
+    info->read_memory_func(pc, buf, n, info);
+
+    for (i = 0; i < n; ++i) {
+        if (i % 32 == 0) {
+            info->fprintf_func(info->stream, "\n%s: ", prefix);
+        }
+        info->fprintf_func(info->stream, "%02x", buf[i]);
+    }
+
+    g_free(buf);
+    return n;
+}
+
+static int print_insn_od_host(bfd_vma pc, disassemble_info *info)
+{
+    return print_insn_objdump(pc, info, "OBJD-H");
+}
+
+static int print_insn_od_target(bfd_vma pc, disassemble_info *info)
+{
+    return print_insn_objdump(pc, info, "OBJD-T");
+}
+
 /* Disassemble this for me please... (debugging). 'flags' has the following
    values:
-    i386 - nonzero means 16 bit code
-    arm  - nonzero means thumb code
+    i386 - 1 means 16 bit code, 2 means 64 bit code
+    arm  - bit 0 = thumb, bit 1 = reverse endian
     ppc  - nonzero means little endian
     other targets - unused
  */
-void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
+void target_disas(FILE *out, CPUArchState *env, target_ulong code,
+                  target_ulong size, int flags)
 {
     target_ulong pc;
     int count;
-    struct disassemble_info disasm_info;
-    int (*print_insn)(bfd_vma pc, disassemble_info *info);
+    CPUDebug s;
+    int (*print_insn)(bfd_vma pc, disassemble_info *info) = NULL;
 
-    INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf);
+    INIT_DISASSEMBLE_INFO(s.info, out, fprintf);
 
-    disasm_info.read_memory_func = target_read_memory;
-    disasm_info.buffer_vma = code;
-    disasm_info.buffer_length = size;
+    s.env = env;
+    s.info.read_memory_func = target_read_memory;
+    s.info.buffer_vma = code;
+    s.info.buffer_length = size;
+    s.info.print_address_func = generic_print_target_address;
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    disasm_info.endian = BFD_ENDIAN_BIG;
+    s.info.endian = BFD_ENDIAN_BIG;
 #else
-    disasm_info.endian = BFD_ENDIAN_LITTLE;
+    s.info.endian = BFD_ENDIAN_LITTLE;
 #endif
 #if defined(TARGET_I386)
-    if (flags == 2)
-        disasm_info.mach = bfd_mach_x86_64;
-    else if (flags == 1)
-        disasm_info.mach = bfd_mach_i386_i8086;
-    else
-        disasm_info.mach = bfd_mach_i386_i386;
+    if (flags == 2) {
+        s.info.mach = bfd_mach_x86_64;
+    } else if (flags == 1) {
+        s.info.mach = bfd_mach_i386_i8086;
+    } else {
+        s.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
+        s.info.endian = BFD_ENDIAN_LITTLE;
+#else
+        s.info.endian = BFD_ENDIAN_BIG;
+#endif
+    }
 #elif defined(TARGET_SPARC)
     print_insn = print_insn_sparc;
 #ifdef TARGET_SPARC64
-    disasm_info.mach = bfd_mach_sparc_v9b;
+    s.info.mach = bfd_mach_sparc_v9b;
 #endif
 #elif defined(TARGET_PPC)
-    if (flags >> 16)
-        disasm_info.endian = BFD_ENDIAN_LITTLE;
+    if (flags >> 16) {
+        s.info.endian = BFD_ENDIAN_LITTLE;
+    }
     if (flags & 0xFFFF) {
         /* If we have a precise definitions of the instructions set, use it */
-        disasm_info.mach = flags & 0xFFFF;
+        s.info.mach = flags & 0xFFFF;
     } else {
 #ifdef TARGET_PPC64
-        disasm_info.mach = bfd_mach_ppc64;
+        s.info.mach = bfd_mach_ppc64;
 #else
-        disasm_info.mach = bfd_mach_ppc;
+        s.info.mach = bfd_mach_ppc;
 #endif
     }
+    s.info.disassembler_options = (char *)"any";
     print_insn = print_insn_ppc;
 #elif defined(TARGET_M68K)
     print_insn = print_insn_m68k;
@@ -202,41 +267,46 @@
     print_insn = print_insn_little_mips;
 #endif
 #elif defined(TARGET_SH4)
-    disasm_info.mach = bfd_mach_sh4;
+    s.info.mach = bfd_mach_sh4;
     print_insn = print_insn_sh;
 #elif defined(TARGET_ALPHA)
-    disasm_info.mach = bfd_mach_alpha;
+    s.info.mach = bfd_mach_alpha_ev6;
     print_insn = print_insn_alpha;
 #elif defined(TARGET_CRIS)
     if (flags != 32) {
-        disasm_info.mach = bfd_mach_cris_v0_v10;
+        s.info.mach = bfd_mach_cris_v0_v10;
         print_insn = print_insn_crisv10;
     } else {
-    disasm_info.mach = bfd_mach_cris_v32;
-    print_insn = print_insn_crisv32;
+        s.info.mach = bfd_mach_cris_v32;
+        print_insn = print_insn_crisv32;
     }
 #elif defined(TARGET_S390X)
-    disasm_info.mach = bfd_mach_s390_64;
+    s.info.mach = bfd_mach_s390_64;
     print_insn = print_insn_s390;
 #elif defined(TARGET_MICROBLAZE)
-    disasm_info.mach = bfd_arch_microblaze;
+    s.info.mach = bfd_arch_microblaze;
     print_insn = print_insn_microblaze;
-#else
-    fprintf(out, "0x" TARGET_FMT_lx
-	    ": Asm output not supported on this arch\n", code);
-    return;
+#elif defined(TARGET_MOXIE)
+    s.info.mach = bfd_arch_moxie;
+    print_insn = print_insn_moxie;
+#elif defined(TARGET_LM32)
+    s.info.mach = bfd_mach_lm32;
+    print_insn = print_insn_lm32;
 #endif
+    if (print_insn == NULL) {
+        print_insn = print_insn_od_target;
+    }
 
     for (pc = code; size > 0; pc += count, size -= count) {
 	fprintf(out, "0x" TARGET_FMT_lx ":  ", pc);
-	count = print_insn(pc, &disasm_info);
+	count = print_insn(pc, &s.info);
 #if 0
         {
             int i;
             uint8_t b;
             fprintf(out, " {");
             for(i = 0; i < count; i++) {
-                target_read_memory(pc + i, &b, 1, &disasm_info);
+                target_read_memory(pc + i, &b, 1, &s.info);
                 fprintf(out, " %02x", b);
             }
             fprintf(out, " }");
@@ -258,37 +328,39 @@
 /* Disassemble this for me please... (debugging). */
 void disas(FILE *out, void *code, unsigned long size)
 {
-    unsigned long pc;
+    uintptr_t pc;
     int count;
-    struct disassemble_info disasm_info;
-    int (*print_insn)(bfd_vma pc, disassemble_info *info);
+    CPUDebug s;
+    int (*print_insn)(bfd_vma pc, disassemble_info *info) = NULL;
 
-    INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf);
+    INIT_DISASSEMBLE_INFO(s.info, out, fprintf);
+    s.info.print_address_func = generic_print_host_address;
 
-    disasm_info.buffer = code;
-    disasm_info.buffer_vma = (unsigned long)code;
-    disasm_info.buffer_length = size;
+    s.info.buffer = code;
+    s.info.buffer_vma = (uintptr_t)code;
+    s.info.buffer_length = size;
 
 #ifdef HOST_WORDS_BIGENDIAN
-    disasm_info.endian = BFD_ENDIAN_BIG;
+    s.info.endian = BFD_ENDIAN_BIG;
 #else
-    disasm_info.endian = BFD_ENDIAN_LITTLE;
+    s.info.endian = BFD_ENDIAN_LITTLE;
 #endif
-#if defined(__i386__)
-    disasm_info.mach = bfd_mach_i386_i386;
+#if defined(CONFIG_TCG_INTERPRETER)
+    print_insn = print_insn_tci;
+#elif defined(__i386__)
+    s.info.mach = bfd_mach_i386_i386;
     print_insn = print_insn_i386;
 #elif defined(__x86_64__)
-    disasm_info.mach = bfd_mach_x86_64;
+    s.info.mach = bfd_mach_x86_64;
     print_insn = print_insn_i386;
 #elif defined(_ARCH_PPC)
+    s.info.disassembler_options = (char *)"any";
     print_insn = print_insn_ppc;
 #elif defined(__alpha__)
     print_insn = print_insn_alpha;
 #elif defined(__sparc__)
     print_insn = print_insn_sparc;
-#if defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
-    disasm_info.mach = bfd_mach_sparc_v9b;
-#endif
+    s.info.mach = bfd_mach_sparc_v9b;
 #elif defined(__arm__)
     print_insn = print_insn_arm;
 #elif defined(__MIPSEB__)
@@ -303,14 +375,13 @@
     print_insn = print_insn_hppa;
 #elif defined(__ia64__)
     print_insn = print_insn_ia64;
-#else
-    fprintf(out, "0x%lx: Asm output not supported on this arch\n",
-	    (long) code);
-    return;
 #endif
-    for (pc = (unsigned long)code; size > 0; pc += count, size -= count) {
-	fprintf(out, "0x%08lx:  ", pc);
-	count = print_insn(pc, &disasm_info);
+    if (print_insn == NULL) {
+        print_insn = print_insn_od_host;
+    }
+    for (pc = (uintptr_t)code; size > 0; pc += count, size -= count) {
+        fprintf(out, "0x%08" PRIxPTR ":  ", pc);
+        count = print_insn(pc, &s.info);
 	fprintf(out, "\n");
 	if (count < 0)
 	    break;
@@ -338,16 +409,17 @@
 #include "monitor/monitor.h"
 
 static int monitor_disas_is_physical;
-static CPUState *monitor_disas_env;
 
 static int
 monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
                      struct disassemble_info *info)
 {
+    CPUDebug *s = container_of(info, CPUDebug, info);
+
     if (monitor_disas_is_physical) {
         cpu_physical_memory_read(memaddr, myaddr, length);
     } else {
-        cpu_memory_rw_debug(monitor_disas_env, memaddr,myaddr, length, 0);
+        cpu_memory_rw_debug(s->env, memaddr,myaddr, length, 0);
     }
     return 0;
 }
@@ -362,33 +434,35 @@
     return 0;
 }
 
-void monitor_disas(Monitor *mon, CPUState *env,
+void monitor_disas(Monitor *mon, CPUArchState *env,
                    target_ulong pc, int nb_insn, int is_physical, int flags)
 {
     int count, i;
-    struct disassemble_info disasm_info;
+    CPUDebug s;
     int (*print_insn)(bfd_vma pc, disassemble_info *info);
 
-    INIT_DISASSEMBLE_INFO(disasm_info, (FILE *)mon, monitor_fprintf);
+    INIT_DISASSEMBLE_INFO(s.info, (FILE *)mon, monitor_fprintf);
 
-    monitor_disas_env = env;
+    s.env = env;
     monitor_disas_is_physical = is_physical;
-    disasm_info.read_memory_func = monitor_read_memory;
+    s.info.read_memory_func = monitor_read_memory;
+    s.info.print_address_func = generic_print_target_address;
 
-    disasm_info.buffer_vma = pc;
+    s.info.buffer_vma = pc;
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    disasm_info.endian = BFD_ENDIAN_BIG;
+    s.info.endian = BFD_ENDIAN_BIG;
 #else
-    disasm_info.endian = BFD_ENDIAN_LITTLE;
+    s.info.endian = BFD_ENDIAN_LITTLE;
 #endif
 #if defined(TARGET_I386)
-    if (flags == 2)
-        disasm_info.mach = bfd_mach_x86_64;
-    else if (flags == 1)
-        disasm_info.mach = bfd_mach_i386_i8086;
-    else
-        disasm_info.mach = bfd_mach_i386_i386;
+    if (flags == 2) {
+        s.info.mach = bfd_mach_x86_64;
+    } else if (flags == 1) {
+        s.info.mach = bfd_mach_i386_i8086;
+    } else {
+        s.info.mach = bfd_mach_i386_i386;
+    }
     print_insn = print_insn_i386;
 #elif defined(TARGET_ARM)
     print_insn = print_insn_arm;
@@ -397,13 +471,13 @@
 #elif defined(TARGET_SPARC)
     print_insn = print_insn_sparc;
 #ifdef TARGET_SPARC64
-    disasm_info.mach = bfd_mach_sparc_v9b;
+    s.info.mach = bfd_mach_sparc_v9b;
 #endif
 #elif defined(TARGET_PPC)
 #ifdef TARGET_PPC64
-    disasm_info.mach = bfd_mach_ppc64;
+    s.info.mach = bfd_mach_ppc64;
 #else
-    disasm_info.mach = bfd_mach_ppc;
+    s.info.mach = bfd_mach_ppc;
 #endif
     print_insn = print_insn_ppc;
 #elif defined(TARGET_M68K)
@@ -415,11 +489,17 @@
     print_insn = print_insn_little_mips;
 #endif
 #elif defined(TARGET_SH4)
-    disasm_info.mach = bfd_mach_sh4;
+    s.info.mach = bfd_mach_sh4;
     print_insn = print_insn_sh;
 #elif defined(TARGET_S390X)
-    disasm_info.mach = bfd_mach_s390_64;
+    s.info.mach = bfd_mach_s390_64;
     print_insn = print_insn_s390;
+#elif defined(TARGET_MOXIE)
+    s.info.mach = bfd_arch_moxie;
+    print_insn = print_insn_moxie;
+#elif defined(TARGET_LM32)
+    s.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);
@@ -428,7 +508,7 @@
 
     for(i = 0; i < nb_insn; i++) {
 	monitor_printf(mon, "0x" TARGET_FMT_lx ":  ", pc);
-	count = print_insn(pc, &disasm_info);
+        count = print_insn(pc, &s.info);
 	monitor_printf(mon, "\n");
 	if (count < 0)
 	    break;
diff --git a/distrib/README b/distrib/README
index 22d276f..cd19d13 100644
--- a/distrib/README
+++ b/distrib/README
@@ -1,42 +1,2 @@
-This is source release of the Android emulator. simply run the "build-emulator.sh" script to
-generate a statically linked "emulator" binary in the current directory.
-
-you can also use the "--target=<path>" option to install the executable into a different location,
-
-At the moment, only Linux and Mac OS X are supported.
-
-This emulator is probably not usable without other support files provided by the Android project,
-like a specific kernel image, ramdisk, system and user disk images. Please go to the Android web
-site for more details.
-
-This emulator is licensed under the GNU General Public License (GPL) version 2, which can be
-found in the file "qemu/COPYING".
-
-it is based on QEMU 0.8.2 with many changes used to support the following features:
-
-  - additionnal hardware support for some Android reference boards.
-
-  - various OS-X related patches to make everything compile cleanly with GCC 4.1 and
-    beyond. this includes better support for the Mach-O binary format
-
-  - support for instruction-level profiling and data cache simulation. this allows the
-    emulator to generate "profile" files that can later be analyzed with external tools
-    to provide accurate information about what's happening in the system
-
-  - changes in the dynamic code generators, mainly to support concurrent generators in
-    a single binary (this allows us to use different generators for profiling and
-    non-profiling modes, and switch between them dynamically at runtime when needed)
-
-  - support for network throttling and latency simulation, used to better emulate the
-    network conditions of radio networks.
-
-  - a new graphical user interface capable of displaying and rotating "device skins"
-
-  - an optional (and disabled by default) "polling" runtime mode that doesn't use
-    SIGALRM signals to implement timers. this makes for much better timing accuracy
-    when using "old" emukated Linux kernels, at the cost of using 100% CPU, even when
-    the guest system is idle. This is now disabled since Linux 2.6.21 and beyond use
-    "dynamic ticks" that make this mode un-necessary for Android.
-
-
-it also uses a patched version of LibSDL-1.2.15.
+This directory contains the sources of various third-party libraries used
+by the Android emulator build. Plus a few helper scripts.
diff --git a/distrib/build-emulator.sh b/distrib/build-emulator.sh
deleted file mode 100755
index e8d1749..0000000
--- a/distrib/build-emulator.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-#
-#  this script is used to build a static version of the Android emulator
-#  from our distribution package.
-#
-cd $(dirname $0)
-CURDIR=$(pwd)
-
-show_help=
-TARGET=emulator
-for opt; do
-  optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
-  case "$opt" in
-  --help|-h|-\?) show_help=yes
-  ;;
-  --target=*) TARGET=$optarg
-  ;;
-  esac
-done
-
-if [ -n "$show_help" ] ; then
-    echo "usage: build-emulator [--target=FILEPATH]"
-    exit 1
-fi
-
-# directory where we'll place the temporary SDL binaries
-LOCAL=$CURDIR/local
-
-cd $CURDIR/qemu
-if ! (./android-rebuild.sh); then
-    echo "ERROR: could not build the emulator, please check the sources"
-fi
-
-cp objs/emulator $CURDIR/emulator
diff --git a/distrib/make-distrib.sh b/distrib/make-distrib.sh
deleted file mode 100755
index e05117f..0000000
--- a/distrib/make-distrib.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash
-#
-# this script is used to build a source distribution package for the Android emulator
-# the package includes:
-#  - the sources of our patched SDL library
-#  - the sources of our patched QEMU emulator
-#  - appropriate scripts to rebuild the emulator binary
-#
-
-# get absolute path of source directory tree
-CURDIR=`dirname $0`
-TOPDIR=`cd $CURDIR/.. && pwd`
-
-# create temporary directory
-TMPROOT=/tmp/android-package
-DATE=$(date +%Y%m%d)
-PACKAGE=android-emulator-$DATE
-TMPDIR=$TMPROOT/$PACKAGE
-if ! ( rm -rf $TMPROOT && mkdir -p $TMPDIR ) then
-    echo "could not create temporary directory $TMPDIR"
-    exit 3
-fi
-
-# clone the current source tree to $TMPDIR/qemu
-QEMUDIR=$TMPDIR/qemu
-echo "Copying sources to $QEMUDIR"
-cd $TMPDIR && git clone file://$TOPDIR $QEMUDIR && rm -rf $QEMUDIR/.git
-if [ $? != 0 ] ; then
-    echo "Could not clone sources"
-fi
-
-echo "copying control scripts"
-mv $QEMUDIR/distrib/build-emulator.sh $TMPDIR/build-emulator.sh
-mv $QEMUDIR/distrib/README $TMPDIR/README
-
-echo "packaging release into a tarball"
-cd $TMPROOT
-tar cjf $PACKAGE.tar.bz2 $PACKAGE
-
-echo "cleaning up"
-rm -rf $TMPDIR
-
-echo "please grab $TMPROOT/$PACKAGE.tar.bz2"
diff --git a/distrib/mini-glib/include/glib.h b/distrib/mini-glib/include/glib.h
index 214557b..cd9c65c 100644
--- a/distrib/mini-glib/include/glib.h
+++ b/distrib/mini-glib/include/glib.h
@@ -15,17 +15,76 @@
 #include <stdarg.h>
 #include <stddef.h>
 
+// Types
+
+typedef char gchar;
+typedef int gint;
+typedef unsigned int guint;
+typedef unsigned short gushort;
+typedef int gboolean;
+typedef void* gpointer;
+typedef const void* gconstpointer;
+
+typedef void (*GFunc)(gpointer data, gpointer user_data);
+
+typedef int (*GCompareFunc)(gconstpointer a,
+                            gconstpointer b);
+
+typedef int (*GCompareDataFunc)(gconstpointer a,
+                                gconstpointer b,
+                                gpointer user_data);
+
+typedef gboolean (*GEqualFunc)(gconstpointer a, gconstpointer b);
+
+typedef guint (*GHashFunc)(gconstpointer key);
+
+typedef void (*GHFunc)(gpointer key,
+                       gpointer value,
+                       gpointer user_data);
+
+typedef gboolean (*GHRFunc)(gpointer key,
+                            gpointer value,
+                            gpointer user_data);
+
+// Constants.
+
+#ifdef _WIN32
+#define G_DIR_SEPARATOR_S "\\"
+#else
+#define G_DIR_SEPARATOR_S  "/"
+#endif
+
+// Testing
+
+// TODO(digit): Turn assertions on.
+
+void g_critical(const char* fmt, ...);
+
+void g_panic(const char* fmt, ...) __attribute__((noreturn));
+
+#define g_assert(condition)  do { \
+    if (!(condition)) { \
+      g_panic("%s:%d: Assertion failure: %s\n", \
+              __FILE__, \
+              __LINE__, \
+              #condition); \
+      } \
+  } while (0)
+
+#define g_assert_not_reached()  \
+    g_panic("%s:%d: Assertion failure: NOT REACHED\n", __FILE__, __LINE__)
+
 // Heap allocation.
 void* g_malloc(size_t size);
 void* g_malloc0(size_t size);
 void* g_realloc(void* ptr, size_t size);
 void g_free(void* ptr);
 
-#define g_new(type, count)         ((type*) g_malloc(sizeof(*type) * (count))
-#define g_new0(type, count)        ((type*) g_malloc0(sizeof(*type) * (count))
+#define g_new(type, count)         ((type*) g_malloc(sizeof(type) * (count)))
+#define g_new0(type, count)        ((type*) g_malloc0(sizeof(type) * (count)))
 
 #define g_renew(type, mem, count)  \
-    ((type*) g_realloc((mem), sizeof(*type) * (count))
+    ((type*) g_realloc((mem), sizeof(type) * (count)))
 
 // Strings.
 int g_vasprintf(char** str, const char* fmt, va_list args);
@@ -34,4 +93,118 @@
 char* g_strdup_printf(const char* fmt, ...);
 char* g_strdup_vprintf(const char* fmt, va_list args);
 
+char** g_strsplit(const char* str, const char* sep, int max_tokens);
+void g_strfreev(char** strings);
+
+gboolean g_str_equal(const void* s1, const void* s2);
+guint g_str_hash(const void* str);
+
+// Atomic operations
+
+void g_atomic_int_inc(int volatile* atomic);
+
+gboolean g_atomic_int_dec_and_test(int volatile* atomic);
+
+// Single-linked lists
+
+typedef struct _GSList {
+  void* data;
+  struct _GSList* next;
+} GSList;
+
+void g_slist_free(GSList* list);
+GSList* g_slist_last(GSList* list);
+GSList* g_slist_find(GSList* list, gconstpointer data);
+GSList* g_slist_append(GSList* list, gpointer data);
+GSList* g_slist_prepend(GSList* list, gpointer data);
+GSList* g_slist_remove(GSList* list, gconstpointer data);
+void g_slist_foreach(GSList* list, GFunc func, gpointer user_data);
+GSList* g_slist_sort(GSList* list, GCompareFunc compare_func);
+
+// Hash tables
+
+typedef struct _GHashTable GHashTable;
+
+GHashTable* g_hash_table_new(GHashFunc hash_func,
+                             GEqualFunc key_equal_func);
+
+void g_hash_table_destroy(GHashTable* hash_table);
+
+void g_hash_table_insert(GHashTable* hash_table,
+                         void* key,
+                         void* value);
+
+void* g_hash_table_lookup(GHashTable* hash_table,
+                          const void* key);
+
+gboolean g_hash_table_remove(GHashTable* hash_table,
+                         const void* key);
+
+void g_hash_table_foreach(GHashTable* hash_table,
+                          GHFunc func,
+                          gpointer user_data);
+
+gpointer g_hash_table_find(GHashTable* hash_table,
+                           GHRFunc predicate,
+                           gpointer user_data);
+
+guint g_hash_table_size(GHashTable* hash_table);
+
+GHashTable* g_hash_table_ref(GHashTable* hash_table);
+
+void g_hash_table_unref(GHashTable* hash_table);
+
+
+// Queues
+
+typedef struct _GQueueNode GQueueNode;
+
+typedef struct _GQueue {
+  GQueueNode* head;
+  GQueueNode* tail;
+  guint length;
+} GQueue;
+
+GQueue* g_queue_new(void);
+
+void g_queue_free(GQueue* queue);
+
+void g_queue_push_tail(GQueue* queue, void* data);
+
+void* g_queue_peek_head(GQueue* queue);
+
+void* g_queue_pop_head(GQueue* queue);
+
+gboolean g_queue_is_empty(GQueue* queue);
+
+#ifdef _WIN32
+char* g_win32_error_message(int error);
+#endif
+
+// GSource etc...
+
+// Opaque data type.
+typedef struct GSource GSource;
+
+typedef gboolean (*GSourceFunc)(gpointer user_data);
+
+typedef struct {
+  gboolean (*prepare)(GSource* source, gint* timeout);
+  gboolean (*check)(GSource* source);
+  gboolean (*dispatch)(GSource* source,
+                       GSourceFunc callback,
+                       gpointer user_data);
+  void (*finalize)(GSource* source);
+} GSourceFuncs;
+
+typedef struct GPollFD {
+#if defined(_WIN32) && defined(__LP64__)
+  int64_t fd;
+#else
+  int fd;
+#endif
+  gushort events;
+  gushort revents;
+} GPollFD;
+
 #endif  // GLIB_H
diff --git a/distrib/mini-glib/sources.make b/distrib/mini-glib/sources.make
index d3f4488..d442f52 100644
--- a/distrib/mini-glib/sources.make
+++ b/distrib/mini-glib/sources.make
@@ -1,4 +1,7 @@
 # Included from top-level Makefile.common
 
 GLIB_INCLUDE_DIR := $(LOCAL_PATH)/$(GLIB_DIR)/include
-GLIB_SOURCES := $(GLIB_DIR)/src/glib-mini.c
+
+GLIB_SOURCES := \
+    $(GLIB_DIR)/src/glib-mini.c \
+    $(GLIB_DIR)/src/glib-mini-win32.c
diff --git a/distrib/mini-glib/src/glib-mini-win32.c b/distrib/mini-glib/src/glib-mini-win32.c
new file mode 100644
index 0000000..73530e1
--- /dev/null
+++ b/distrib/mini-glib/src/glib-mini-win32.c
@@ -0,0 +1,92 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// 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.
+
+#ifdef _WIN32
+
+#include <glib.h>
+
+#include <assert.h>
+#include <wchar.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+// Atomic operations
+
+void g_atomic_int_inc(int volatile* atomic) {
+  assert(sizeof(LONG) == sizeof(int));
+  InterlockedIncrement((LONG volatile*)atomic);
+}
+
+gboolean g_atomic_int_dec_and_test(int volatile* atomic) {
+  assert(sizeof(LONG) == sizeof(int));
+  return !InterlockedIncrement((LONG volatile*)atomic);
+}
+
+// Win32 error messages.
+
+static char*
+utf16_to_utf8(const wchar_t* wstring, int wstring_len)
+{
+  int utf8_len = WideCharToMultiByte(CP_UTF8,          // CodePage
+                                     0,                // dwFlags
+                                     (LPWSTR) wstring, // lpWideCharStr
+                                     wstring_len,      // cchWideChar
+                                     NULL,             // lpMultiByteStr
+                                     0,                // cbMultiByte
+                                     NULL,             // lpDefaultChar
+                                     NULL);            // lpUsedDefaultChar
+  if (utf8_len == 0)
+    return g_strdup("");
+
+  char* result = g_malloc(utf8_len + 1);
+
+  WideCharToMultiByte(CP_UTF8, 0, (LPWSTR) wstring, wstring_len,
+                      result, utf8_len, NULL, NULL);
+  result[utf8_len] = '\0';
+  return result;
+}
+
+char *
+g_win32_error_message (int error)
+{
+  LPWSTR msg = NULL;
+  int nchars;
+  char* result;
+
+  // Work around for compiler warning, due to brain-dead API.
+  union {
+    LPWSTR* address;
+    LPWSTR  value;
+  } msg_param;
+  msg_param.address = &msg;
+
+  FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
+                 |FORMAT_MESSAGE_IGNORE_INSERTS
+                 |FORMAT_MESSAGE_FROM_SYSTEM,
+                 NULL, error, 0,
+                 msg_param.value,
+                 0, NULL);
+  if (!msg)
+    return g_strdup("");
+
+  // Get rid of trailing \r\n if any.
+  nchars = wcslen (msg);
+  if (nchars > 2 && msg[nchars-1] == '\n' && msg[nchars-2] == '\r')
+    msg[nchars-2] = '\0';
+
+  result = utf16_to_utf8 (msg, nchars);
+
+  LocalFree (msg);
+
+  return result;
+}
+
+#endif  // _WIN32
diff --git a/distrib/mini-glib/src/glib-mini.c b/distrib/mini-glib/src/glib-mini.c
index d3528c5..9a954be 100644
--- a/distrib/mini-glib/src/glib-mini.c
+++ b/distrib/mini-glib/src/glib-mini.c
@@ -18,16 +18,23 @@
 #include <string.h>
 
 // Print a panic message then exit the program immediately.
-static  __attribute__((noreturn)) void g_panic(const char* fmt, ...){
+void g_critical(const char* fmt, ...) {
   va_list args;
-  fprintf(stderr, "MiniGLib:PANIC: ");
+  fprintf(stderr, "CRITICAL: ");
+  va_start(args, fmt);
+  vfprintf(stderr, fmt, args);
+  va_end(args);
+}
+
+void g_panic(const char* fmt, ...) {
+  va_list args;
+  fprintf(stderr, "PANIC: ");
   va_start(args, fmt);
   vfprintf(stderr, fmt, args);
   va_end(args);
   exit(1);
 }
 
-
 // Heap allocation.
 
 void* g_malloc(size_t size) {
@@ -155,3 +162,578 @@
   return len;
 #endif
 }
+
+char** g_strsplit(const char* string, const char* delim, int max_tokens) {
+  // Sanity checks.
+  if (!string || !delim || !*delim)
+    return NULL;
+
+  if (max_tokens < 1)
+    max_tokens = INT_MAX;
+
+  // Create empty list of results.
+  GSList* string_list = NULL;
+  guint n = 0;
+
+  if (*string) {
+    // Input list is not empty, so try to split it.
+    const char* remainder = string;
+    const char* s = strstr(remainder, delim);
+    if (s) {
+      size_t delim_len = strlen(delim);
+      while (--max_tokens && s) {
+        size_t len = s - remainder;
+        string_list = g_slist_prepend(string_list, g_strndup(remainder, len));
+        n++;
+        remainder = s + delim_len;
+        s = strstr(remainder, delim);
+      }
+    }
+    n++;
+    string_list = g_slist_prepend(string_list, g_strdup(remainder));
+  }
+
+  // Convert list into NULL-terminated vector.
+  char** result = g_new(char*, n + 1);
+  result[n--] = NULL;
+  GSList* slist = string_list;
+  while (slist) {
+    result[n--] = slist->data;
+    slist = slist->next;
+  }
+  g_slist_free(string_list);
+
+  return result;
+}
+
+void g_strfreev(char** strings) {
+  guint n;
+  for (n = 0; strings[n]; ++n) {
+    g_free(strings[n]);
+  }
+  g_free(strings);
+}
+
+gboolean g_str_equal(const void* v1, const void* v2) {
+  return !strcmp((const char*)v1, (const char*)v2);
+}
+
+guint g_str_hash(const void* str) {
+  const signed char* p = str;
+  guint hash = 5381U;
+
+  for (; *p; ++p)
+    hash = (hash << 5) + hash + (guint)*p;
+
+  return hash;
+}
+
+// Single-linked list
+
+static GSList* _g_slist_alloc(void) {
+  return (GSList*) g_malloc(sizeof(GSList));
+}
+
+void g_slist_free(GSList* list) {
+  while (list) {
+    GSList* next = list->next;
+    g_free(list);
+    list = next;
+  }
+}
+
+GSList* g_slist_last(GSList* list) {
+  while (list && list->next)
+    list = list->next;
+  return list;
+}
+
+GSList* g_slist_find(GSList* list, const void* data) {
+  while (list) {
+    if (list->data == data)
+      break;
+    list = list->next;
+  }
+  return list;
+}
+
+GSList* g_slist_append(GSList* list, void* data) {
+  GSList* new_list = _g_slist_alloc();
+  new_list->data = data;
+  new_list->next = NULL;
+
+  if (!list)
+    return new_list;
+
+  GSList* last = g_slist_last(list);
+  last->next = new_list;
+  return list;
+}
+
+GSList* g_slist_prepend(GSList* list, void* data) {
+  GSList* new_list = _g_slist_alloc();
+  new_list->data = data;
+  new_list->next = list;
+  return new_list;
+}
+
+GSList* g_slist_remove(GSList* list, const void* data) {
+  GSList** pnode = &list;
+  for (;;) {
+    GSList* node = *pnode;
+    if (!node)
+      break;
+    if (node->data == data) {
+      *pnode = node->next;
+      g_slist_free(node);
+      break;
+    }
+    pnode = &node->next;
+  }
+  return list;
+}
+
+void g_slist_foreach(GSList* list, GFunc func, void* user_data) {
+  while (list) {
+    GSList* next = list->next;
+    (*func)(list->data, user_data);
+    list = next;
+  }
+}
+
+// 
+static GSList* g_slist_sort_merge(GSList* l1,
+                                  GSList* l2,
+                                  GFunc compare_func,
+                                  void* user_data) {
+  GSList* list = NULL;
+  GSList** tail = &list;
+
+  while (l1 && l2) {
+    int cmp = ((GCompareDataFunc) compare_func)(l1->data, l2->data, user_data);
+    if (cmp <= 0) {
+      *tail = l1;
+      tail = &l1->next;
+      l1 = l1->next;
+    } else {
+      *tail = l2;
+      tail = &l2->next;
+      l2 = l2->next;
+    }
+  }
+  *tail = l1 ? l1 : l2;
+
+  return list;
+}
+
+static GSList* g_slist_sort_real(GSList* list,
+                                 GFunc compare_func,
+                                 void* user_data) {
+
+  if (!list)
+    return NULL;
+  if (!list->next)
+    return list;
+
+  // Split list into two halves.
+  GSList* l1 = list;
+  GSList* l2 = list->next;
+
+  while (l2->next && l2->next->next) {
+    l2 = l2->next->next;
+    l1 = l1->next;
+  }
+  l2 = l1->next;
+  l1->next = NULL;
+
+  return g_slist_sort_merge(
+      g_slist_sort_real(list, compare_func, user_data),
+      g_slist_sort_real(l2, compare_func, user_data),
+      compare_func,
+      user_data);
+}
+
+GSList* g_slist_sort(GSList* list, GCompareFunc compare_func) {
+  return g_slist_sort_real(list, (GFunc) compare_func, NULL);
+}
+
+// Atomic operations
+
+#if !_WIN32
+// Note: Windows implementation in glib-mini-win32.c
+
+void g_atomic_int_inc(int volatile* atomic) {
+  __sync_fetch_and_add(atomic, 1);
+}
+
+gboolean g_atomic_int_dec_and_test(int volatile* atomic) {
+  return __sync_fetch_and_add(atomic, -1) == 1;
+}
+#endif  // !_WIN32
+
+// Hash Tables
+
+// This is a rather vanilla implementation, slightly simpler
+// than the GLib one, since QEMU doesn't require the full features:
+//
+// - Uses a single dynamic array of (key,value,hash) tuples.
+// - Array capacity is always 2^N
+// - No use of modulo primes for simplicity, we don't expect
+//   QEMU/QAPI to degenerate here.
+// - Dumb container only: doesn't own and free keys and values.
+// - No optimization for sets (i.e. when key == value for each entry).
+// - No iterators.
+//
+typedef struct {
+  gpointer key;
+  gpointer value;
+  guint    hash;
+} GHashEntry;
+
+#define HASH_UNUSED    0   // Must be 0, see _remove_all() below.
+#define HASH_TOMBSTONE 1
+#define HASH_IS_REAL(h)  ((h) >= 2)
+
+#define HASH_MIN_SHIFT  3
+#define HASH_MIN_CAPACITY  (1 << HASH_MIN_SHIFT)
+
+struct _GHashTable {
+  int ref_count;
+  int num_items;
+  int num_used;  // count of items + tombstones
+  int shift;
+  int capacity;
+  GHashEntry* entries;
+  GHashFunc hash_func;
+  GEqualFunc key_equal_func;
+};
+
+// Compute the hash value of a given key.
+static inline size_t
+_g_hash_table_hash(GHashTable* table, gconstpointer key) {
+  size_t hash = table->hash_func(key);
+  return HASH_IS_REAL(hash) ? hash : 2;
+}
+
+
+GHashTable* g_hash_table_new(GHashFunc hash_func,
+                             GEqualFunc key_equal_func) {
+  GHashTable* hash_table = g_new0(GHashTable, 1);
+
+  hash_table->ref_count = 1;
+  hash_table->num_items = 0;
+  hash_table->capacity = HASH_MIN_CAPACITY;
+  hash_table->entries = g_new0(GHashEntry, hash_table->capacity);
+  hash_table->hash_func = hash_func;
+  hash_table->key_equal_func = key_equal_func;
+
+  return hash_table;
+}
+
+
+static void _g_hash_table_remove_all(GHashTable* hash_table) {
+  // NOTE: This uses the fact that HASH_UNUSED is 0!
+  hash_table->num_items = 0;
+  memset(hash_table->entries,
+         0,
+         sizeof(hash_table->entries[0]) * hash_table->capacity);
+}
+
+
+GHashTable* g_hash_table_ref(GHashTable* hash_table) {
+  if (!hash_table)
+    return NULL;
+
+  g_atomic_int_inc(&hash_table->ref_count);
+  return hash_table;
+}
+
+
+void g_hash_table_unref(GHashTable* hash_table) {
+  if (!hash_table)
+    return;
+
+  if (!g_atomic_int_dec_and_test(&hash_table->ref_count))
+    return;
+
+  _g_hash_table_remove_all(hash_table);
+
+  g_free(hash_table->entries);
+  hash_table->capacity = 0;
+  hash_table->entries = NULL;
+
+  g_free(hash_table);
+}
+
+
+void g_hash_table_destroy(GHashTable* hash_table) {
+  if (!hash_table)
+    return;
+
+  _g_hash_table_remove_all(hash_table);
+  g_hash_table_unref(hash_table);
+}
+
+
+// Probe the hash table for |key|. If it is in the table, return the index
+// to the corresponding entry. Otherwise, return the index of an unused
+// or tombstone entry. Also sets |*key_hash| to the key hash value on
+// return.
+static guint _g_hash_table_lookup_index(GHashTable* hash_table,
+                                        gconstpointer key,
+                                        guint* key_hash) {
+  guint hash = _g_hash_table_hash(hash_table, key);
+  *key_hash = hash;
+
+  guint probe_mask = (hash_table->capacity - 1);
+  gint tombstone = -1;
+  guint probe_index = hash & probe_mask;
+  guint step = 0;
+
+  GHashEntry* probe = &hash_table->entries[probe_index];
+  while (probe->hash != HASH_UNUSED) {
+    if (probe->hash == hash) {
+      if (hash_table->key_equal_func) {
+        if (hash_table->key_equal_func(probe->key, key))
+          return probe_index;
+      } else if (probe->key == key) {
+        return probe_index;
+      }
+    } else if (probe->hash == HASH_TOMBSTONE && tombstone < 0) {
+      tombstone = (int)probe_index;
+    }
+
+    step++;
+    probe_index = (probe_index + step) & probe_mask;
+    probe = &hash_table->entries[probe_index];
+  }
+
+  if (tombstone >= 0)
+    return (guint)tombstone;
+
+  return probe_index;
+}
+
+
+void* g_hash_table_lookup(GHashTable* hash_table,
+                          const void* key) {
+  guint key_hash = HASH_UNUSED;
+  guint probe_index = _g_hash_table_lookup_index(hash_table, key, &key_hash);
+  GHashEntry* entry = &hash_table->entries[probe_index];
+
+  return HASH_IS_REAL(entry->hash) ? entry->value : NULL;
+}
+
+
+// Remove key/value pair at index position |i|.
+static void _g_hash_table_remove_index(GHashTable* hash_table,
+                                       int i) {
+  GHashEntry* entry = &hash_table->entries[i];
+  entry->hash = HASH_TOMBSTONE;
+  entry->key = NULL;
+  entry->value = NULL;
+}
+
+
+gboolean g_hash_table_remove(GHashTable* hash_table,
+                             const void* key) {
+  guint key_hash = HASH_UNUSED;
+  guint probe_index = _g_hash_table_lookup_index(hash_table, key, &key_hash);
+  GHashEntry* entry = &hash_table->entries[probe_index];
+  if (!HASH_IS_REAL(entry->hash))
+    return 0;
+
+  _g_hash_table_remove_index(hash_table, probe_index);
+  hash_table->num_items--;
+  return 1;
+}
+
+// Resize the hash table, this also gets rid of all tombstones.
+static void _g_hash_table_resize(GHashTable* hash_table) {
+  guint old_capacity = hash_table->capacity;
+
+  // Compute new shift from new size
+  guint new_size = hash_table->num_items * 2;
+  guint new_capacity = HASH_MIN_CAPACITY;
+  while (new_capacity < new_size)
+    new_capacity <<= 1;
+
+  GHashEntry* new_entries = g_new0(GHashEntry, new_capacity);
+  guint n;
+  for (n = 0; n < old_capacity; ++n) {
+    GHashEntry* old_entry = &hash_table->entries[n];
+    guint old_hash = old_entry->hash;
+
+    if (!HASH_IS_REAL(old_hash))
+      continue;
+
+    guint probe_mask = (new_capacity - 1);
+    guint probe_n = old_hash & probe_mask;
+    GHashEntry* probe = &new_entries[probe_n];
+    guint step = 0;
+    while (probe->hash != HASH_UNUSED) {
+      step++;
+      probe_n = (probe_n + step) & probe_mask;
+      probe = &new_entries[probe_n];
+    }
+    probe[0] = old_entry[0];
+  }
+
+  g_free(hash_table->entries);
+  hash_table->entries = new_entries;
+  hash_table->capacity = new_capacity;
+  hash_table->num_used = hash_table->num_items;
+}
+
+// Resize the hash table if needed.
+static void _g_hash_table_maybe_resize(GHashTable* hash_table) {
+  guint used = hash_table->num_used;
+  guint count = hash_table->num_items;
+  guint capacity = hash_table->capacity;
+  if ((capacity > count * 4 && capacity > HASH_MIN_CAPACITY) ||
+      capacity < used + (used / 16)) {
+    _g_hash_table_resize(hash_table);
+  }
+}
+
+static void _g_hash_table_insert_index(GHashTable* hash_table,
+                                       guint key_index,
+                                       guint new_key_hash,
+                                       gpointer new_key,
+                                       gpointer new_value) {
+  GHashEntry* entry = &hash_table->entries[key_index];
+  guint old_hash = entry->hash;
+
+  entry->key = new_key;
+  entry->value = new_value;
+  entry->hash = new_key_hash;
+
+  if (HASH_IS_REAL(old_hash)) {
+    // Simple replacement, exit immediately.
+    return;
+  }
+
+  hash_table->num_items++;
+  if (old_hash == HASH_TOMBSTONE) {
+    // No need to resize when replacing a tombstone.
+    return;
+  }
+
+  hash_table->num_used++;
+  _g_hash_table_maybe_resize(hash_table);
+}
+
+void g_hash_table_insert(GHashTable* hash_table,
+                         void* key,
+                         void* value) {
+  guint key_hash;
+  guint key_index =
+      _g_hash_table_lookup_index(hash_table, key, &key_hash);
+
+  _g_hash_table_insert_index(hash_table, key_index, key_hash, key, value);
+}
+
+
+void g_hash_table_foreach(GHashTable* hash_table,
+                          GHFunc func,
+                          gpointer user_data) {
+  guint n;
+  for (n = 0; n < hash_table->capacity; ++n) {
+    GHashEntry* entry = &hash_table->entries[n];
+    if (HASH_IS_REAL(entry->hash))
+      (*func)(entry->key, entry->value, user_data);
+  }
+}
+
+
+gpointer g_hash_table_find(GHashTable* hash_table,
+                           GHRFunc predicate,
+                           gpointer user_data) {
+  guint n;
+  for (n = 0; n < hash_table->capacity; ++n) {
+    GHashEntry* entry = &hash_table->entries[n];
+    if (HASH_IS_REAL(entry->hash) &&
+        (*predicate)(entry->key, entry->value, user_data)) {
+      return entry->value;
+    }
+  }
+  return NULL;
+}
+
+
+guint g_hash_table_size(GHashTable* hash_table) {
+  return hash_table->num_items;
+}
+
+// Queues
+
+struct _GQueueNode {
+  void* data;
+  GQueueNode* next;
+  GQueueNode* prev;
+};
+
+static inline GQueueNode* _g_queue_node_alloc(void) {
+  return g_new0(GQueueNode, 1);
+}
+
+static void inline _g_queue_node_free(GQueueNode* node) {
+  g_free(node);
+}
+
+GQueue* g_queue_new(void) {
+  GQueue* queue = g_new0(GQueue, 1);
+  return queue;
+}
+
+void g_queue_free(GQueue* queue) {
+  GQueueNode* node = queue->head;
+  while (node) {
+    GQueueNode* next = node->next;
+    _g_queue_node_free(node);
+    node = next;
+  }
+  queue->head = queue->tail = NULL;
+  queue->length = 0;
+  g_free(queue);
+}
+
+gboolean g_queue_is_empty(GQueue* queue) {
+  return queue->head == NULL;
+}
+
+void g_queue_push_tail(GQueue* queue, void* data) {
+  GQueueNode* node = _g_queue_node_alloc();
+  node->data = data;
+  node->next = NULL;
+  node->prev = queue->tail;
+  queue->tail = node;
+  queue->length++;
+}
+
+void* g_queue_peek_head(GQueue* queue) {
+  return (queue->head) ? queue->head->data : NULL;
+}
+
+void* g_queue_peek_tail(GQueue* queue) {
+  return (queue->tail) ? queue->tail->data : NULL;
+}
+
+void* g_queue_pop_head(GQueue* queue) {
+  GQueueNode* head = queue->head;
+  if (!head)
+    return NULL;
+
+  void* result = head->data;
+
+  if (head->next) {
+    queue->head = head->next;
+    head->next->prev = NULL;
+  } else {
+    queue->head = NULL;
+    queue->tail = NULL;
+  }
+  queue->length--;
+
+  return result;
+}
diff --git a/docs/ANDROID-TRACING.TXT b/docs/ANDROID-TRACING.TXT
deleted file mode 100644
index 5546e7b..0000000
--- a/docs/ANDROID-TRACING.TXT
+++ /dev/null
@@ -1,66 +0,0 @@
-This document details how the Android-specific -trace <name> instruction works.
-
-hw/android/goldfish/trace.c:
-
-- virtual hardware i/o memory used by the goldfish kernel to send event information
-  to the emulator (e.g. context switches, forks, execs, etc...). Used by both -trace
-  and -memcheck implementations.
-
-trace.c/trace.h:
-
-- support functions for the runtime tracing facility. E.g. record static/dynamic
-  blocks, compute instruction sizes, etc..
-
-trace_common.h:
-
-- a header included by "trace.h" but also by the sources of the trace file processor
-  tool (sdk/emulator/qtools). Defines common data structures and types only.
-
-target-arm/translate.c:
-
-- each new translated basic block is recorded by:
-
-    1. calling trace_bb_start()
-    2. for each instruction in the block, calling trace_bb_insn()
-    3. calling trace_bb_end() at the end of the basic block.
-
-  this is done at "translation time".
-
-- each basic block is translated into a "tb" of x86 machine code that
-  will have, at its start, a call to a helper function like:
-
-     trace_bb_helper(bb_num, tb)
-
-  where 'bb_num' is the unique 64-bit ID of the original basic block.
-
-  -> at "execution time", we record which BB are executed.
-
-- we record context switches and other events from goldfish_trace.c through
-  functions like trace_switch(), trace_fork(), trace_exception(), etc...
-  (see trace.c, some of these miss a declaration in trace.h)
-
-- see genTraceTicks(), genTraceBB()
-
-- the number of virtual CPU cycles / instruction is returned by get_insn_ticks_arm()
-  (implemented in trace.c). This does not account for dynamic data interlocks or
-  variable cycles due to operand sizes (e.g. multiplications instructions).
-
-
-target-arm/helpers.h:
-
-- contains a list of helper functions that are going to be called by x86 machine code
-  at runtime. see #ifdef CONFIG_TRACE .. #endif
-
-target-arm/helpers.c:
-
-- implementation of the helper functions. see #ifdef CONFIG_TRACE .. #endif at the end
-
-- helper traceTicks(ticks): used to record that we executed 'ticks' simulated ARM CPU
-  cycles. This just increments a global uint64_t counter.
-
-- helper traceInsn(): used to record that we executed properly a single instruction.
-  this allows to properly recover/profile when a basic block is exited by an exceptional
-  condition (e.g. a signal, a page fault, etc...), instead of reaching its end.
-
-- helper_traceBB32/traceBB64: used to record that we entered a given basic block at
-  runtime. Simply calls trace_bb_helper()
diff --git a/docs/BUILDING.TXT b/docs/BUILDING.TXT
new file mode 100644
index 0000000..8ea9f89
--- /dev/null
+++ b/docs/BUILDING.TXT
@@ -0,0 +1,120 @@
+Rebuilding the Android emulator from sources
+============================================
+
+I. Getting the sources:
+-----------------------
+
+At the moment, you'll need a full AOSP source checkout to rebuild the
+emulator from sources. See the instructions at http://source.android.com on
+how to download the platform sources.
+
+The following directories will be relevant:
+
+  $AOSP/external/qemu        -> The emulator itself.
+  $AOSP/sdk/emulator/opengl  -> Host GPU emulation libraries.
+
+  $AOSP/prebuilts/tools/gcc-sdk           -> host toolchains for SDK tools.
+  $AOSP/prebuilts/gcc/linux-x86/host/
+  $AOSP/prebuilts/gcc/darwin-x86/host/
+
+
+I. Building:
+------------
+
+You can only build the emulator on Linux or Darwin. Windows binaries are always
+generated on Linux, and actually run under Wine (you will need to install
+mingw32 and wine packages from your distribution to build and run them).
+
+1) Generate the host GPU emulation libraries:
+
+  cd $AOSP
+  . build/envsetup.sh
+  lunch sdk-eng
+  make libOpenglRender \
+       libEGL_translator \
+       libGLES_CM_translator \
+       libGLES_V2_translator
+
+on Linux and Darwin, also generate the 64-bit host libraries:
+
+  make lib64OpenglRender \
+       lib64EGL_translator \
+       lib64GLES_CM_translator \
+       lib64GLES_V2_translator
+
+Building 64-bit host binaries is not supported on Windows yet.
+
+
+2) Generate emulator binaries:
+
+  # If you haven't done it yet in 1)
+  cd $AOSP
+  . build/envsetup.sh
+  lunch sdk-eng
+  # then
+  cd external/qemu
+  mm
+
+The emulator binaries are placed under $AOSP/host/<system>/bin which is
+already in your path. If you have a local SDK installation, you can start
+an existing AVD with:
+
+  export ANDROID_SDK_ROOT=/path/to/sdk
+  emulator -avd <name>  [other options...]
+
+
+3) Optional: build system image:
+
+You can also use the emulator to run an SDK system image build from your
+AOSP checkout:
+
+     lunch sdk-eng
+     make
+     emulator
+
+Use sdk_x86-eng for Android/x86 system images, and sdk_mips-eng for MIPS ones.
+
+
+4) Optional: standalone emulator builds:
+
+After generating the GPU libraries as in 1), you have the option to use the
+standalone Android build system to generate the emulator binaries. This is
+convenient if you hack a lot on the emulator sources, because it's faster and
+gives your more options:
+
+    cd $AOSP/external/qemu
+    ./android-rebuild.sh
+
+Use --help option when calling android-rebuild.sh for more information.
+Note that 'android-rebuild.sh' is a wrapper script that calls
+'android-configure.sh' and later invokes 'make'.
+
+The generated binaries are placed under external/qemu/objs which is _not_
+in your PATH, but can be invoked directly, e.g.:
+
+    ./android-rebuild.sh
+    objs/emulator -avd <name>
+
+    IMPORTANT: At the moment, the build will fail if you haven't
+    generated GPU emulation libraries with the platform build.
+
+In all cases, several binaries will be generated:
+
+    emulator         -> 32-bit launcher program.
+    emulator-<cpu>   -> 32-bit emulator for Android <cpu> images.
+    emulator64-<cpu> -> 64-bit emulator for Android <cpu> images.
+
+With <cpu> being one of the CPU architectures supported by the
+Android emulator (e.g. 'arm', 'x86' or 'mips').
+
+The 'emulator' executable is a very small program used to probe
+the host system and the AVD you want to launch, in order to
+invoke the appropriate 'real' emulator program. It also adjusts
+library search paths to ensure that the emulator can load the
+GPU emulation libraries from the right location.
+
+Note that there are no emulator64-<cpu> executables generated on
+Windows at the moment, due to issues with the mingw32-w64 cross-toolchains.
+
+Define ANDROID_SDK_ROOT in your environment to point to your SDK installation
+and be able to start AVDs with your freshly built emulator.
diff --git a/docs/DEVELOPMENT.TXT b/docs/DEVELOPMENT.TXT
new file mode 100644
index 0000000..8b73283
--- /dev/null
+++ b/docs/DEVELOPMENT.TXT
@@ -0,0 +1,113 @@
+Introduction:
+-------------
+
+This document provides important information about the Android
+emulator codebase, which will be useful for anyone planning to
+contribute patches to it.
+
+  **** IMPORTANT NOTE *******************************************************
+  THE ANDROID EMULATOR SOURCES ARE CURRENTLY HEAVILY BEING REFACTORED, IF YOU
+  PLAN TO SUBMIT CONTRIBUTIONS, PLEASE READ docs/REFACTORING-MADNESS.TXT FOR
+  DETAILS ON HOW TO AVOID BREAKAGES.
+  ***************************************************************************
+
+
+I. Building from sources:
+-------------------------
+
+This is covered in docs/BUILDING.TXT
+
+
+II. Overall source layout:
+--------------------------
+
+The Android emulator sources contains many, heavily-modified, sources from the
+upstream QEMU project (http://www.qemu.org). It adds the following directories:
+
+  android/
+    Android-specific code, used to implement a UI and functional layer on
+    top of the QEMU code base. Ideally, anything that shouldn't impact the
+    QEMU internals should be here.
+
+  include/hw/android/goldfish/
+    Headers for the Android-specific goldfish virtual devices.
+    See docs/GOLDFISH-VIRTUAL-PLATFORM.TXT for more details.
+
+  hw/android/goldfish/
+    Implementation files for the Android-specific goldfish virtual devices.
+
+  hw/android/
+    Implementation files for the Android-specific virtual ARM and MIPS
+    boards. For x86, the content of hw/i386/pc.c was modified instead.
+
+  distrib/
+    Contains various third-party libraries the emulator depends on
+    (e.g. zlib, libpng, libSDL).
+
+  elff/
+    Generic ELF processing library, used by memcheck/ implementation.
+    Also used by the "ndk-stack" Android NDK tool. Should probably move
+    to distrib/ or android/ though.
+
+  memcheck/
+    Implementation files related to the Valgrind-like memory checking mode
+    triggered by the -memcheck option (see -help-memcheck). Should move
+    to android/
+
+  slirp-android/
+    Modified version of the slirp/ directory, which adds various Android-specific
+    features and modifications.
+
+  telephony/
+    GSM modem emulation code. Implemented as a QEMU CharDevice (probably
+    needs to be refactored then move to android/).
+
+  proxy/
+    A transparent HTTP rewriting proxy used to implement the -http-proxy option.
+    (need refactor + move to android/)
+
+Generally speaking, some QEMU source files have been rewritten in so signficant
+ways that they gained an -android prefix (e.g. vl-android.c versus vl.c). The
+original file is typically kept as a reference to make it easier to see
+modifications and eventually integrate upstream changes.
+
+Only a fraction of the QEMU sources are actually part of the Android emulator
+sources, and this is intentional. It makes maintaining them easier, especially
+when trying to compare with the state of upstream QEMU.
+
+
+III. Testing:
+-------------
+
+There is currently very limited automated testing for the Android emulator,
+in the form of the "android_unittests" and "android64_unittests" programs,
+which, when invoked, will run a series of GoogleTest-based unit tests that
+only check internal features of the Android-specific code.
+
+There is work to significantly increase the coverage of these unit tests, as
+well as plans for automated function testing. However, for now manual testing of
+the emulator binaries with existing SDK system images remains necessary.
+
+
+III. Integrating upstream QEMU changes:
+---------------------------------------
+
+It is sometimes useful to integrate changes from upstream QEMU into the Android
+emulator code (e.g. to gain new features, like the ability to emulate new CPUs,
+or fix some bugs).
+
+Doing this is a delicate affair, but workable when using directory comparison
+tools (e.g. meld), and a lot of patience. It is strongly recommended to read
+both Android emulator and QEMU documentation before trying to do so though.
+
+Do not try to integrate QEMU features that are not directly useful to the
+Android emulator. It's generally preferable to write stubs. The Android emulator
+does not use many QEMU features, like user-mode-emulation, the QEMU monitor,
+the QMP protocol, tracing, and many many more.
+
+
+  **** IMPORTANT NOTE *******************************************************
+  THE ANDROID EMULATOR SOURCES ARE CURRENTLY HEAVILY BEING REFACTORED, IF YOU
+  PLAN TO SUBMIT CONTRIBUTIONS, PLEASE READ docs/REFACTORING-MADNESS.TXT FOR
+  DETAILS ON HOW TO AVOID BREAKAGES.
+  ***************************************************************************
diff --git a/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT b/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
new file mode 100644
index 0000000..a0dc90d
--- /dev/null
+++ b/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
@@ -0,0 +1,917 @@
+Introduction
+============
+
+This file documents the 'goldfish' virtual hardware platform used to run some
+emulated Android systems under QEMU. It serves as a reference for implementers
+of virtual devices in QEMU, as well as Linux kernel developers who need to
+maintain the corresponding drivers.
+
+The following abbreviations will be used here:
+
+  $QEMU  -> path to the Android AOSP directory, i.e. a git clone of
+            https://android.googlesource.com/platform/external/qemu.git
+
+  $KERNEL -> path to the Android goldfish kernel source tree, i.e. a git clone of
+             https://android.googlesource.com/kernel/goldfish.git
+
+             More specifically, to the android-goldfish-2.6.29 branch for now.
+
+'goldfish' is the name of a family of similar virtual hardware platforms, that
+mostly differ in the virtual CPU they support. 'goldfish' started as an
+ARM-specific platform, but has now been ported to x86 and MIPS virtual CPUs.
+
+Inside of QEMU, goldfish-specific virtual device implementation sources files
+are in $QEMU/hw/android/goldfish/*.c sources
+
+Inside the Linux kernel tree, they are under $KERNEL/arch/$ARCH/mach-goldfish,
+or $KERNEL/arch/$ARCH/goldfish/, as well as a few arch-independent drivers in
+different locations (detailed below).
+
+Goldfish devices appear to the Linux kernel as 'platform devices'. Read [1] and
+[2] for an introduction and reference documentation for these.
+
+Each device is identified by a name, and an optional unique id (an integer used
+to distinguish between several identical instances of similar devices, like
+serial ports, of block devices). When only one instance of a given device can
+be used, an ID of -1 is used instead.
+
+It also communicates with the kernel through:
+
+  - One or more 32-bit of I/O registers, mapped to physical addresses at
+    specific locations which depend on the architecture.
+
+  - Zero or more interrupt requests, used to signal to the kernel that an
+    important event occured.
+
+    Note that IRQ lines are numbered from 0 to 31, and are relative to the
+    goldfish interrupt controller, documented below.
+
+
+[1] http://lwn.net/Articles/448499/
+[2] https://www.kernel.org/doc/Documentation/driver-model/platform.txt
+
+
+I. Goldfish platform bus:
+=========================
+
+The 'platform bus', in Linux kernel speak, is a special device that is capable
+of enumerating other platform devices found on the system to the kernel. This
+flexibility allows to customize which virtual devices are available when running
+a given emulated system configuration.
+
+Relevant files:
+  $QEMU/hw/android/goldfish/device.c
+  $KERNEL/arch/arm/mach-goldfish/pdev_bus.c
+  $KERNEL/arch/x86/mach-goldfish/pdev_bus.c
+  $KERNEL/arch/mips/goldfish/pdev_bus.c
+
+Device properties:
+  Name: goldfish_device_bus
+  Id:   -1
+  IrqCount: 1
+
+  32-bit I/O registers (offset, name, abstract)
+
+    0x00 BUS_OP      R: Iterate to next device in enumeration.
+                     W: Start device enumeration.
+
+    0x04 GET_NAME    W: Copy device name to kernel memory.
+    0x08 NAME_LEN    R: Read length of current device's name.
+    0x0c ID          R: Read id of current device.
+    0x10 IO_BASE     R: Read I/O base address of current device.
+    0x14 IO_SIZE     R: Read I/O base size of current device.
+    0x18 IRQ_BASE    R: Read base IRQ of current device.
+    0x1c IRQ_COUNT   R: Read IRQ count of current device.
+
+The kernel iterates over the list of current devices with something like:
+
+   IO_WRITE(BUS_OP, 0);    // Start iteration, any value other than 0 is invalid.
+   for (;;) {
+     int ret = IO_READ(BUS_OP);
+     if (ret == 0 /* OP_DONE */) {
+       // no more devices.
+       break;
+     }
+     else if (ret == 8 /* OP_ADD_DEV */) {
+       // Read device properties.
+       Device dev;
+       dev.name_len  = IO_READ(NAME_LEN);
+       dev.id        = IO_READ(ID);
+       dev.io_base   = IO_READ(IO_BASE);
+       dev.io_size   = IO_READ(IO_SIZE);
+       dev.irq_base  = IO_READ(IRQ_BASE);
+       dev.irq_count = IO_READ(IRQ_COUNT);
+
+       dev.name = kalloc(dev.name_len + 1);  // allocate room for device name.
+       IO_WRITE(GET_NAME, dev.name);         // copy to kernel memory.
+       dev.name[dev.name_len] = 0;
+
+       .. add device to kernel's list.
+     }
+     else {
+       // Not returned by current goldfish implementation.
+     }
+   }
+
+The device also uses a single IRQ, which it will raise to indicate to the kernel
+that new devices are available, or that some of them have been removed. The
+kernel will then start a new enumeration. The IRQ is lowered by the device only
+when a IO_READ(BUS_OP) returns 0 (OP_DONE).
+
+NOTE: The kernel hard-codes a platform_device definition with the name
+      "goldfish_pdev_bus" for the platform bus (e.g. see
+      $KERNEL/arch/arm/mach-goldfish/board-goldfish.c), however, the bus itself
+      will appear during enumeration as a device named "goldfish_device_bus"
+
+      The kernel driver for the platform bus only matches the "goldfish_pdev_bus"
+      name, and will ignore any device named "goldfish_device_bus".
+
+
+II. Goldfish interrupt controller:
+==================================
+
+IMPORTANT: The controller IS NOT USED IN EMULATED X86 SYSTEMS.
+           TODO(digit): Indicate which virtual PIC is used on x86 systems.
+
+Relevant files:
+  $QEMU/hw/android/goldfish/interrupt.c
+  $KERNEL/arch/arm/mach-goldfish/board-goldfish.c
+  $KERNEL/arch/mips/goldfish/goldfish-interrupt.c
+
+Device properties:
+  Name: goldfish_interrupt_controller
+  Id: -1
+  IrqCount: 0  (uses parent CPU IRQ instead).
+
+  32-bit I/O registers (offset, name, abtract):
+    0x00 STATUS       R: Read the number of pending interrupts (0 to 32).
+    0x04 NUMBER       R: Read the lowest pending interrupt index, or 0 if none.
+    0x08 DISABLE_ALL  W: Clear all pending interrupts (does not disable them!)
+    0x0c DISABLE      W: Disable a given interrupt, value must be in [0..31].
+    0x10 ENABLE       W: Enable a given interrupt, value must be in [0..31].
+
+Goldfish provides its own interrupt controller that can manage up to 32 distinct
+maskable interrupt request lines. The controller itself is cascaded from a
+parent CPU IRQ.
+
+What this means in practice:
+
+  - Each IRQ has a 'level' that is either 'high' (1) or 'low' (0).
+
+  - Each IRQ also has a binary 'enable' flag.
+
+  - Whenever (level == 1 && enabled == 1) is reached due to a state change, the
+    controller raises its parent IRQ. This typically interrupts the CPU and
+    forces the kernel to deal with the interrupt request.
+
+  - Raised/Enabled interrupts that have not been serviced yet are called
+    "pending". Raised/Disabled interrupts are called "masked" and are
+    essentially silent until enabled.
+
+When the interrupt controller triggers the parent IRQ, the kernel should do
+the following:
+
+  num_pending = IO_READ(STATUS);  // Read number of pending interrupts.
+  for (int n = 0; n < num_pending; ++n) {
+    int irq_index = IO_READ(NUMBER);  // Read n-th interrupt index.
+    .. service interrupt request with the proper driver.
+  }
+
+IO_WRITE(DISABLE, <num>) or IO_WRITE(ENABLE, <num>) can change the 'enable' flag
+of a given IRQ. <num> must be a value in the [0..31] range. Note that enabling
+an IRQ which has already been raised will make it active, i.e. it will raise
+the parent IRQ.
+
+IO_WRITE(DISABLE_ALL, 0) can be used to lower all interrupt levels at once (even
+disabled one). Note that this constant is probably mis-named since it does not
+change the 'enable' flag of any IRQ.
+
+Note that this is the only way for the kernel to lower an IRQ level through
+this device. Generally speaking, Goldfish devices are responsible for lowering
+their own IRQ, which is performed either when a specific condition is met, or
+when the kernel reads from or writes to a device-specific I/O register.
+
+
+III. Godlfish timer:
+====================
+
+NOTE: This is not used on x86 emulated platforms.
+
+Relevant files:
+  $QEMU/hw/android/goldfish/timer.c
+  $KERNEL/arch/arm/mach-goldfish/timer.c
+  $KERNEL/arch/mips/goldfish/goldfish-time.c
+
+Device properties:
+  Name: goldfish_timer
+  Id: -1
+  IrqCount: 1
+
+  32-bit I/O registers (offset, name, abstract)
+    0x00  TIME_LOW         R: Get current time, then return low-order 32-bits.
+    0x04  TIME_HIGH        R: Return high 32-bits from previous TIME_LOW read.
+    0x08  ALARM_LOW        W: Set low 32-bit value of alarm, then arm it.
+    0x0c  ALARM_HIGH       W: Set high 32-bit value of alarm.
+    0x10  CLEAR_INTERRUPT  W: Lower device's irq level.
+    0x14  CLEAR_ALARM
+
+This device is used to return the current host time to the kernel, as a
+high-precision signed 64-bit nanoseconds value, starting from a liberal point
+in time. This value should correspond to the QEMU "vm_clock", i.e. it should
+not be updated when the emulated system does _not_ run, and hence cannot be
+based directly on a host clock.
+
+To read the value, the kernel must perform an IO_READ(TIME_LOW), which returns
+an unsigned 32-bit value, before an IO_READ(TIME_HIGH), which returns a signed
+32-bit value, corresponding to the higher half of the full value.
+
+The device can also be used to program an alarm, with something like:
+
+  IO_WRITE(ALARM_HIGH, <high-value>)  // Must happen first.
+  IO_WRITE(ALARM_LOW, <low-value>)    // Must happen second.
+
+When the corresponding value is reached, the device will raise its IRQ. Note
+that the IRQ is raised as soon as the second IO_WRITE() if the alarm value is
+already older than the current time.
+
+IO_WRITE(CLEAR_INTERRUPT, <any>) can be used to lower the IRQ level once the
+alarm has been handled by the kernel.
+
+IO_WRITE(CLEAR_ALARM, <any>) can be used to disarm an existing alarm, if any.
+
+Note: At the moment, the alarm is only used on ARM-based system. MIPS based
+      systems only use TIME_LOW / TIME_HIGH on this device.
+
+
+III. Goldfish real-time clock (RTC):
+====================================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/timer.c
+  $KERNEL/drivers/rtc/rtc-goldfish.c
+
+Device properties:
+  Name: goldfish_rtc
+  Id: -1
+  IrqCount: 1
+  I/O Registers:
+    0x00  TIME_LOW         R: Get current time, then return low-order 32-bits.
+    0x04  TIME_HIGH        R: Return high 32-bits, from previous TIME_LOW read.
+    0x08  ALARM_LOW        W: Set low 32-bit value or alarm, then arm it.
+    0x0c  ALARM_HIGH       W: Set high 32-bit value of alarm.
+    0x10  CLEAR_INTERRUPT  W: Lower device's irq level.
+
+This device is _very_ similar to the Goldfish timer one, with the following
+important differences:
+
+  - Values reported are still 64-bit nanoseconds, but they have a granularity
+    of 1 second, and represent host-specific values (really 'time() * 1e9')
+
+  - The alarm is non-functioning, i.e. writing to ALARM_LOW / ALARM_HIGH will
+    work, but will never arm any alarm.
+
+To support old Goldfish kernels, make sure to support writing to
+ALARM_LOW / ALARM_HIGH / CLEAR_INTERRUPT, even if the device never raises its
+IRQ.
+
+
+IV. Goldfish serial port (tty):
+===============================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/tty.c
+  $KERNEL/drivers/char/goldfish_tty.c
+  $KERNEL/arch/arm/mach-goldfish/include/debug-macro.S
+
+Device properties:
+  Name: goldfish_tty
+  Id: 0 to N
+  IrqCount:
+  I/O Registers:
+    0x00  PUT_CHAR      W: Write a single 8-bit value to the serial port.
+    0x04  BYTES_READY   R: Read the number of available buffered input bytes.
+    0x08  CMD           W: Send command (see below).
+    0x10  DATA_PTR      W: Write kernel buffer address.
+    0x14  DATA_LEN      W: Write kernel buffer size.
+
+This is the first case of a multi-instance goldfish device in this document.
+Each instance implements a virtual serial port that contains a small internal
+buffer where incoming data is stored until the kernel fetches it.
+
+The CMD I/O register is used to send various commands to the device, identified
+by the following values:
+
+  0x00  CMD_INT_DISABLE   Disable device.
+  0x01  CMD_INT_ENABLE    Enable device.
+  0x02  CMD_WRITE_BUFFER  Write buffer from kernel to device.
+  0x03  CMD_READ_BUFFER   Read buffer from device to kernel.
+
+Each device instance uses one IRQ that is raised to indicate that there is
+incoming/buffered data to read. To read such data, the kernel should do the
+following:
+
+    len = IO_READ(PUT_CHAR);   // Read length of incoming data.
+    if (len == 0) return;      // Nothing to do.
+
+    available = get_buffer(len, &buffer);  // Get address of buffer and its size.
+    IO_WRITE(DATA_PTR, buffer);            // Write buffer address to device.
+    IO_WRITE(DATA_LEN, available);         // Write buffer length to device.
+    IO_WRITE(CMD, CMD_READ_BUFFER);        // Read the data into kernel buffer.
+
+The device will automatically lower its IRQ when there is no more input data
+in its buffer. However, the kernel can also temporarily disable device interrupts
+with CMD_INT_DISABLE / CMD_INT_ENABLE.
+
+Note that disabling interrupts does not flush the buffer, nor prevent it from
+buffering further data from external inputs.
+
+To write to the serial port, the device can either send a single byte at a time
+with:
+
+  IO_WRITE(PUT_CHAR, <value>)    // Send the lower 8 bits of <value>.
+
+Or use the mode efficient sequence:
+
+  IO_WRITE(DATA_PTR, buffer)
+  IO_WRITE(DATA_LEN, buffer_len)
+  IO_WRITE(CMD, CMD_WRITE_BUFFER)
+
+The former is less efficient but simpler, and is typically used by the kernel
+to send debug messages only.
+
+Note that the Android emulator always reserves the first two virtual serial
+ports:
+
+  - The first one is used to receive kernel messages, this is done by adding
+    the 'console=ttyS0' parameter to the kernel command line in
+    $QEMU/vl-android.c
+
+  - The second one is used to setup the legacy "qemud" channel, used on older
+    Android platform revisions. This is done by adding 'android.qemud=ttyS1'
+    on the kernel command line in $QEMU/vl-android.c
+
+    Read docs/ANDROID-QEMUD.TXT for more details about the data that passes
+    through this serial port. In a nutshell, this is required to emulate older
+    Android releases (e.g. cupcake). It provides a direct communication channel
+    between the guest system and the emulator.
+
+    More recent Android platforms do not use QEMUD anymore, but instead rely
+    on the much faster "QEMU pipe" device, described later in this document as
+    well as in docs/ANDROID-QEMU-PIPE.TXT.
+
+
+V. Goldfish framebuffer:
+========================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/fb.c
+  $KERNEL/drivers/video/goldfish_fb.c
+
+Device properties:
+  Name: goldfish_fb
+  Id: 0 to N  (only one used in practice).
+  IrqCount: 0
+  I/O Registers:
+    0x00  GET_WIDTH       R: Read framebuffer width in pixels.
+    0x04  GET_HEIGHT      R: Read framebuffer height in pixels.
+    0x08  INT_STATUS
+    0x0c  INT_ENABLE
+    0x10  SET_BASE
+    0x14  SET_ROTATION
+    0x18  SET_BLANK       W: Set 'blank' flag.
+    0x1c  GET_PHYS_WIDTH  R: Read framebuffer width in millimeters.
+    0x20  GET_PHYS_HEIGHT R: Read framebuffer height in millimeters.
+    0x24  GET_FORMAT      R: Read framebuffer pixel format.
+
+The framebuffer device is a bit peculiar, because it uses, in addition to the
+typical I/O registers and IRQs, a large area of physical memory, allocated by
+the kernel, but visible to the emulator, to store a large pixel buffer.
+
+The emulator is responsible for displaying the framebuffer content in its UI
+window, which can be rotated, as instructed by the kernel.
+
+IMPORTANT NOTE: When GPU emulation is enabled, the framebuffer will typically
+only be used during boot. Note that GPU emulation doesn't rely on a specific
+virtual GPU device, however, it uses the "QEMU Pipe" device described below.
+For more information, please read:
+
+  https://android.googlesource.com/platform/sdk/+/master/emulator/opengl/DESIGN
+
+On boot, the kernel will read various properties of the framebuffer:
+
+  IO_READ(GET_WIDTH) and IO_READ(GET_HEIGHT) return the width and height of
+  the framebuffer in pixels. Note that a 'row' corresponds to consecutive bytes
+  in memory, but doesn't necessarily to an horizontal line on the final display,
+  due to possible rotation (see SET_ROTATION below).
+
+  IO_READ(GET_PHYS_WIDTH) and IO_READ(GET_PHYS_HEIGHT) return the emulated
+  physical width and height in millimeters, this is later used by the kernel
+  and the platform to determine the device's emulated density.
+
+  IO_READ(GET_FORMAT) returns a value matching the format of pixels in the
+  framebuffer. Note that these values are specified by the Android hardware
+  abstraction layer (HAL) and cannot change:
+
+    0x01  HAL_PIXEL_FORMAT_BRGA_8888
+    0x02  HAL_PIXEL_FORMAT_RGBX_8888
+    0x03  HAL_PIXEL_FORMAT_RGB_888
+    0x04  HAL_PIXEL_FORMAT_RGB_565
+    0x05  HAL_PIXEL_FORMAT_BGRA_8888
+    0x06  HAL_PIXEL_FORMAT_RGBA_5551
+    0x08  HAL_PIXEL_FORMAT_RGBA_4444
+
+  HOWEVER, the kernel driver only expects a value of HAL_PIXEL_FORMAT_RGB_565
+  at the moment. Until this is fixed, the virtual device should always return
+  the value 0x04 here. Rows are not padded, so the size in bytes of a single
+  framebuffer will always be exactly 'width * heigth * 2'.
+
+  Note that GPU emulation doesn't have this limitation and can use and display
+  32-bit surfaces properly, because it doesn't use the framebuffer.
+
+The device has a 'blank' flag. When set to 1, the UI should only display an
+empty/blank framebuffer, ignoring the content of the framebuffer memory.
+It is set with IO_WRITE(SET_BLANK, <value>), where value can be 1 or 0. This is
+used when simulating suspend/resume.
+
+IMPORTANT: The framebuffer memory is allocated by the kernel, which will send
+its physical address to the device by using IO_WRITE(SET_BASE, <address>).
+
+The kernel really allocates a memory buffer large enough to hold *two*
+framebuffers, in order to implement panning / double-buffering. This also means
+that calls to IO_WRITE(SET_BASE, <address>) will be frequent.
+
+The allocation happens with dma_alloc_writecombine() on ARM, which can only
+allocate a maximum of 4 MB, this limits the size of each framebuffer to 2 MB,
+which may not be enough to emulate high-density devices :-(
+
+For other architectures, dma_alloc_coherent() is used instead, and has the same
+upper limit / limitation.
+
+TODO(digit): Explain how it's possible to raise this limit by modifyinf
+             CONSISTENT_DMA_SIZE and/or MAX_ORDER in the kernel configuration.
+
+The device uses a single IRQ to notify the kernel of several events. When it
+is raised, the kernel IRQ handler must IO_READ(INT_STATUS), which will return
+a value containing the following bit flags:
+
+  bit 0: Set to 1 to indicate a VSYNC event.
+
+  bit 1: Set to 1 to indicate that the content of a previous SET_BASE has
+         been properly displayed.
+
+Note that reading this register also lowers the device's IRQ level.
+
+The second flag is essentially a way to notify the kernel that an
+IO_WRITE(SET_BASE, <address>) operation has been succesfully processed by
+the emulator, i.e. that the new content has been displayed to the user.
+
+The kernel can control which flags should raise an IRQ by using
+IO_WRITE(INT_ENABLE, <flags>), where <flags> has the same format as the
+result of IO_READ(INT_STATUS). If the corresponding bit is 0, the an IRQ
+for the corresponding event will never be generated,
+
+
+VI. Goldfish audio device:
+==========================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/audio.c
+  $KERNEL/drivers/misc/goldfish_audio.c
+
+Device properties:
+  Name: goldfish_audio
+  Id: -1
+  IrqCount: 1
+  I/O Registers:
+    0x00  INT_STATUS
+    0x04  INT_ENABLE
+    0x08  SET_WRITE_BUFFER_1     W: Set address of first kernel output buffer.
+    0x0c  SET_WRITE_BUFFER_2     W: Set address of second kernel output buffer.
+    0x10  WRITE_BUFFER_1         W: Send first kernel buffer samples to output.
+    0x14  WRITE_BUFFER_2         W: Send second kernel buffer samples to output.
+    0x18  READ_SUPPORTED         R: Reads 1 if input is supported, 0 otherwise.
+    0x1c  SET_READ_BUFFER
+    0x20  START_READ
+    0x24  READ_BUFFER_AVAILABLE
+
+This device implements a virtual sound card with the following properties:
+
+  - Stereo output at fixed 44.1 kHz frequency, using signed 16-bit samples.
+    Mandatory.
+
+  - Mono input at fixed 8 kHz frequency, using signed 16-bit samples.
+    Optional.
+
+For output, the kernel driver allocates two internal buffers to hold output
+samples, and passes their physical address with
+IO_WRITE(SET_WRITE_BUFFER_1, <buffer1>) and
+IO_WRITE(SET_WRITE_BUFFER_2, <buffer2>).
+
+After this, samples will be sent from the driver to the virtual device by
+using one of IO_WRITE(WRITE_BUFFER_1, <length1>) or
+IO_WRITE(WRITE_BUFFER_2, <length2>), depending on which sample buffer to use.
+NOTE: Each length is in bytes.
+
+Note however that the driver should wait, before doing this, until the device
+gives permission by raising its IRQ and setting the appropriate 'status' flags.
+
+The virtual device has an internal 'int_status' field made of 3 bit flags:
+
+  bit0: 1 iff the device is ready to receive data from the first buffer.
+  bit1: 1 iff the device is ready to receive data from the second buffer.
+  bit2: 1 iff the device has input samples for the kernel to read.
+
+Note that an IO_READ(INT_STATUS) also automatically lowers the IRQ level,
+except if the read value is 0 (which should not happen, since it should not
+raise the IRQ).
+
+The corresponding interrupts can be masked by using IO_WRITE(INT_ENABLE, <mask>),
+where <mask> has the same format as 'int_status'. A 1 bit in the mask enables the
+IRQ raise when the corresponding status bit is also set to 1.
+
+For input, the driver should first IO_READ(READ_SUPPORTED), which will return 1
+if the virtual device supports input, or 0 otherwise. If it does support it,
+the driver must allocate an internal buffer and send its physical address with
+IO_WRITE(SET_READ_BUFFER, <read-buffer>), then perform
+IO_WRITE(START_READ, <read-buffer-length>) to start recording and specify
+the kernel's buffer length.
+
+Later, the device will raise its IRQ and set bit2 of 'int_status' to indicate
+there are incoming samples to the driver. In its interrupt handler, the latter
+should IO_READ(READ_BUFFER_AVAILABLE), which triggers the transfer (from the
+device to the kernel), as well as return the size in bytes of the samples.
+
+
+VII. Goldfish battery:
+======================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/battery.c
+  $QEMU/hw/power_supply.h
+  $KERNEL/drivers/power/goldfish_battery.c
+
+Device properties:
+  Name: goldfish_battery
+  Id: -1
+  IrqCount: 1
+  I/O Registers:
+    0x00 INT_STATUS   R: Read battery and A/C status change bits.
+    0x04 INT_ENABLE   W: Enable or disable IRQ on status change.
+    0x08 AC_ONLINE    R: Read 0 if AC power disconnected, 1 otherwise.
+    0x0c STATUS       R: Read battery status (charging/full/... see below).
+    0x10 HEALTH       R: Read battery health (good/overheat/... see below).
+    0x14 PRESENT      R: Read 1 if battery is present, 0 otherwise.
+    0x18 CAPACITY     R: Read battery charge percentage in [0..100] range.
+
+A simple device used to report the state of the virtual device's battery, and
+whether the device is powered through a USB or A/C adapter.
+
+The device uses a single IRQ to notify the kernel that the battery or A/C status
+changed. When this happens, the kernel should perform an IO_READ(INT_STATUS)
+which returns a 2-bit value containing flags:
+
+  bit 0: Set to 1 to indicate a change in battery status.
+  bit 1: Set to 1 to indicate a change in A/C status.
+
+Note that reading this register also lowers the IRQ level.
+
+The A/C status can be read with IO_READ(AC_ONLINE), which returns 1 if the
+device is powered, or 0 otherwise.
+
+The battery status is spread over multiple I/O registers:
+
+  IO_READ(PRESENT) returns 1 if the battery is present in the virtual device,
+  or 0 otherwise.
+
+  IO_READ(CAPACITY) returns the battery's charge percentage, as an integer
+  between 0 and 100, inclusive. NOTE: This register is probably misnamed since
+  it does not represent the battery's capacity, but it's current charge level.
+
+  IO_READ(STATUS) returns one of the following values:
+
+    0x00  UNKNOWN      Battery state is unknown.
+    0x01  CHARGING     Battery is charging.
+    0x02  DISCHARGING  Battery is discharging.
+    0x03  NOT_CHARGING Battery is not charging (e.g. full or dead).
+
+  IO_READ(HEALTH) returns one of the following values:
+
+    0x00  UNKNOWN         Battery health unknown.
+    0x01  GOOD            Battery is in good condition.
+    0x02  OVERHEATING     Battery is over-heating.
+    0x03  DEAD            Battery is dead.
+    0x04  OVERVOLTAGE     Battery generates too much voltage.
+    0x05  UNSPEC_FAILURE  Battery has unspecified failure.
+
+The kernel can use IO_WRITE(INT_ENABLE, <flags>) to select which condition
+changes should trigger an IRQ. <flags> is a 2-bit value using the same format
+as INT_STATUS.
+
+
+VIII. Goldfish events device (user input):
+==========================================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/events_device.c
+  $KERNEL/drivers/input/keyboard/goldfish_events.c
+
+Device properties:
+  Name: goldfish_events
+  Id: -1
+  IrqCount: 1
+  I/O Registers:
+    0x00 READ       R: Read next event type, code or value.
+    0x00 SET_PAGE   W: Set page index.
+    0x04 LEN        R: Read length of page data.
+    0x08 DATA       R: Read page data.
+    ....            R: Read additional page data (see below).
+
+This device is responsible for sending several kinds of user input events to
+the kernel, i.e. emulated device buttons, hardware keyboard, touch screen,
+trackball and lid events.
+
+NOTE: Android supports other input devices like mice or game controllers
+      through USB or Bluetooth, these are not supported by this virtual
+      Goldfish device.
+
+NOTE: The 'lid event' is useful for devices with a clamshell of foldable
+      keyboard design, and is used to report when it is opened or closed.
+
+As per Linux conventions, each 'emulated event' is sent to the kernel as a
+series of (<type>,<code>,<value>) triplets or 32-bit values. For more
+information, see:
+
+  https://www.kernel.org/doc/Documentation/input/input.txt
+
+As well as the <linux/input.h> kernel header.
+
+Note that in the context of goldfish:
+
+ - Button and keyboard events are reported with:
+     (EV_KEY, <code>, <press>)
+
+   Where <code> is a 9-bit keycode, as defined by <linux/input.h>, and
+   <press> is 1 for key/button presses, and 0 for releases.
+
+ - For touchscreen events, a single-touch event is reported with:
+     (EV_ABS, ABS_X, <x-position>) +
+     (EV_ABS, ABS_Y, <y-position>) +
+     (EV_ABS, ABS_Z, 0) +
+     (EV_KEY, BTN_TOUCH, <button-state>) +
+     (EV_SYN, 0, 0)
+
+   where <x-position> and <y-position> are the horizontal and vertical position
+   of the touch event, respectfully, and <button-state> is either 1 or 0 and
+   indicates the start/end of the touch gesture, respectively.
+
+ - For multi-touch events, things are much more complicated. In a nutshell,
+   these events are reported through (EV_ABS, ABS_MT_XXXXX, YYY) triplets,
+   as documented at:
+
+   https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt
+
+   TODO(digit): There may be bugs in either the virtual device or driver code
+                when it comes to multi-touch. Iron out the situation and better
+                explain what's required to support all Android platforms.
+
+ - For trackball events:
+     (EV_REL, REL_X, <x-delta>) +
+     (EV_REL, REL_Y, <y-delta>) +
+     (EV_SYN, 0, 0)
+
+   Where <x-delta> and <y-delta> are the signed relative trackball displacement
+   in the horizontal and vertical directions, respectively.
+
+ - For lid events:
+     (EV_SW, 0, 1) + (EV_SYN, 0, 0)    // When lid is closed.
+     (EV_SW, 0, 0) + (EV_SYN, 0, 0)    // When lid is opened.
+
+When the kernel driver starts, it will probe the device to know what kind
+of events are supported by the emulated configuration. There are several
+categories of queries:
+
+  - Asking for the current physical keyboard 'charmap' name, used by the system
+    to translate keycodes in actual characters. In practice, this will nearly
+    always be 'goldfish' for emulated systems, but this out of spec for this
+    document.
+
+  - Asking which event codes are supported for a given event type
+    (e.g. all the possible KEY_XXX values generated for EV_KEY typed triplets).
+
+  - Asking for various minimum or maximum values for each supported EV_ABS
+    event code. For example the min/max values of (EV_ABS, ABS_X, ...) triplets,
+    to know the bounds of the input touch panel.
+
+The kernel driver first select which kind of query it wants by using
+IO_WRITE(SET_PAGE, <page>), where <page> is one of the following values:
+
+    PAGE_NAME    0x0000   Keyboard charmap name.
+    PAGE_EVBITS  0x10000  Event code supported sets.
+    PAGE_ABSDATA 0x20003  (really 0x20000 + EV_ABS) EV_ABS min/max values.
+
+Once a 'page' has been selected, it is possible to read from it with
+IO_READ(LEN) and IO_READ(DATA). In practice:
+
+  - To read the name of the keyboard charmap, the kernel will do:
+
+      IO_WRITE(SET_PAGE, PAGE_NAME);  # Ind
+
+      charmap_name_len = IO_READ(LEN);
+      charmap_name = kalloc(charmap_name_len + 1);
+      for (int n = 0; n < charmap_name_len; ++n)
+        charmap_name[n] = (char) IO_READ(DATA);
+      charmap_name[n] = 0;
+
+  - To read which codes a given event type (here EV_KEY) supports:
+
+      IO_WRITE(SET_PAGE, PAGE_EVBITS + EV_KEY);  // Or EV_REL, EV_ABS, etc...
+
+      bitmask_len = IO_READ(LEN);
+      for (int offset = 0; offset < bitmask_len; ++offset) {
+          uint8_t mask = (uint8_t) IO_READ(DATA):
+          for (int bit = 0; bit < 8; ++bit) {
+              int code = (offset * 8) + bit;
+              if ((mask & (1 << bit)) != 0) {
+                  ... record that keycode |code| is supported.
+              }
+          }
+      }
+
+  - To read the range values of absolute event values:
+
+      IO_WRITE(SET_PAGE, PAGE_ABSDATA);
+      max_entries = IO_READ(LEN);
+      for (int n = 0; n < max_entries; n += 4) {
+        int32_t min = IO_READ(DATA + n);
+        int32_t max = IO_READ(DATA + n + 4);
+        int32_t fuzz = IO_READ(DATA + n + 8);
+        int32_t flat = IO_READ(DATA + n + 12);
+        int event_code = n/4;
+
+        // Record (min, max, fuzz, flat) values for EV_ABS 'event_code'.
+      }
+
+    Note that the 'fuzz' and 'flat' values reported by Goldfish are always 0,
+    refer to the source for more details.
+
+At runtime, the device implements a small buffer for incoming event triplets
+(each one is stored as three 32-bit integers in a circular buffer), and raises
+its IRQ to signal them to the kernel.
+
+When that happens, the kernel driver should use IO_READ(READ) to extract the
+32-bit values from the device. Note that three IO_READ() calls are required to
+extract a single event triplet.
+
+There are a few important notes here:
+
+  - The IRQ should not be raised _before_ the kernel driver is started
+    (otherwise the driver will be confused and ignore all events).
+
+    I.e. the emulator can buffer events before kernel initialization completes,
+    but should only raise the IRQ, if needed, lazily. Currently this is done
+    on the first IO_READ(LEN) following a IO_WRITE(SET_PAGE, PAGE_ABSDATA).
+
+  - The IRQ is lowered by the device once all event values have been read,
+    i.e. its buffer is empty.
+
+    However, on x86, if after an IO_READ(READ), there are still values in the
+    device's buffer, the IRQ should be lowered then re-raised immediately.
+
+
+IX. Goldfish NAND device:
+=========================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/nand.c
+  $KERNEL/drivers/mtd/devices/goldfish_nand.c
+
+Device properties:
+  Name: goldfish_nand
+  Id: -1
+  IrqCount: 1
+  I/O Registers:
+
+This virtual device can provide access to one or more emulated NAND memory
+banks [3] (each one being backed by a different host file in the current
+implementation).
+
+These are used to back the following virtual partition files:
+
+  - system.img
+  - data.img
+  - cache.img
+
+TODO(digit): Complete this.
+
+
+[3] http://en.wikipedia.org/wiki/Flash_memory#NAND_memories
+
+
+X. Goldfish MMC device:
+=======================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/mmc.c
+  $KERNEL/drivers/mmc/host/goldfish.c
+
+Device properties:
+  Name: goldfish_mmc
+  Id: -1
+  IrqCount: 1
+  I/O Registers:
+
+Similar to the NAND device, but uses a different, higher-level interface
+to access the emulated 'flash' memory. This is only used to access the
+virtual SDCard device with the Android emulator.
+
+TODO(digit): Complete this.
+
+
+XI. Goldfish memlog:
+=====================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/memlog.c
+
+Device properties:
+  Name: goldfish_memlog
+  Id: -1
+  IrqCount: 0
+  I/O Registers:
+    ???
+
+Obsolete debugging device. Should be removed from both the kernel and the
+emulator sources.
+
+
+XII. Goldfish switch:
+=====================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/switch.c
+  $KERNEL/arch/arm/mach-goldfish/switch.c
+  $KERNEL/arch/mips/goldfish/switch.c
+
+Device properties:
+  Name: goldfish_switch
+  Id: -1
+  IrqCount: 1
+  I/O Registers:
+
+Obsolete debugging device. Should be removed from both the kernel and the
+emulator sources.
+
+
+XIV. QEMU Pipe device:
+======================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/pipe.c
+  $KERNEL/drivers/misc/qemupipe/qemu_pipe.c
+
+Device properties:
+  Name: qemu_pipe
+  Id: -1
+  IrqCount: 1
+  I/O Registers:
+    0x00  COMMAND          W: Write to perform command (see below).
+    0x04  STATUS           R: Read status
+    0x08  CHANNEL          RW: Read or set current channel id.
+    0x0c  SIZE             RW: Read or set current buffer size.
+    0x10  ADDRESS          RW: Read or set current buffer physical address.
+    0x14  WAKES            R: Read wake flags.
+    0x18  PARAMS_ADDR_LOW  RW: Read/set low bytes of parameters block address.
+    0x1c  PARAMS_ADDR_HIGH RW: Read/set high bytes of parameters block address.
+    0x20  ACCESS_PARAMS    W: Perform access with parameter block.
+
+This is a special device that is totally specific to QEMU, but allows guest
+processes to communicate directly with the emulator with extremely high
+performance. This is achieved by avoiding any in-kernel memory copies, relying
+on the fact that QEMU can access guest memory at runtime (under proper
+conditions controlled by the kernel).
+
+Please refer to $QEMU/docs/ANDROID-QEMU-PIPE.TXT for full details on the
+device's operations.
+
+
+XIII. QEMU Trace device:
+========================
+
+Relevant files:
+  $QEMU/hw/android/goldfish/trace.c
+  $KERNEL/drivers/misc/qemutrace/qemu_trace.c
+  $KERNEL/drivers/misc/qemutrace/qemu_trace_sysfs.c
+  $KERNEL/fs/exec.c
+  $KERNEL/exit.c
+  $KERNEL/fork.c
+  $KERNEL/sched/core.c
+  $KERNEL/mm/mmap.c
+
+Device properties:
+  Name: qemu_trace
+  Id: -1
+  IrqCount: 0
+  I/O Registers:
+
+TODO(digit)
+
diff --git a/docs/REFACTORING-MADNESS.TXT b/docs/REFACTORING-MADNESS.TXT
new file mode 100644
index 0000000..25c77ae
--- /dev/null
+++ b/docs/REFACTORING-MADNESS.TXT
@@ -0,0 +1,123 @@
+Android emulator upstream integration madness
+=============================================
+
+After more than 2 years of inactivity, the Android emulator sources are
+being refactored to match the level of a much more recent upstream QEMU.
+
+The main goal for this work is to get to reuse Intel, ARM and MIPS 64-bit
+emulation support, as well as to clean up some of the cruft accumulated over
+the years.
+
+A secondary goal is to make it drastically easier to send patches to QEMU
+upstream to support Android use cases, when that makes sense, and if they
+are interested.
+
+
+I. Branches:
+------------
+
+All work happens in the open on the public AOSP source/gerrit servers, but
+two branches are being used:
+
+  idea133
+        This branch is currently used by the Android SDK tools team to
+        develop the next release of all SDK tools, emulator included.
+
+        If you have a general fix that is not related to the refactoring
+        work, this is where to send your contributions if you want them
+        to appear as soon as possible in the next public SDK tools release.
+
+  master
+        This branch is used to host a series of several hundred small patches
+        needed by the refactoring work. Each patch should try to do one simple
+        thing at a time. However, due to the extremely high coupling present in
+        the QEMU code base, even changing a couple header lines might impact
+        several dozen sources.
+
+        Each patch *must* result in a perfectly buildable emulator for all
+        supported host systems, and ideally not break anything when running it.
+
+        Because these patches are so numerous, they are typically uploaded to
+        the AOSP server as a batch of 20 or 50, through an explicit merge
+        commit. I.e. the batch will appear on Gerrit as a simple change, instead
+        of 20-50 individual ones.
+
+        We currently discourage you to submit to this branch on your own, unless
+        you've contacted tools@android.com first (we can help rebasing your
+        patches on top of the next batch before they happen).
+
+See section III. to see how to checkout and submit to the idea133 branch.
+
+Explicit (manual) merges will happen too:
+
+  - Merging aosp/idea133 into aosp/master will happen frequently, to ensure that
+    general fixes go into the refactored codebase.
+
+  - Merging aosp/master into aosp/idea133 will happen more rarely, and after
+    significant testing from the team to ensure that doesn't break anything.
+
+For reference, the master branch is currently targetting the upstream QEMU
+commit with the following SHA-1:
+
+        47acdd63a33a5966bf4fc94a6ac835d72a70c555
+
+Which may be updated later to integrate more upstream fixes.
+
+
+II. Scope:
+----------
+
+The priority is to get the following components to the level of upstream
+as soon as possible:
+
+  - tcg
+  - cpu emulation
+  - softmmu
+  - kvm / haxm
+  - virtual devices (goldfish and others).
+
+Other components like block/, net/, ui/, audio/ have lower priority.
+Some upstream components like qmp, tracing or migration will not be used.
+In case of doubt, contact tools@android.com.
+
+The content of android/ will also be refactored to make it more testable and
+less dependant on the QEMU parts of the code, whenever possible. It is expected
+that some of this code will be rewritten in C++ too. This is lower priority and
+will probably happen in the idea133 branch, instead of the master one.
+
+
+III. Checking it out and sending patches to idea133:
+----------------------------------------------------
+
+If you plan to work on general emulator fixes, without other parts of the
+platform, it is highly recommended to checkout the full branch with repo:
+
+  cd android-idea133
+  repo init -u https://android.googlesource.com/a/platform/manifest -b idea133
+  repo sync
+
+In that case, "repo upload" will send your patches directly from the right
+branch when you upload them to gerrit.
+
+
+If you already have a 'master' checkout of AOSP, you can still work on individual
+changes for the branch, but do _not_ use repo to upload them, instead do
+something like:
+
+  cd external/qemu
+  git checkout -t -b my-fix aosp/idea133
+
+  ... edit files ...
+  mm                     # Verify that everything builds.
+  emulator_unittests     # Run the unit tests.
+  emulator @my-test-avd  # Verify manually that everything runs.
+
+  git add .
+  git commit
+  git push aosp +HEAD:refs/for/idea133
+
+This will upload the patch to gerrit to the right branch.
+
+Be careful that a "repo sync" will erase all custom branches that are not
+tracking master. If this happens use "git reflog" to get your past state
+(but not your branches).
diff --git a/exec.c b/exec.c
index ba53ad0..609c4c7 100644
--- a/exec.c
+++ b/exec.c
@@ -39,6 +39,7 @@
 #include "hw/hw.h"
 #include "qemu/osdep.h"
 #include "sysemu/kvm.h"
+#include "exec/cputlb.h"
 #include "exec/hax.h"
 #include "qemu/timer.h"
 #if defined(CONFIG_USER_ONLY)
@@ -67,23 +68,6 @@
 
 #define SMC_BITMAP_USE_THRESHOLD 10
 
-#if defined(TARGET_SPARC64)
-#define TARGET_PHYS_ADDR_SPACE_BITS 41
-#elif defined(TARGET_SPARC)
-#define TARGET_PHYS_ADDR_SPACE_BITS 36
-#elif defined(TARGET_ALPHA)
-#define TARGET_PHYS_ADDR_SPACE_BITS 42
-#define TARGET_VIRT_ADDR_SPACE_BITS 42
-#elif defined(TARGET_PPC64)
-#define TARGET_PHYS_ADDR_SPACE_BITS 42
-#elif defined(TARGET_X86_64)
-#define TARGET_PHYS_ADDR_SPACE_BITS 42
-#elif defined(TARGET_I386)
-#define TARGET_PHYS_ADDR_SPACE_BITS 36
-#else
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#endif
-
 static TranslationBlock *tbs;
 int code_gen_max_blocks;
 TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
@@ -121,10 +105,10 @@
 RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) };
 #endif
 
-CPUState *first_cpu;
+CPUArchState *first_cpu;
 /* current CPU in the current thread. It is only valid inside
    cpu_exec() */
-CPUState *cpu_single_env;
+CPUArchState *cpu_single_env;
 /* 0 = Do not count executed instructions.
    1 = Precise instruction counting.
    2 = Adaptive rate instruction counting.  */
@@ -145,12 +129,6 @@
 #endif
 } PageDesc;
 
-typedef struct PhysPageDesc {
-    /* offset in host memory of the page + io_index in the low bits */
-    ram_addr_t phys_offset;
-    ram_addr_t region_offset;
-} PhysPageDesc;
-
 #define L2_BITS 10
 #if defined(CONFIG_USER_ONLY) && defined(TARGET_VIRT_ADDR_SPACE_BITS)
 /* XXX: this is a temporary hack for alpha target.
@@ -165,10 +143,9 @@
 #define L1_SIZE (1 << L1_BITS)
 #define L2_SIZE (1 << L2_BITS)
 
-unsigned long qemu_real_host_page_size;
-unsigned long qemu_host_page_bits;
-unsigned long qemu_host_page_size;
-unsigned long qemu_host_page_mask;
+uintptr_t qemu_real_host_page_size;
+uintptr_t qemu_host_page_size;
+uintptr_t qemu_host_page_mask;
 
 /* XXX: for system emulation, it could just be an array */
 static PageDesc *l1_map[L1_SIZE];
@@ -182,7 +159,7 @@
 CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
 void *io_mem_opaque[IO_MEM_NB_ENTRIES];
 static char io_mem_used[IO_MEM_NB_ENTRIES];
-static int io_mem_watch;
+int io_mem_watch;
 #endif
 
 /* log support */
@@ -196,7 +173,6 @@
 static int log_append = 0;
 
 /* statistics */
-static int tlb_flush_count;
 static int tb_flush_count;
 static int tb_phys_invalidate_count;
 
@@ -253,9 +229,6 @@
         qemu_host_page_size = qemu_real_host_page_size;
     if (qemu_host_page_size < TARGET_PAGE_SIZE)
         qemu_host_page_size = TARGET_PAGE_SIZE;
-    qemu_host_page_bits = 0;
-    while ((1 << qemu_host_page_bits) < qemu_host_page_size)
-        qemu_host_page_bits++;
     qemu_host_page_mask = ~(qemu_host_page_size - 1);
     l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *));
     memset(l1_phys_map, 0, L1_SIZE * sizeof(void *));
@@ -383,15 +356,12 @@
     return ((PhysPageDesc *)pd) + (index & (L2_SIZE - 1));
 }
 
-static inline PhysPageDesc *phys_page_find(hwaddr index)
+PhysPageDesc *phys_page_find(hwaddr index)
 {
     return phys_page_find_alloc(index, 0);
 }
 
 #if !defined(CONFIG_USER_ONLY)
-static void tlb_protect_code(ram_addr_t ram_addr);
-static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
-                                    target_ulong vaddr);
 #define mmap_lock() do { } while(0)
 #define mmap_unlock() do { } while(0)
 #endif
@@ -535,7 +505,7 @@
 
 static void cpu_common_save(QEMUFile *f, void *opaque)
 {
-    CPUState *env = opaque;
+    CPUOldState *env = opaque;
 
     cpu_synchronize_state(env, 0);
 
@@ -545,7 +515,7 @@
 
 static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
 {
-    CPUState *env = opaque;
+    CPUOldState *env = opaque;
 
     if (version_id != CPU_COMMON_SAVE_VERSION)
         return -EINVAL;
@@ -562,9 +532,9 @@
 }
 #endif
 
-CPUState *qemu_get_cpu(int cpu)
+CPUArchState *qemu_get_cpu(int cpu)
 {
-    CPUState *env = first_cpu;
+    CPUArchState *env = first_cpu;
 
     while (env) {
         if (env->cpu_index == cpu)
@@ -575,9 +545,9 @@
     return env;
 }
 
-void cpu_exec_init(CPUState *env)
+void cpu_exec_init(CPUArchState *env)
 {
-    CPUState **penv;
+    CPUArchState **penv;
     int cpu_index;
 
 #if defined(CONFIG_USER_ONLY)
@@ -635,9 +605,9 @@
 
 /* flush all the translation blocks */
 /* XXX: tb_flush is currently not thread safe */
-void tb_flush(CPUState *env1)
+void tb_flush(CPUArchState *env1)
 {
-    CPUState *env;
+    CPUArchState *env;
 #if defined(DEBUG_FLUSH)
     printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
            (unsigned long)(code_gen_ptr - code_gen_buffer),
@@ -781,7 +751,7 @@
 
 void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr)
 {
-    CPUState *env;
+    CPUArchState *env;
     PageDesc *p;
     unsigned int h, n1;
     hwaddr phys_pc;
@@ -898,7 +868,7 @@
     }
 }
 
-TranslationBlock *tb_gen_code(CPUState *env,
+TranslationBlock *tb_gen_code(CPUArchState *env,
                               target_ulong pc, target_ulong cs_base,
                               int flags, int cflags)
 {
@@ -922,10 +892,6 @@
     tb->cs_base = cs_base;
     tb->flags = flags;
     tb->cflags = cflags;
-#ifdef CONFIG_TRACE
-    tb->bb_rec = NULL;
-    tb->prev_time = 0;
-#endif
     cpu_gen_code(env, tb, &code_gen_size);
     code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
 
@@ -948,7 +914,7 @@
                                    int is_cpu_write_access)
 {
     TranslationBlock *tb, *tb_next, *saved_tb;
-    CPUState *env = cpu_single_env;
+    CPUArchState *env = cpu_single_env;
     target_ulong tb_start, tb_end;
     PageDesc *p;
     int n;
@@ -1085,7 +1051,7 @@
     int n;
 #ifdef TARGET_HAS_PRECISE_SMC
     TranslationBlock *current_tb = NULL;
-    CPUState *env = cpu_single_env;
+    CPUArchState *env = cpu_single_env;
     int current_tb_modified = 0;
     target_ulong current_pc = 0;
     target_ulong current_cs_base = 0;
@@ -1341,7 +1307,7 @@
 }
 
 #if defined(TARGET_HAS_ICE)
-static void breakpoint_invalidate(CPUState *env, target_ulong pc)
+static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
 {
     hwaddr addr;
     target_ulong pd;
@@ -1361,7 +1327,7 @@
 #endif
 
 /* Add a watchpoint.  */
-int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
+int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
                           int flags, CPUWatchpoint **watchpoint)
 {
     target_ulong len_mask = ~(len - 1);
@@ -1393,7 +1359,7 @@
 }
 
 /* Remove a specific watchpoint.  */
-int cpu_watchpoint_remove(CPUState *env, target_ulong addr, target_ulong len,
+int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, target_ulong len,
                           int flags)
 {
     target_ulong len_mask = ~(len - 1);
@@ -1410,7 +1376,7 @@
 }
 
 /* Remove a specific watchpoint by reference.  */
-void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint)
+void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint)
 {
     QTAILQ_REMOVE(&env->watchpoints, watchpoint, entry);
 
@@ -1420,7 +1386,7 @@
 }
 
 /* Remove all matching watchpoints.  */
-void cpu_watchpoint_remove_all(CPUState *env, int mask)
+void cpu_watchpoint_remove_all(CPUArchState *env, int mask)
 {
     CPUWatchpoint *wp, *next;
 
@@ -1431,7 +1397,7 @@
 }
 
 /* Add a breakpoint.  */
-int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
+int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
                           CPUBreakpoint **breakpoint)
 {
 #if defined(TARGET_HAS_ICE)
@@ -1459,7 +1425,7 @@
 }
 
 /* Remove a specific breakpoint.  */
-int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags)
+int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags)
 {
 #if defined(TARGET_HAS_ICE)
     CPUBreakpoint *bp;
@@ -1477,7 +1443,7 @@
 }
 
 /* Remove a specific breakpoint by reference.  */
-void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint)
+void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint)
 {
 #if defined(TARGET_HAS_ICE)
     QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
@@ -1489,7 +1455,7 @@
 }
 
 /* Remove all matching breakpoints. */
-void cpu_breakpoint_remove_all(CPUState *env, int mask)
+void cpu_breakpoint_remove_all(CPUArchState *env, int mask)
 {
 #if defined(TARGET_HAS_ICE)
     CPUBreakpoint *bp, *next;
@@ -1503,7 +1469,7 @@
 
 /* enable or disable single step mode. EXCP_DEBUG is returned by the
    CPU loop after each instruction */
-void cpu_single_step(CPUState *env, int enabled)
+void cpu_single_step(CPUOldState *env, int enabled)
 {
 #if defined(TARGET_HAS_ICE)
     if (env->singlestep_enabled != enabled) {
@@ -1557,7 +1523,7 @@
     cpu_set_log(loglevel);
 }
 
-static void cpu_unlink_tb(CPUState *env)
+static void cpu_unlink_tb(CPUOldState *env)
 {
     /* FIXME: TB unchaining isn't SMP safe.  For now just ignore the
        problem and hope the cpu will stop of its own accord.  For userspace
@@ -1578,7 +1544,7 @@
 }
 
 /* mask must never be zero, except for A20 change call */
-void cpu_interrupt(CPUState *env, int mask)
+void cpu_interrupt(CPUOldState *env, int mask)
 {
     int old_mask;
 
@@ -1609,90 +1575,18 @@
     }
 }
 
-void cpu_reset_interrupt(CPUState *env, int mask)
+void cpu_reset_interrupt(CPUOldState *env, int mask)
 {
     env->interrupt_request &= ~mask;
 }
 
-void cpu_exit(CPUState *env)
+void cpu_exit(CPUOldState *env)
 {
     env->exit_request = 1;
     cpu_unlink_tb(env);
 }
 
-const CPULogItem cpu_log_items[] = {
-    { CPU_LOG_TB_OUT_ASM, "out_asm",
-      "show generated host assembly code for each compiled TB" },
-    { CPU_LOG_TB_IN_ASM, "in_asm",
-      "show target assembly code for each compiled TB" },
-    { CPU_LOG_TB_OP, "op",
-      "show micro ops for each compiled TB" },
-    { CPU_LOG_TB_OP_OPT, "op_opt",
-      "show micro ops "
-#ifdef TARGET_I386
-      "before eflags optimization and "
-#endif
-      "after liveness analysis" },
-    { CPU_LOG_INT, "int",
-      "show interrupts/exceptions in short format" },
-    { CPU_LOG_EXEC, "exec",
-      "show trace before each executed TB (lots of logs)" },
-    { CPU_LOG_TB_CPU, "cpu",
-      "show CPU state before block translation" },
-#ifdef TARGET_I386
-    { CPU_LOG_PCALL, "pcall",
-      "show protected mode far calls/returns/exceptions" },
-    { CPU_LOG_RESET, "cpu_reset",
-      "show CPU state before CPU resets" },
-#endif
-#ifdef DEBUG_IOPORT
-    { CPU_LOG_IOPORT, "ioport",
-      "show all i/o ports accesses" },
-#endif
-    { 0, NULL, NULL },
-};
-
-static int cmp1(const char *s1, int n, const char *s2)
-{
-    if (strlen(s2) != n)
-        return 0;
-    return memcmp(s1, s2, n) == 0;
-}
-
-/* takes a comma separated list of log masks. Return 0 if error. */
-int cpu_str_to_log_mask(const char *str)
-{
-    const CPULogItem *item;
-    int mask;
-    const char *p, *p1;
-
-    p = str;
-    mask = 0;
-    for(;;) {
-        p1 = strchr(p, ',');
-        if (!p1)
-            p1 = p + strlen(p);
-	if(cmp1(p,p1-p,"all")) {
-		for(item = cpu_log_items; item->mask != 0; item++) {
-			mask |= item->mask;
-		}
-	} else {
-        for(item = cpu_log_items; item->mask != 0; item++) {
-            if (cmp1(p, p1 - p, item->name))
-                goto found;
-        }
-        return 0;
-	}
-    found:
-        mask |= item->mask;
-        if (*p1 != ',')
-            break;
-        p = p1 + 1;
-    }
-    return mask;
-}
-
-void cpu_abort(CPUState *env, const char *fmt, ...)
+void cpu_abort(CPUOldState *env, const char *fmt, ...)
 {
     va_list ap;
     va_list ap2;
@@ -1732,17 +1626,17 @@
     abort();
 }
 
-CPUState *cpu_copy(CPUState *env)
+CPUArchState *cpu_copy(CPUOldState *env)
 {
-    CPUState *new_env = cpu_init(env->cpu_model_str);
-    CPUState *next_cpu = new_env->next_cpu;
+    CPUArchState *new_env = cpu_init(env->cpu_model_str);
+    CPUArchState *next_cpu = new_env->next_cpu;
     int cpu_index = new_env->cpu_index;
 #if defined(TARGET_HAS_ICE)
     CPUBreakpoint *bp;
     CPUWatchpoint *wp;
 #endif
 
-    memcpy(new_env, env, sizeof(CPUState));
+    memcpy(new_env, env, sizeof(CPUOldState));
 
     /* Preserve chaining and index. */
     new_env->next_cpu = next_cpu;
@@ -1768,121 +1662,11 @@
 
 #if !defined(CONFIG_USER_ONLY)
 
-static inline void tlb_flush_jmp_cache(CPUState *env, target_ulong addr)
-{
-    unsigned int i;
-
-    /* Discard jump cache entries for any tb which might potentially
-       overlap the flushed page.  */
-    i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
-    memset (&env->tb_jmp_cache[i], 0,
-            TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
-
-    i = tb_jmp_cache_hash_page(addr);
-    memset (&env->tb_jmp_cache[i], 0,
-            TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
-}
-
-/* NOTE: if flush_global is true, also flush global entries (not
-   implemented yet) */
-void tlb_flush(CPUState *env, int flush_global)
-{
-    int i;
-
-#if defined(DEBUG_TLB)
-    printf("tlb_flush:\n");
-#endif
-    /* must reset current TB so that interrupts cannot modify the
-       links while we are modifying them */
-    env->current_tb = NULL;
-
-    for(i = 0; i < CPU_TLB_SIZE; i++) {
-        int mmu_idx;
-        for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
-            env->tlb_table[mmu_idx][i].addr_read = -1;
-            env->tlb_table[mmu_idx][i].addr_write = -1;
-            env->tlb_table[mmu_idx][i].addr_code = -1;
-        }
-    }
-
-    memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
-
-#ifdef CONFIG_KQEMU
-    if (env->kqemu_enabled) {
-        kqemu_flush(env, flush_global);
-    }
-#endif
-    tlb_flush_count++;
-}
-
-static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
-{
-    if (addr == (tlb_entry->addr_read &
-                 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
-        addr == (tlb_entry->addr_write &
-                 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
-        addr == (tlb_entry->addr_code &
-                 (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        tlb_entry->addr_read = -1;
-        tlb_entry->addr_write = -1;
-        tlb_entry->addr_code = -1;
-    }
-}
-
-void tlb_flush_page(CPUState *env, target_ulong addr)
-{
-    int i;
-    int mmu_idx;
-
-#if defined(DEBUG_TLB)
-    printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr);
-#endif
-    /* must reset current TB so that interrupts cannot modify the
-       links while we are modifying them */
-    env->current_tb = NULL;
-
-    addr &= TARGET_PAGE_MASK;
-    i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++)
-        tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr);
-
-    tlb_flush_jmp_cache(env, addr);
-}
-
-/* update the TLBs so that writes to code in the virtual page 'addr'
-   can be detected */
-static void tlb_protect_code(ram_addr_t ram_addr)
-{
-    cpu_physical_memory_reset_dirty(ram_addr,
-                                    ram_addr + TARGET_PAGE_SIZE,
-                                    CODE_DIRTY_FLAG);
-}
-
-/* update the TLB so that writes in physical page 'phys_addr' are no longer
-   tested for self modifying code */
-static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
-                                    target_ulong vaddr)
-{
-    cpu_physical_memory_set_dirty_flags(ram_addr, CODE_DIRTY_FLAG);
-}
-
-static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
-                                         unsigned long start, unsigned long length)
-{
-    unsigned long addr;
-    if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
-        addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
-        if ((addr - start) < length) {
-            tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | TLB_NOTDIRTY;
-        }
-    }
-}
-
 /* Note: start and end must be within the same ram block.  */
 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
                                      int dirty_flags)
 {
-    CPUState *env;
+    CPUOldState *env;
     unsigned long length, start1;
     int i;
 
@@ -1954,7 +1738,7 @@
 }
 
 /* update the TLB according to the current state of the dirty bits */
-void cpu_tlb_update_dirty(CPUState *env)
+void cpu_tlb_update_dirty(CPUArchState *env)
 {
     int i;
     int mmu_idx;
@@ -1964,170 +1748,18 @@
     }
 }
 
-static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr)
-{
-    if (tlb_entry->addr_write == (vaddr | TLB_NOTDIRTY))
-        tlb_entry->addr_write = vaddr;
-}
-
-/* update the TLB corresponding to virtual page vaddr
-   so that it is no longer dirty */
-static inline void tlb_set_dirty(CPUState *env, target_ulong vaddr)
-{
-    int i;
-    int mmu_idx;
-
-    vaddr &= TARGET_PAGE_MASK;
-    i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++)
-        tlb_set_dirty1(&env->tlb_table[mmu_idx][i], vaddr);
-}
-
-/* add a new TLB entry. At most one entry for a given virtual address
-   is permitted. Return 0 if OK or 2 if the page could not be mapped
-   (can only happen in non SOFTMMU mode for I/O pages or pages
-   conflicting with the host address space). */
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
-                      hwaddr paddr, int prot,
-                      int mmu_idx, int is_softmmu)
-{
-    PhysPageDesc *p;
-    unsigned long pd;
-    unsigned int index;
-    target_ulong address;
-    target_ulong code_address;
-    ptrdiff_t addend;
-    int ret;
-    CPUTLBEntry *te;
-    CPUWatchpoint *wp;
-    hwaddr iotlb;
-
-    p = phys_page_find(paddr >> TARGET_PAGE_BITS);
-    if (!p) {
-        pd = IO_MEM_UNASSIGNED;
-    } else {
-        pd = p->phys_offset;
-    }
-#if defined(DEBUG_TLB)
-    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",
-           vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);
-#endif
-
-    ret = 0;
-    address = vaddr;
-    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
-        /* IO memory case (romd handled later) */
-        address |= TLB_MMIO;
-    }
-    addend = (ptrdiff_t)qemu_get_ram_ptr(pd & TARGET_PAGE_MASK);
-    if ((pd & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
-        /* Normal RAM.  */
-        iotlb = pd & TARGET_PAGE_MASK;
-        if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM)
-            iotlb |= IO_MEM_NOTDIRTY;
-        else
-            iotlb |= IO_MEM_ROM;
-    } else {
-        /* IO handlers are currently passed a physical address.
-           It would be nice to pass an offset from the base address
-           of that region.  This would avoid having to special case RAM,
-           and avoid full address decoding in every device.
-           We can't use the high bits of pd for this because
-           IO_MEM_ROMD uses these as a ram address.  */
-        iotlb = (pd & ~TARGET_PAGE_MASK);
-        if (p) {
-            iotlb += p->region_offset;
-        } else {
-            iotlb += paddr;
-        }
-    }
-
-    code_address = address;
-    /* Make accesses to pages with watchpoints go via the
-       watchpoint trap routines.  */
-    QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
-        if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) {
-            iotlb = io_mem_watch + paddr;
-            /* TODO: The memory case can be optimized by not trapping
-               reads of pages with a write breakpoint.  */
-            address |= TLB_MMIO;
-        }
-    }
-
-    index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    env->iotlb[mmu_idx][index] = iotlb - vaddr;
-    te = &env->tlb_table[mmu_idx][index];
-    te->addend = addend - vaddr;
-    if (prot & PAGE_READ) {
-        te->addr_read = address;
-    } else {
-        te->addr_read = -1;
-    }
-
-    if (prot & PAGE_EXEC) {
-        te->addr_code = code_address;
-    } else {
-        te->addr_code = -1;
-    }
-    if (prot & PAGE_WRITE) {
-        if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
-            (pd & IO_MEM_ROMD)) {
-            /* Write access calls the I/O callback.  */
-            te->addr_write = address | TLB_MMIO;
-        } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
-                   !cpu_physical_memory_is_dirty(pd)) {
-            te->addr_write = address | TLB_NOTDIRTY;
-        } else {
-            te->addr_write = address;
-        }
-    } else {
-        te->addr_write = -1;
-    }
-
-#ifdef CONFIG_MEMCHECK
-    /*
-     * If we have memchecker running, we need to make sure that page, cached
-     * into TLB as the result of this operation will comply with our requirement
-     * to cause __ld/__stx_mmu being called for memory access on the pages
-     * containing memory blocks that require access violation checks.
-     *
-     * We need to check with memory checker if we should invalidate this page
-     * iff:
-     *  - Memchecking is enabled.
-     *  - Page that's been cached belongs to the user space.
-     *  - Request to cache this page didn't come from softmmu. We're covered
-     *    there, because after page was cached here we will invalidate it in
-     *    the __ld/__stx_mmu wrapper.
-     *  - Cached page belongs to RAM, not I/O area.
-     *  - Page is cached for read, or write access.
-     */
-    if (memcheck_instrument_mmu && mmu_idx == 1 && !is_softmmu &&
-        (pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
-        (prot & (PAGE_READ | PAGE_WRITE)) &&
-        memcheck_is_checked(vaddr & TARGET_PAGE_MASK, TARGET_PAGE_SIZE)) {
-        if (prot & PAGE_READ) {
-            te->addr_read ^= TARGET_PAGE_MASK;
-        }
-        if (prot & PAGE_WRITE) {
-            te->addr_write ^= TARGET_PAGE_MASK;
-        }
-    }
-#endif  // CONFIG_MEMCHECK
-
-    return ret;
-}
 
 #else
 
-void tlb_flush(CPUState *env, int flush_global)
+void tlb_flush(CPUArchState *env, int flush_global)
 {
 }
 
-void tlb_flush_page(CPUState *env, target_ulong addr)
+void tlb_flush_page(CPUArchState *env, target_ulong addr)
 {
 }
 
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
+int tlb_set_page_exec(CPUArchState *env, target_ulong vaddr,
                       hwaddr paddr, int prot,
                       int mmu_idx, int is_softmmu)
 {
@@ -2326,7 +1958,7 @@
     return 0;
 }
 
-static inline void tlb_set_dirty(CPUState *env,
+static inline void tlb_set_dirty(CPUOldState *env,
                                  unsigned long addr, target_ulong vaddr)
 {
 }
@@ -2374,7 +2006,7 @@
 {
     hwaddr addr, end_addr;
     PhysPageDesc *p;
-    CPUState *env;
+    CPUOldState *env;
     ram_addr_t orig_size = size;
     subpage_t *subpage;
 
@@ -2935,7 +2567,7 @@
 /* Generate a debug exception if a watchpoint has been hit.  */
 static void check_watchpoint(int offset, int len_mask, int flags)
 {
-    CPUState *env = cpu_single_env;
+    CPUOldState *env = cpu_single_env;
     target_ulong pc, cs_base;
     TranslationBlock *tb;
     target_ulong vaddr;
@@ -3803,7 +3435,7 @@
 #endif
 
 /* virtual memory access for debug (includes writing to ROM) */
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
+int cpu_memory_rw_debug(CPUOldState *env, target_ulong addr,
                         void *buf, int len, int is_write)
 {
     int l;
@@ -3836,7 +3468,7 @@
 
 /* in deterministic execution mode, instructions doing device I/Os
    must be at the end of the TB */
-void cpu_io_recompile(CPUState *env, void *retaddr)
+void cpu_io_recompile(CPUArchState *env, void *retaddr)
 {
     TranslationBlock *tb;
     uint32_t n, cflags;
@@ -3947,23 +3579,4 @@
     tcg_dump_info(f, cpu_fprintf);
 }
 
-#define MMUSUFFIX _cmmu
-#define GETPC() NULL
-#define env cpu_single_env
-#define SOFTMMU_CODE_ACCESS
-
-#define SHIFT 0
-#include "exec/softmmu_template.h"
-
-#define SHIFT 1
-#include "exec/softmmu_template.h"
-
-#define SHIFT 2
-#include "exec/softmmu_template.h"
-
-#define SHIFT 3
-#include "exec/softmmu_template.h"
-
-#undef env
-
 #endif
diff --git a/gdbstub.c b/gdbstub.c
index 2173f5e..2078f11 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -274,9 +274,9 @@
     RS_SYSCALL,
 };
 typedef struct GDBState {
-    CPUState *c_cpu; /* current CPU for step/continue ops */
-    CPUState *g_cpu; /* current CPU for other ops */
-    CPUState *query_cpu; /* for q{f|s}ThreadInfo */
+    CPUOldState *c_cpu; /* current CPU for step/continue ops */
+    CPUOldState *g_cpu; /* current CPU for other ops */
+    CPUOldState *query_cpu; /* for q{f|s}ThreadInfo */
     enum RSState state; /* parsing state */
     char line_buf[MAX_PACKET_LENGTH];
     int line_buf_index;
@@ -512,7 +512,7 @@
 
 #define NUM_CORE_REGS (CPU_NB_REGS * 2 + 25)
 
-static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     if (n < CPU_NB_REGS) {
         GET_REGL(env->regs[gpr_map[n]]);
@@ -559,7 +559,7 @@
     return 0;
 }
 
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int i)
+static int cpu_gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int i)
 {
     uint32_t tmp;
 
@@ -637,7 +637,7 @@
 #define GDB_CORE_XML "power-core.xml"
 #endif
 
-static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     if (n < 32) {
         /* gprs */
@@ -674,7 +674,7 @@
     return 0;
 }
 
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     if (n < 32) {
         /* gprs */
@@ -735,7 +735,7 @@
 #define GET_REGA(val) GET_REGL(val)
 #endif
 
-static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     if (n < 8) {
         /* g0..g7 */
@@ -790,7 +790,7 @@
     return 0;
 }
 
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
 #if defined(TARGET_ABI32)
     abi_ulong tmp;
@@ -865,7 +865,7 @@
 #define NUM_CORE_REGS 26
 #define GDB_CORE_XML "arm-core.xml"
 
-static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     if (n < 16) {
         /* Core integer register.  */
@@ -892,7 +892,7 @@
     return 0;
 }
 
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     uint32_t tmp;
 
@@ -935,7 +935,7 @@
 
 #define GDB_CORE_XML "cf-core.xml"
 
-static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     if (n < 8) {
         /* D0-D7 */
@@ -954,7 +954,7 @@
     return 0;
 }
 
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     uint32_t tmp;
 
@@ -979,7 +979,7 @@
 
 #define NUM_CORE_REGS 73
 
-static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     if (n < 32) {
         GET_REGL(env->active_tc.gpr[n]);
@@ -1025,7 +1025,7 @@
 #define RESTORE_ROUNDING_MODE \
     set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], &env->active_fpu.fp_status)
 
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     target_ulong tmp;
 
@@ -1081,7 +1081,7 @@
 
 #define NUM_CORE_REGS 59
 
-static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     if (n < 8) {
         if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
@@ -1115,7 +1115,7 @@
     return 0;
 }
 
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     uint32_t tmp;
 
@@ -1161,7 +1161,7 @@
 
 #define NUM_CORE_REGS (32 + 5)
 
-static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     if (n < 32) {
 	GET_REG32(env->regs[n]);
@@ -1171,7 +1171,7 @@
     return 0;
 }
 
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     uint32_t tmp;
 
@@ -1191,7 +1191,7 @@
 
 #define NUM_CORE_REGS 49
 
-static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     uint8_t srs;
 
@@ -1218,7 +1218,7 @@
     return 0;
 }
 
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     uint32_t tmp;
 
@@ -1251,7 +1251,7 @@
 
 #define NUM_CORE_REGS 65
 
-static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     if (n < 31) {
        GET_REGL(env->ir[n]);
@@ -1278,7 +1278,7 @@
     return 0;
 }
 
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     target_ulong tmp;
     tmp = ldtul_p(mem_buf);
@@ -1301,12 +1301,12 @@
 
 #define NUM_CORE_REGS 0
 
-static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     return 0;
 }
 
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+static int cpu_gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int n)
 {
     return 0;
 }
@@ -1381,7 +1381,7 @@
 }
 #endif
 
-static int gdb_read_register(CPUState *env, uint8_t *mem_buf, int reg)
+static int gdb_read_register(CPUOldState *env, uint8_t *mem_buf, int reg)
 {
     GDBRegisterState *r;
 
@@ -1396,7 +1396,7 @@
     return 0;
 }
 
-static int gdb_write_register(CPUState *env, uint8_t *mem_buf, int reg)
+static int gdb_write_register(CPUOldState *env, uint8_t *mem_buf, int reg)
 {
     GDBRegisterState *r;
 
@@ -1417,7 +1417,7 @@
    gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
  */
 
-void gdb_register_coprocessor(CPUState * env,
+void gdb_register_coprocessor(CPUOldState * env,
                              gdb_reg_cb get_reg, gdb_reg_cb set_reg,
                              int num_regs, const char *xml, int g_pos)
 {
@@ -1461,7 +1461,7 @@
 
 static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
 {
-    CPUState *env;
+    CPUOldState *env;
     int err = 0;
 
     if (kvm_enabled())
@@ -1495,7 +1495,7 @@
 
 static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
 {
-    CPUState *env;
+    CPUOldState *env;
     int err = 0;
 
     if (kvm_enabled())
@@ -1528,7 +1528,7 @@
 
 static void gdb_breakpoint_remove_all(void)
 {
-    CPUState *env;
+    CPUOldState *env;
 
     if (kvm_enabled()) {
         kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
@@ -1568,7 +1568,7 @@
 #endif
 }
 
-static inline int gdb_id(CPUState *env)
+static inline int gdb_id(CPUOldState *env)
 {
 #if defined(CONFIG_USER_ONLY) && defined(USE_NPTL)
     return env->host_tid;
@@ -1577,9 +1577,9 @@
 #endif
 }
 
-static CPUState *find_cpu(uint32_t thread_id)
+static CPUOldState *find_cpu(uint32_t thread_id)
 {
-    CPUState *env;
+    CPUOldState *env;
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
         if (gdb_id(env) == thread_id) {
@@ -1592,7 +1592,7 @@
 
 static int gdb_handle_packet(GDBState *s, const char *line_buf)
 {
-    CPUState *env;
+    CPUOldState *env;
     const char *p;
     uint32_t thread;
     int ch, reg_size, type, res;
@@ -1948,7 +1948,7 @@
     return RS_IDLE;
 }
 
-void gdb_set_stop_cpu(CPUState *env)
+void gdb_set_stop_cpu(CPUOldState *env)
 {
     gdbserver_state->c_cpu = env;
     gdbserver_state->g_cpu = env;
@@ -1958,7 +1958,7 @@
 static void gdb_vm_state_change(void *opaque, int running, int reason)
 {
     GDBState *s = gdbserver_state;
-    CPUState *env = s->c_cpu;
+    CPUOldState *env = s->c_cpu;
     char buf[256];
     const char *type;
     int ret;
@@ -2157,7 +2157,7 @@
 }
 
 int
-gdb_handlesig (CPUState *env, int sig)
+gdb_handlesig (CPUOldState *env, int sig)
 {
   GDBState *s;
   char buf[256];
@@ -2206,7 +2206,7 @@
 }
 
 /* Tell the remote gdb that the process has exited.  */
-void gdb_exit(CPUState *env, int code)
+void gdb_exit(CPUOldState *env, int code)
 {
   GDBState *s;
   char buf[4];
@@ -2220,7 +2220,7 @@
 }
 
 /* Tell the remote gdb that the process has exited due to SIG.  */
-void gdb_signalled(CPUState *env, int sig)
+void gdb_signalled(CPUOldState *env, int sig)
 {
   GDBState *s;
   char buf[4];
@@ -2253,7 +2253,7 @@
 
     /* set short latency */
     val = 1;
-    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
+    qemu_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
 
     s = g_malloc0(sizeof(GDBState));
     s->c_cpu = first_cpu;
@@ -2279,7 +2279,7 @@
 
     /* allow fast reuse */
     val = 1;
-    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
+    qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
 
     sockaddr.sin_family = AF_INET;
     sockaddr.sin_port = htons(port);
@@ -2308,7 +2308,7 @@
 }
 
 /* Disable gdb stub for child processes.  */
-void gdbserver_fork(CPUState *env)
+void gdbserver_fork(CPUOldState *env)
 {
     GDBState *s = gdbserver_state;
     if (gdbserver_fd < 0 || s->fd < 0)
diff --git a/hw/android/android_arm.c b/hw/android/android_arm.c
index 66c784b..ff0e569 100644
--- a/hw/android/android_arm.c
+++ b/hw/android/android_arm.c
@@ -66,7 +66,7 @@
     const char *initrd_filename,
     const char *cpu_model)
 {
-    CPUState *env;
+    CPUARMState *env;
     qemu_irq *cpu_pic;
     qemu_irq *goldfish_pic;
     int i;
@@ -138,22 +138,11 @@
     goldfish_add_device_no_io(&nand_device);
     nand_dev_init(nand_device.base);
 #endif
-#ifdef CONFIG_TRACE
-    extern const char *trace_filename;
-    /* Init trace device if either tracing, or memory checking is enabled. */
-    if (trace_filename != NULL
 #ifdef CONFIG_MEMCHECK
-        || memcheck_enabled
-#endif  // CONFIG_MEMCHECK
-       ) {
+    if (memcheck_enabled) {
         trace_dev_init();
     }
-    if (trace_filename != NULL) {
-        D( "Trace file name is set to %s\n", trace_filename );
-    } else  {
-        D("Trace file name is not set\n");
-    }
-#endif
+#endif  // CONFIG_MEMCHECK
 
     pipe_dev_init();
 
diff --git a/hw/android/android_mips.c b/hw/android/android_mips.c
index c55ef76..a0a3649 100644
--- a/hw/android/android_mips.c
+++ b/hw/android/android_mips.c
@@ -71,7 +71,7 @@
 
 #define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fffffff)
 
-static void android_load_kernel(CPUState *env, int ram_size, const char *kernel_filename,
+static void android_load_kernel(CPUOldState *env, int ram_size, const char *kernel_filename,
               const char *kernel_cmdline, const char *initrd_filename)
 {
     int initrd_size;
@@ -156,7 +156,7 @@
     const char *initrd_filename,
     const char *cpu_model)
 {
-    CPUState *env;
+    CPUOldState *env;
     qemu_irq *goldfish_pic;
     int i;
     ram_addr_t ram_offset;
@@ -232,23 +232,12 @@
     goldfish_add_device_no_io(&nand_device);
     nand_dev_init(nand_device.base);
 #endif
-#ifdef CONFIG_TRACE
-    extern const char *trace_filename;
-    /* Init trace device if either tracing, or memory checking is enabled. */
-    if (trace_filename != NULL
+
 #ifdef CONFIG_MEMCHECK
-        || memcheck_enabled
-#endif  // CONFIG_MEMCHECK
-       ) {
+    if (memcheck_enabled) {
         trace_dev_init();
     }
-    if (trace_filename != NULL) {
-        D( "Trace file name is set to %s\n", trace_filename );
-    } else  {
-        D("Trace file name is not set\n");
-    }
-#endif
-
+#endif  // CONFIG_MEMCHECK
     pipe_dev_init();
 
 #if TEST_SWITCH
diff --git a/hw/android/goldfish/audio.c b/hw/android/goldfish/audio.c
index 05ca3a4..8c7cfd2 100644
--- a/hw/android/goldfish/audio.c
+++ b/hw/android/goldfish/audio.c
@@ -9,6 +9,7 @@
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 */
+#include "cpu.h"
 #include "migration/qemu-file.h"
 #include "hw/android/goldfish/device.h"
 #include "audio/audio.h"
diff --git a/hw/android/goldfish/battery.c b/hw/android/goldfish/battery.c
index 896362b..4797bbb 100644
--- a/hw/android/goldfish/battery.c
+++ b/hw/android/goldfish/battery.c
@@ -9,8 +9,10 @@
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 */
+#include "cpu.h"
 #include "migration/qemu-file.h"
 #include "hw/android/goldfish/device.h"
+#include "hw/hw.h"
 #include "hw/power_supply.h"
 
 
diff --git a/hw/android/goldfish/device.c b/hw/android/goldfish/device.c
index 87ce575..225f63c 100644
--- a/hw/android/goldfish/device.c
+++ b/hw/android/goldfish/device.c
@@ -9,6 +9,7 @@
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 */
+#include "cpu.h"
 #include "migration/qemu-file.h"
 #include "hw/arm/pic.h"
 #include "hw/android/goldfish/device.h"
diff --git a/hw/android/goldfish/events_device.c b/hw/android/goldfish/events_device.c
index 8a8720c..f11e7ab 100644
--- a/hw/android/goldfish/events_device.c
+++ b/hw/android/goldfish/events_device.c
@@ -9,11 +9,15 @@
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 */
+#include "hw/android/goldfish/device.h"
 #include "migration/qemu-file.h"
 #include "android/hw-events.h"
 #include "android/charmap.h"
 #include "android/globals.h"  /* for android_hw */
 #include "android/multitouch-screen.h"
+#include "exec/cpu-common.h"
+#include "exec/hwaddr.h"
+#include "hw/hw.h"
 #include "hw/irq.h"
 #include "android/user-events.h"
 #include "ui/console.h"
diff --git a/hw/android/goldfish/fb.c b/hw/android/goldfish/fb.c
index e9ccf4b..da7376f 100644
--- a/hw/android/goldfish/fb.c
+++ b/hw/android/goldfish/fb.c
@@ -9,11 +9,13 @@
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 */
+#include "cpu.h"
 #include "migration/qemu-file.h"
 #include "android/android.h"
 #include "android/utils/debug.h"
 #include "android/utils/duff.h"
 #include "hw/android/goldfish/device.h"
+#include "hw/hw.h"
 #include "ui/console.h"
 
 /* These values *must* match the platform definitions found under
diff --git a/hw/android/goldfish/interrupt.c b/hw/android/goldfish/interrupt.c
index 62d534a..b7738e6 100644
--- a/hw/android/goldfish/interrupt.c
+++ b/hw/android/goldfish/interrupt.c
@@ -13,6 +13,7 @@
 #include "hw/arm/pic.h"
 #include "hw/android/goldfish/device.h"
 #include "hw/irq.h"
+#include "hw/hw.h"
 
 enum {
     INTERRUPT_STATUS        = 0x00, // number of pending interrupts
diff --git a/hw/android/goldfish/mmc.c b/hw/android/goldfish/mmc.c
index 4d861bb..f58e36b 100644
--- a/hw/android/goldfish/mmc.c
+++ b/hw/android/goldfish/mmc.c
@@ -9,8 +9,10 @@
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 */
+#include "cpu.h"
 #include "migration/qemu-file.h"
 #include "hw/android/goldfish/device.h"
+#include "hw/hw.h"
 #include "hw/mmc.h"
 #include "hw/sd.h"
 #include "block/block.h"
diff --git a/hw/android/goldfish/nand.c b/hw/android/goldfish/nand.c
index d4983c5..072b504 100644
--- a/hw/android/goldfish/nand.c
+++ b/hw/android/goldfish/nand.c
@@ -13,6 +13,7 @@
 #include "nand_reg.h"
 #include "hw/android/goldfish/nand.h"
 #include "hw/android/goldfish/vmem.h"
+#include "hw/hw.h"
 #include "android/utils/tempfile.h"
 #include "android/qemu-debug.h"
 #include "android/android.h"
@@ -218,8 +219,8 @@
 
     lseek_ret = do_lseek(dev->fd, 0, SEEK_END);
     if (lseek_ret == -1) {
+      qemu_file_set_error(f, -errno);
       XLOG("%s EOF seek failed: %s\n", __FUNCTION__, strerror(errno));
-      qemu_file_set_error(f);
       return;
     }
     const uint64_t total_size = lseek_ret;
@@ -228,15 +229,15 @@
     /* copy all data from the stream to the stored image */
     lseek_ret = do_lseek(dev->fd, 0, SEEK_SET);
     if (lseek_ret == -1) {
+        qemu_file_set_error(f, -errno);
         XLOG("%s seek failed: %s\n", __FUNCTION__, strerror(errno));
-        qemu_file_set_error(f);
         return;
     }
     do {
         ret = do_read(dev->fd, buffer, buf_size);
         if (ret < 0) {
+            qemu_file_set_error(f, -errno);
             XLOG("%s read failed: %s\n", __FUNCTION__, strerror(errno));
-            qemu_file_set_error(f);
             return;
         }
         qemu_put_buffer(f, buffer, ret);
diff --git a/hw/android/goldfish/pipe.c b/hw/android/goldfish/pipe.c
index 7f3dd90..5c2a64c 100644
--- a/hw/android/goldfish/pipe.c
+++ b/hw/android/goldfish/pipe.c
@@ -966,7 +966,7 @@
 {
     Pipe** lookup = pipe_list_findp_channel(&dev->pipes, dev->channel);
     Pipe*  pipe   = *lookup;
-    CPUState* env = cpu_single_env;
+    CPUOldState* env = cpu_single_env;
 
     /* Check that we're referring a known pipe channel */
     if (command != PIPE_CMD_OPEN && pipe == NULL) {
diff --git a/hw/android/goldfish/switch.c b/hw/android/goldfish/switch.c
index 355f88a..5f5eaae 100644
--- a/hw/android/goldfish/switch.c
+++ b/hw/android/goldfish/switch.c
@@ -12,6 +12,7 @@
 #include "migration/qemu-file.h"
 #include "hw/android/goldfish/device.h"
 #include "hw/android/goldfish/vmem.h"
+#include "hw/hw.h"
 
 enum {
     SW_NAME_LEN     = 0x00,
diff --git a/hw/android/goldfish/trace.c b/hw/android/goldfish/trace.c
index 364e827..7cc4347 100644
--- a/hw/android/goldfish/trace.c
+++ b/hw/android/goldfish/trace.c
@@ -17,7 +17,6 @@
 #include "hw/android/goldfish/trace.h"
 #include "hw/android/goldfish/vmem.h"
 #include "sysemu/sysemu.h"
-#include "android/trace.h"
 #ifdef CONFIG_MEMCHECK
 #include "memcheck/memcheck.h"
 #include "memcheck/memcheck_util.h"
@@ -41,9 +40,11 @@
 #  define  DPID(...)  ((void)0)
 #endif
 
+// TODO(digit): Re-enable tracing some day?
+#define tracing 0
+
 extern void cpu_loop_exit(void);
 
-extern int tracing;
 extern const char *trace_filename;
 
 /* for execve */
@@ -73,7 +74,6 @@
     case TRACE_DEV_REG_SWITCH:  // context switch, switch to pid
         DPID("QEMU.trace: context switch tid=%u\n", value);
         if (trace_filename != NULL) {
-            trace_switch(value);
             D("QEMU.trace: kernel, context switch %u\n", value);
         }
 #ifdef CONFIG_MEMCHECK
@@ -93,7 +93,6 @@
     case TRACE_DEV_REG_FORK:    // fork, fork new pid
         DPID("QEMU.trace: fork (pid=%d tgid=%d value=%d)\n", pid, tgid, value);
         if (trace_filename != NULL) {
-            trace_fork(tgid, value);
             D("QEMU.trace: kernel, fork %u\n", value);
         }
 #ifdef CONFIG_MEMCHECK
@@ -105,7 +104,6 @@
     case TRACE_DEV_REG_CLONE:    // fork, clone new pid (i.e. thread)
         DPID("QEMU.trace: clone (pid=%d tgid=%d value=%d)\n", pid, tgid, value);
         if (trace_filename != NULL) {
-            trace_clone(tgid, value);
             D("QEMU.trace: kernel, clone %u\n", value);
         }
 #ifdef CONFIG_MEMCHECK
@@ -126,7 +124,6 @@
     case TRACE_DEV_REG_EXECVE_EXEPATH:  // init exec, path of EXE
         vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
         if (trace_filename != NULL) {
-            trace_init_exec(vstart, vend, eoff, exec_path);
             D("QEMU.trace: kernel, init exec [%lx,%lx]@%lx [%s]\n",
               vstart, vend, eoff, exec_path);
         }
@@ -148,7 +145,7 @@
     case TRACE_DEV_REG_CMDLINE:         // execve, process cmdline
         safe_memory_rw_debug(cpu_single_env, value, (uint8_t*)exec_arg, cmdlen, 0);
         if (trace_filename != NULL) {
-            trace_execve(exec_arg, cmdlen);
+            D("QEMU.trace: kernel, execve [%.*s]\n", cmdlen, exec_arg);
         }
 #ifdef CONFIG_MEMCHECK
         if (memcheck_enabled) {
@@ -169,7 +166,6 @@
     case TRACE_DEV_REG_EXIT:            // exit, exit current process with exit code
         DPID("QEMU.trace: exit tid=%u\n", value);
         if (trace_filename != NULL) {
-            trace_exit(value);
             D("QEMU.trace: kernel, exit %x\n", value);
         }
 #ifdef CONFIG_MEMCHECK
@@ -188,7 +184,6 @@
             exec_path[len - 1] = 0;
         }
         if (trace_filename != NULL) {
-            trace_name(exec_path);
             D("QEMU.trace: kernel, name %s\n", exec_path);
         }
         break;
@@ -196,7 +191,6 @@
         vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
         DPID("QEMU.trace: mmap exe=%s\n", exec_path);
         if (trace_filename != NULL) {
-            trace_mmap(vstart, vend, eoff, exec_path);
             D("QEMU.trace: kernel, mmap [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, exec_path);
         }
 #ifdef CONFIG_MEMCHECK
@@ -224,7 +218,6 @@
         vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
         DPID("QEMU.trace: tgid=%d pid=%d name=%s\n", tgid, pid, exec_path);
         if (trace_filename != NULL) {
-            trace_init_name(tgid, pid, exec_path);
             D("QEMU.trace: kernel, init name %u [%s]\n", pid, exec_path);
         }
         exec_path[0] = 0;
@@ -236,14 +229,12 @@
     case TRACE_DEV_REG_DYN_SYM:         // add dynamic symbol
         vstrcpy(value, exec_arg, CLIENT_PAGE_SIZE);
         if (trace_filename != NULL) {
-            trace_dynamic_symbol_add(dsaddr, exec_arg);
             D("QEMU.trace: dynamic symbol %lx:%s\n", dsaddr, exec_arg);
         }
         exec_arg[0] = 0;
         break;
     case TRACE_DEV_REG_REMOVE_ADDR:         // remove dynamic symbol addr
         if (trace_filename != NULL) {
-            trace_dynamic_symbol_remove(value);
             D("QEMU.trace: dynamic symbol remove %lx\n", dsaddr);
         }
         break;
@@ -261,11 +252,6 @@
         break;
 
     case TRACE_DEV_REG_STOP_EMU:        // stop the VM execution
-        if (trace_filename != NULL) {
-            // To ensure that the number of instructions executed in this
-            // block is correct, we pretend that there was an exception.
-            trace_exception(0);
-        }
         cpu_single_env->exception_index = EXCP_HLT;
         cpu_single_env->halted = 1;
         qemu_system_shutdown_request();
@@ -273,29 +259,12 @@
         break;
 
     case TRACE_DEV_REG_ENABLE:          // tracing enable: 0 = stop, 1 = start
-        if (value == 1) {
-            if (trace_filename != NULL) {
-                start_tracing();
-            }
-        }
-        else if (value == 0) {
-            if (trace_filename != NULL) {
-                stop_tracing();
-
-                // To ensure that the number of instructions executed in this
-                // block is correct, we pretend that there was an exception.
-                trace_exception(0);
-            }
-        }
         break;
 
     case TRACE_DEV_REG_UNMAP_START:
         unmap_start = value;
         break;
     case TRACE_DEV_REG_UNMAP_END:
-        if (trace_filename != NULL) {
-            trace_munmap(unmap_start, value);
-        }
 #ifdef CONFIG_MEMCHECK
         if (memcheck_enabled) {
             memcheck_unmap(unmap_start, value);
@@ -311,8 +280,8 @@
     case TRACE_DEV_REG_NATIVE_EXCEPTION:
         if (trace_filename != NULL) {
             if (tracing) {
-                int call_type = (offset - 4096) >> 2;
-                trace_interpreted_method(value, call_type);
+                int __attribute__((unused)) call_type = (offset - 4096) >> 2;
+                //trace_interpreted_method(value, call_type);
             }
         }
         break;
diff --git a/hw/android/goldfish/vmem.c b/hw/android/goldfish/vmem.c
index e676b61..95c6a05 100644
--- a/hw/android/goldfish/vmem.c
+++ b/hw/android/goldfish/vmem.c
@@ -26,7 +26,7 @@
 // and on AMD some of those ioctls (in particular KVM_GET_MSRS) are 10 to 100x
 // slower than on Intel chips.
 
-int safe_memory_rw_debug(CPUState *env, target_ulong addr, uint8_t *buf,
+int safe_memory_rw_debug(CPUOldState *env, target_ulong addr, uint8_t *buf,
                          int len, int is_write)
 {
 #ifdef TARGET_I386
@@ -37,7 +37,7 @@
     return cpu_memory_rw_debug(env, addr, buf, len, is_write);
 }
 
-hwaddr safe_get_phys_page_debug(CPUState *env, target_ulong addr)
+hwaddr safe_get_phys_page_debug(CPUOldState *env, target_ulong addr)
 {
 #ifdef TARGET_I386
     if (kvm_enabled()) {
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 0563fef..57af7a5 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -156,7 +156,7 @@
 qemu_irq *armv7m_init(int flash_size, int sram_size,
                       const char *kernel_filename, const char *cpu_model)
 {
-    CPUState *env;
+    CPUOldState *env;
     DeviceState *nvic;
     /* FIXME: make this local state.  */
     static qemu_irq pic[64];
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 846ddb1..b6ab870 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -44,7 +44,7 @@
 
 static void main_cpu_reset(void *opaque)
 {
-    CPUState *env = opaque;
+    CPUARMState *env = opaque;
 
     cpu_reset(env);
     if (env->boot_info)
@@ -184,7 +184,7 @@
     }
 }
 
-void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
+void arm_load_kernel(CPUARMState *env, struct arm_boot_info *info)
 {
     int kernel_size;
     int initrd_size;
diff --git a/hw/arm/pic.c b/hw/arm/pic.c
index 9ae4bca..d542a82 100644
--- a/hw/arm/pic.c
+++ b/hw/arm/pic.c
@@ -24,7 +24,7 @@
 /* Input 0 is IRQ and input 1 is FIQ.  */
 static void arm_pic_cpu_handler(void *opaque, int irq, int level)
 {
-    CPUState *env = (CPUState *)opaque;
+    CPUOldState *env = (CPUOldState *)opaque;
     switch (irq) {
     case ARM_PIC_CPU_IRQ:
         if (level)
@@ -43,7 +43,7 @@
     }
 }
 
-qemu_irq *arm_pic_init_cpu(CPUState *env)
+qemu_irq *arm_pic_init_cpu(CPUOldState *env)
 {
     return qemu_allocate_irqs(arm_pic_cpu_handler, env, 2);
 }
diff --git a/hw/block/cdrom.c b/hw/block/cdrom.c
index c457354..b938234 100644
--- a/hw/block/cdrom.c
+++ b/hw/block/cdrom.c
@@ -59,7 +59,7 @@
             q += 3;
         } else {
             /* sector 0 */
-            cpu_to_be32wu((uint32_t *)q, 0);
+            stl_be_p(q, 0);
             q += 4;
         }
     }
@@ -73,11 +73,11 @@
         lba_to_msf(q, nb_sectors);
         q += 3;
     } else {
-        cpu_to_be32wu((uint32_t *)q, nb_sectors);
+        stl_be_p(q, nb_sectors);
         q += 4;
     }
     len = q - buf;
-    cpu_to_be16wu((uint16_t *)buf, len - 2);
+    stw_be_p(buf, len - 2);
     return len;
 }
 
@@ -127,7 +127,7 @@
         lba_to_msf(q, nb_sectors);
         q += 3;
     } else {
-        cpu_to_be32wu((uint32_t *)q, nb_sectors);
+        stl_be_p(q, nb_sectors);
         q += 4;
     }
 
@@ -150,6 +150,6 @@
     }
 
     len = q - buf;
-    cpu_to_be16wu((uint16_t *)buf, len - 2);
+    stw_be_p(buf, len - 2);
     return len;
 }
diff --git a/hw/core/dma.c b/hw/core/dma.c
index 3c87547..5e9bc8d 100644
--- a/hw/core/dma.c
+++ b/hw/core/dma.c
@@ -21,6 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+#include "cpu.h"
+#include "exec/cpu-common.h"
 #include "hw/hw.h"
 #include "hw/isa/isa.h"
 
@@ -447,7 +449,7 @@
 /* request the emulator to transfer a new DMA memory block ASAP */
 void DMA_schedule(int nchan)
 {
-    CPUState *env = cpu_single_env;
+    CPUOldState *env = cpu_single_env;
     if (env)
         cpu_exit(env);
 }
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 8e74125..77f4774 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
  */
 
+#include "exec/cpu-common.h"
 #include "hw/sysbus.h"
 #include "sysemu/sysemu.h"
 #include "monitor/monitor.h"
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f11bd09..0536aed 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -112,21 +112,11 @@
 /* TSC handling */
 uint64_t cpu_get_tsc(CPUX86State *env)
 {
-    /* Note: when using kqemu, it is more logical to return the host TSC
-       because kqemu does not trap the RDTSC instruction for
-       performance reasons */
-#ifdef CONFIG_KQEMU
-    if (env->kqemu_enabled) {
-        return cpu_get_real_ticks();
-    } else
-#endif
-    {
-        return cpu_get_ticks();
-    }
+    return cpu_get_ticks();
 }
 
 /* SMM support */
-void cpu_smm_update(CPUState *env)
+void cpu_smm_update(CPUOldState *env)
 {
     if (i440fx_state && env == first_cpu)
         i440fx_set_smm(i440fx_state, (env->hflags >> HF_SMM_SHIFT) & 1);
@@ -134,7 +124,7 @@
 
 
 /* IRQ handling */
-int cpu_get_pic_interrupt(CPUState *env)
+int cpu_get_pic_interrupt(CPUOldState *env)
 {
     int intno;
 
@@ -155,7 +145,7 @@
 
 static void pic_irq_request(void *opaque, int irq, int level)
 {
-    CPUState *env = first_cpu;
+    CPUOldState *env = first_cpu;
 
     if (env->apic_state) {
         while (env) {
@@ -769,7 +759,7 @@
 
 static void main_cpu_reset(void *opaque)
 {
-    CPUState *env = opaque;
+    CPUOldState *env = opaque;
     cpu_reset(env);
 }
 
@@ -848,7 +838,7 @@
         return size;
 }
 
-int cpu_is_bsp(CPUState *env)
+int cpu_is_bsp(CPUOldState *env)
 {
 	return env->cpuid_apic_id == 0;
 }
@@ -887,7 +877,7 @@
     int bios_size, isa_bios_size, oprom_area_size;
     PCIBus *pci_bus;
     int __attribute__((unused)) piix3_devfn = -1;
-    CPUState *env;
+    CPUOldState *env;
     qemu_irq *cpu_irq;
     qemu_irq *i8259;
 #ifndef CONFIG_ANDROID
diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c
index 913b074..bdda698 100644
--- a/hw/i386/smbios.c
+++ b/hw/i386/smbios.c
@@ -13,7 +13,7 @@
 
 #include "sysemu/sysemu.h"
 #include "hw/i386/smbios.h"
-
+#include "hw/loader.h"
 /*
  * Structures shared with the BIOS
  */
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index c1342e99..114d21f 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -64,7 +64,7 @@
 #define MAX_APIC_WORDS 8
 
 typedef struct APICState {
-    CPUState *cpu_env;
+    CPUOldState *cpu_env;
     uint32_t apicbase;
     uint8_t id;
     uint8_t arb_id;
@@ -136,7 +136,7 @@
     return !!(tab[i] & mask);
 }
 
-static void apic_local_deliver(CPUState *env, int vector)
+static void apic_local_deliver(CPUOldState *env, int vector)
 {
     APICState *s = env->apic_state;
     uint32_t lvt = s->lvt[vector];
@@ -167,7 +167,7 @@
     }
 }
 
-void apic_deliver_pic_intr(CPUState *env, int level)
+void apic_deliver_pic_intr(CPUOldState *env, int level)
 {
     if (level)
         apic_local_deliver(env, APIC_LVT_LINT0);
@@ -276,7 +276,7 @@
                      trigger_mode);
 }
 
-void cpu_set_apic_base(CPUState *env, uint64_t val)
+void cpu_set_apic_base(CPUOldState *env, uint64_t val)
 {
     APICState *s = env->apic_state;
 #ifdef DEBUG_APIC
@@ -294,7 +294,7 @@
     }
 }
 
-uint64_t cpu_get_apic_base(CPUState *env)
+uint64_t cpu_get_apic_base(CPUOldState *env)
 {
     APICState *s = env->apic_state;
 #ifdef DEBUG_APIC
@@ -455,7 +455,7 @@
 }
 
 
-void apic_init_reset(CPUState *env)
+void apic_init_reset(CPUOldState *env)
 {
     APICState *s = env->apic_state;
     int i;
@@ -490,7 +490,7 @@
     cpu_interrupt(s->cpu_env, CPU_INTERRUPT_SIPI);
 }
 
-void apic_sipi(CPUState *env)
+void apic_sipi(CPUOldState *env)
 {
     APICState *s = env->apic_state;
 
@@ -554,7 +554,7 @@
                      trigger_mode);
 }
 
-int apic_get_interrupt(CPUState *env)
+int apic_get_interrupt(CPUOldState *env)
 {
     APICState *s = env->apic_state;
     int intno;
@@ -578,7 +578,7 @@
     return intno;
 }
 
-int apic_accept_pic_intr(CPUState *env)
+int apic_accept_pic_intr(CPUOldState *env)
 {
     APICState *s = env->apic_state;
     uint32_t lvt0;
@@ -666,7 +666,7 @@
 
 static uint32_t apic_mem_readl(void *opaque, hwaddr addr)
 {
-    CPUState *env;
+    CPUOldState *env;
     APICState *s;
     uint32_t val;
     int index;
@@ -747,7 +747,7 @@
 
 static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
 {
-    CPUState *env;
+    CPUOldState *env;
     APICState *s;
     int index;
 
@@ -933,7 +933,7 @@
     apic_mem_writel,
 };
 
-int apic_init(CPUState *env)
+int apic_init(CPUOldState *env)
 {
     APICState *s;
 
diff --git a/hw/mips/cputimer.c b/hw/mips/cputimer.c
index 1cf88ec..c97edb1 100644
--- a/hw/mips/cputimer.c
+++ b/hw/mips/cputimer.c
@@ -5,7 +5,7 @@
 #define TIMER_FREQ	100 * 1000 * 1000
 
 /* XXX: do not use a global */
-uint32_t cpu_mips_get_random (CPUState *env)
+uint32_t cpu_mips_get_random (CPUOldState *env)
 {
     static uint32_t lfsr = 1;
     static uint32_t prev_idx = 0;
@@ -20,7 +20,7 @@
 }
 
 /* MIPS R4K timer */
-uint32_t cpu_mips_get_count (CPUState *env)
+uint32_t cpu_mips_get_count (CPUOldState *env)
 {
     if (env->CP0_Cause & (1 << CP0Ca_DC))
         return env->CP0_Count;
@@ -30,7 +30,7 @@
                                TIMER_FREQ, get_ticks_per_sec());
 }
 
-static void cpu_mips_timer_update(CPUState *env)
+static void cpu_mips_timer_update(CPUOldState *env)
 {
     uint64_t now, next;
     uint32_t wait;
@@ -42,7 +42,7 @@
     qemu_mod_timer(env->timer, next);
 }
 
-void cpu_mips_store_count (CPUState *env, uint32_t count)
+void cpu_mips_store_count (CPUOldState *env, uint32_t count)
 {
     if (env->CP0_Cause & (1 << CP0Ca_DC))
         env->CP0_Count = count;
@@ -56,7 +56,7 @@
     }
 }
 
-void cpu_mips_store_compare (CPUState *env, uint32_t value)
+void cpu_mips_store_compare (CPUOldState *env, uint32_t value)
 {
     env->CP0_Compare = value;
     if (!(env->CP0_Cause & (1 << CP0Ca_DC)))
@@ -66,12 +66,12 @@
     qemu_irq_lower(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]);
 }
 
-void cpu_mips_start_count(CPUState *env)
+void cpu_mips_start_count(CPUOldState *env)
 {
     cpu_mips_store_count(env, env->CP0_Count);
 }
 
-void cpu_mips_stop_count(CPUState *env)
+void cpu_mips_stop_count(CPUOldState *env)
 {
     /* Store the current value */
     env->CP0_Count += (uint32_t)muldiv64(qemu_get_clock(vm_clock),
@@ -80,7 +80,7 @@
 
 static void mips_timer_cb (void *opaque)
 {
-    CPUState *env;
+    CPUOldState *env;
 
     env = opaque;
 #if 0
@@ -101,7 +101,7 @@
     qemu_irq_raise(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]);
 }
 
-void cpu_mips_clock_init (CPUState *env)
+void cpu_mips_clock_init (CPUOldState *env)
 {
     env->timer = qemu_new_timer_ns(vm_clock, &mips_timer_cb, env);
     env->CP0_Compare = 0;
diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c
index 48dffa2..3a6afbf 100644
--- a/hw/mips/mips_int.c
+++ b/hw/mips/mips_int.c
@@ -4,7 +4,7 @@
 
 /* Raise IRQ to CPU if necessary. It must be called every time the active
    IRQ may change */
-void cpu_mips_update_irq(CPUState *env)
+void cpu_mips_update_irq(CPUOldState *env)
 {
     if ((env->CP0_Status & (1 << CP0St_IE)) &&
         !(env->CP0_Status & (1 << CP0St_EXL)) &&
@@ -20,7 +20,7 @@
 
 static void cpu_mips_irq_request(void *opaque, int irq, int level)
 {
-    CPUState *env = (CPUState *)opaque;
+    CPUOldState *env = (CPUOldState *)opaque;
 
     if (irq < 0 || irq > 7)
         return;
@@ -33,7 +33,7 @@
     cpu_mips_update_irq(env);
 }
 
-void cpu_mips_irq_init_cpu(CPUState *env)
+void cpu_mips_irq_init_cpu(CPUOldState *env)
 {
     qemu_irq *qi;
     int i;
diff --git a/hw/mips/mips_pic.c b/hw/mips/mips_pic.c
index 321eb5a..7f6abab 100644
--- a/hw/mips/mips_pic.c
+++ b/hw/mips/mips_pic.c
@@ -16,7 +16,7 @@
 
 static void mips_cpu_irq_handler(void *opaque, int irq, int level)
 {
-    CPUState *env = (CPUState *)opaque;
+    CPUOldState *env = (CPUOldState *)opaque;
     int causebit;
 
     if (irq < 0 || 7 < irq)
@@ -33,7 +33,7 @@
     }
 }
 
-qemu_irq *mips_cpu_irq_init(CPUState *env)
+qemu_irq *mips_cpu_irq_init(CPUOldState *env)
 {
     return qemu_allocate_irqs(mips_cpu_irq_handler, env, 8);
 }
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index bf7d379..dba979e 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -71,7 +71,7 @@
 static int mips_qemu_iomemtype = 0;
 
 typedef struct ResetData {
-    CPUState *env;
+    CPUOldState *env;
     uint64_t vector;
 } ResetData;
 
@@ -148,7 +148,7 @@
 static void main_cpu_reset(void *opaque)
 {
     ResetData *s = (ResetData *)opaque;
-    CPUState *env = s->env;
+    CPUOldState *env = s->env;
 
     cpu_reset(env);
     env->active_tc.PC = s->vector;
@@ -165,7 +165,7 @@
     ram_addr_t ram_offset;
     ram_addr_t bios_offset;
     int bios_size;
-    CPUState *env;
+    CPUOldState *env;
     ResetData *reset_info;
     RTCState *rtc_state;
     int i;
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 69df0bf..98b15c1 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -514,7 +514,7 @@
     addr &= ~1; /* XXX: check exact behaviour if not even */
     if (addr < 32 ||
         (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
-        cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
+        stl_le_p(s->mem + addr, val);
     }
 }
 
@@ -544,7 +544,7 @@
     addr &= ~1; /* XXX: check exact behaviour if not even */
     if (addr < 32 ||
         (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
-        return le32_to_cpupu((uint32_t *)(s->mem + addr));
+        return ldl_le_p(s->mem + addr);
     } else {
         return 0xffffffff;
     }
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index a26ecd4..da637a6 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -21,6 +21,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+#include "cpu.h"
 #include "hw/hw.h"
 #include "sysemu/sysemu.h"
 #include "hw/isa/isa.h"
@@ -45,11 +46,11 @@
     FWCfgCallback callback;
 } FWCfgEntry;
 
-typedef struct _FWCfgState {
+struct FWCfgState {
     FWCfgEntry entries[2][FW_CFG_MAX_ENTRY];
     uint16_t cur_entry;
     uint16_t cur_offset;
-} FWCfgState;
+};
 
 static void fw_cfg_write(FWCfgState *s, uint8_t value)
 {
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index aabc41a..42ac3f7 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -21,6 +21,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+#include "cpu.h"
 #include "hw/hw.h"
 #include "hw/pci/pci.h"
 #include "monitor/monitor.h"
@@ -839,10 +840,10 @@
     return NULL;
 }
 
-typedef struct {
+struct PCIBridge {
     PCIDevice dev;
     PCIBus *bus;
-} PCIBridge;
+};
 
 static void pci_bridge_write_config(PCIDevice *d,
                              uint32_t address, uint32_t val, int len)
diff --git a/include/android/log-rotate.h b/include/android/log-rotate.h
new file mode 100644
index 0000000..5de7b3c
--- /dev/null
+++ b/include/android/log-rotate.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// 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.
+
+#ifndef ANDROID_LOG_ROTATE_H
+#define ANDROID_LOG_ROTATE_H
+
+// This header provides facilities to rotate misc QEMU log files
+// use in the Android emulator.
+
+// Setup log rotation, this installed a signal handler for SIGUSR1
+// which will trigger a log rotation at runtime.
+void qemu_log_rotation_init(void);
+
+// Perform log rotation if needed. For now, this must be called from
+// the main event loop, though a future implementation might schedule
+// a bottom-half handler instead to achieve the same result.
+void qemu_log_rotation_poll(void);
+
+#endif  // ANDROID_LOG_ROTATE_H
diff --git a/include/android/sockets.h b/include/android/sockets.h
index 6ce3041..47d6c91 100644
--- a/include/android/sockets.h
+++ b/include/android/sockets.h
@@ -339,6 +339,9 @@
 /* set socket in blocking mode */
 int  socket_set_blocking(int fd);
 
+/* set cork mode on Linux (if set, don't send partial frames). */
+int socket_set_cork(int fd, int value);
+
 /* disable the TCP Nagle algorithm for lower latency */
 int  socket_set_nodelay(int fd);
 
diff --git a/include/android/trace.h b/include/android/trace.h
deleted file mode 100644
index a492667..0000000
--- a/include/android/trace.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright (C) 2006-2007 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** 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.
-*/
-
-#ifndef TRACE_H
-#define TRACE_H
-
-#include <inttypes.h>
-#include "android/trace_common.h"
-
-extern uint64_t start_time, end_time;
-extern uint64_t elapsed_usecs;
-extern uint64_t Now();
-
-struct TranslationBlock;
-
-// The simulated time, in clock ticks, starting with one.
-extern uint64_t sim_time;
-extern uint64_t trace_static_bb_num(void);;
-
-// This variable == 1 if we are currently tracing, otherwise == 0.
-extern int tracing;
-extern int trace_all_addr;
-extern int trace_cache_miss;
-
-extern void start_tracing();
-extern void stop_tracing();
-extern void trace_init(const char *filename);
-extern void trace_bb_start(uint32_t bb_addr);
-extern void trace_add_insn(uint32_t insn, int is_thumb);
-extern void trace_bb_end();
-
-extern int get_insn_ticks_arm(uint32_t insn);
-extern int get_insn_ticks_thumb(uint32_t  insn);
-
-extern void trace_exception(uint32_t pc);
-extern void trace_bb_helper(uint64_t bb_num, struct TranslationBlock *tb);
-extern void trace_insn_helper();
-extern void sim_dcache_load(uint32_t addr);
-extern void sim_dcache_store(uint32_t addr, uint32_t val);
-extern void sim_dcache_swp(uint32_t addr);
-extern void trace_interpreted_method(uint32_t addr, int call_type);
-
-extern const char *trace_filename;
-extern int tracing;
-extern int trace_cache_miss;
-extern int trace_all_addr;
-
-// Trace process/thread operations
-extern void trace_switch(int pid);
-extern void trace_fork(int tgid, int pid);
-extern void trace_clone(int tgid, int pid);
-extern void trace_exit(int exitcode);
-extern void trace_name(char *name);
-
-#endif /* TRACE_H */
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index 296537a..803b6ef 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -184,6 +184,9 @@
 #define bfd_mach_sh5        0x50
   bfd_arch_alpha,      /* Dec Alpha */
 #define bfd_mach_alpha 1
+#define bfd_mach_alpha_ev4  0x10
+#define bfd_mach_alpha_ev5  0x20
+#define bfd_mach_alpha_ev6  0x30
   bfd_arch_arm,        /* Advanced Risc Machines ARM */
 #define bfd_mach_arm_unknown	0
 #define bfd_mach_arm_2		1
@@ -215,9 +218,12 @@
 #define bfd_mach_cris_v32      32
 #define bfd_mach_cris_v10_v32  1032
   bfd_arch_microblaze, /* Xilinx MicroBlaze.  */
+  bfd_arch_moxie,      /* The Moxie core.  */
   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
@@ -362,6 +368,7 @@
    target address.  Return number of bytes processed.  */
 typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *);
 
+int print_insn_tci(bfd_vma, disassemble_info*);
 int print_insn_big_mips         (bfd_vma, disassemble_info*);
 int print_insn_little_mips      (bfd_vma, disassemble_info*);
 int print_insn_i386             (bfd_vma, disassemble_info*);
@@ -386,6 +393,7 @@
 int print_insn_m88k             (bfd_vma, disassemble_info*);
 int print_insn_mn10200          (bfd_vma, disassemble_info*);
 int print_insn_mn10300          (bfd_vma, disassemble_info*);
+int print_insn_moxie            (bfd_vma, disassemble_info*);
 int print_insn_ns32k            (bfd_vma, disassemble_info*);
 int print_insn_big_powerpc      (bfd_vma, disassemble_info*);
 int print_insn_little_powerpc   (bfd_vma, disassemble_info*);
@@ -400,6 +408,7 @@
 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/include/disas/disas.h b/include/disas/disas.h
index 254963c..aac2531 100644
--- a/include/disas/disas.h
+++ b/include/disas/disas.h
@@ -4,11 +4,14 @@
 #include "qemu-common.h"
 
 #ifdef NEED_CPU_H
+#include "cpu.h"
+
 /* Disassemble this for me please... (debugging). */
 void disas(FILE *out, void *code, unsigned long size);
-void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
+void target_disas(FILE *out, CPUArchState *env, target_ulong code,
+                  target_ulong size, int flags);
 
-void monitor_disas(Monitor *mon, CPUState *env,
+void monitor_disas(Monitor *mon, CPUArchState *env,
                    target_ulong pc, int nb_insn, int is_physical, int flags);
 
 /* Look up symbol for debugging purpose.  Returns "" if unknown. */
diff --git a/include/elf.h b/include/elf.h
index ffcac7e..667af6f 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -106,6 +106,8 @@
 #define EM_H8S          48      /* Hitachi H8S     */
 #define EM_LATTICEMICO32 138    /* LatticeMico32 */
 
+#define EM_OPENRISC     92        /* OpenCores OpenRISC */
+
 #define EM_UNICORE32    110     /* UniCore32 */
 
 /*
@@ -125,6 +127,10 @@
 #define EM_MICROBLAZE      189
 #define EM_MICROBLAZE_OLD  0xBAAB
 
+#define EM_XTENSA   94      /* Tensilica Xtensa */
+
+#define EM_AARCH64  183
+
 /* This is the info that is needed to parse the dynamic section of the file */
 #define DT_NULL		0
 #define DT_NEEDED	1
@@ -214,6 +220,7 @@
 
 #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)
@@ -343,6 +350,21 @@
 #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
  */
@@ -389,6 +411,65 @@
 #define R_SPARC_5		44
 #define R_SPARC_6		45
 
+/* Bits present in AT_HWCAP for ARM.  */
+
+#define HWCAP_ARM_SWP           (1 << 0)
+#define HWCAP_ARM_HALF          (1 << 1)
+#define HWCAP_ARM_THUMB         (1 << 2)
+#define HWCAP_ARM_26BIT         (1 << 3)
+#define HWCAP_ARM_FAST_MULT     (1 << 4)
+#define HWCAP_ARM_FPA           (1 << 5)
+#define HWCAP_ARM_VFP           (1 << 6)
+#define HWCAP_ARM_EDSP          (1 << 7)
+#define HWCAP_ARM_JAVA          (1 << 8)
+#define HWCAP_ARM_IWMMXT        (1 << 9)
+#define HWCAP_ARM_CRUNCH        (1 << 10)
+#define HWCAP_ARM_THUMBEE       (1 << 11)
+#define HWCAP_ARM_NEON          (1 << 12)
+#define HWCAP_ARM_VFPv3         (1 << 13)
+#define HWCAP_ARM_VFPv3D16      (1 << 14)       /* also set for VFPv4-D16 */
+#define HWCAP_ARM_TLS           (1 << 15)
+#define HWCAP_ARM_VFPv4         (1 << 16)
+#define HWCAP_ARM_IDIVA         (1 << 17)
+#define HWCAP_ARM_IDIVT         (1 << 18)
+#define HWCAP_IDIV              (HWCAP_IDIVA | HWCAP_IDIVT)
+#define HWCAP_VFPD32            (1 << 19)       /* set if VFP has 32 regs */
+#define HWCAP_LPAE              (1 << 20)
+
+/* Bits present in AT_HWCAP for PowerPC.  */
+
+#define PPC_FEATURE_32                  0x80000000
+#define PPC_FEATURE_64                  0x40000000
+#define PPC_FEATURE_601_INSTR           0x20000000
+#define PPC_FEATURE_HAS_ALTIVEC         0x10000000
+#define PPC_FEATURE_HAS_FPU             0x08000000
+#define PPC_FEATURE_HAS_MMU             0x04000000
+#define PPC_FEATURE_HAS_4xxMAC          0x02000000
+#define PPC_FEATURE_UNIFIED_CACHE       0x01000000
+#define PPC_FEATURE_HAS_SPE             0x00800000
+#define PPC_FEATURE_HAS_EFP_SINGLE      0x00400000
+#define PPC_FEATURE_HAS_EFP_DOUBLE      0x00200000
+#define PPC_FEATURE_NO_TB               0x00100000
+#define PPC_FEATURE_POWER4              0x00080000
+#define PPC_FEATURE_POWER5              0x00040000
+#define PPC_FEATURE_POWER5_PLUS         0x00020000
+#define PPC_FEATURE_CELL                0x00010000
+#define PPC_FEATURE_BOOKE               0x00008000
+#define PPC_FEATURE_SMT                 0x00004000
+#define PPC_FEATURE_ICACHE_SNOOP        0x00002000
+#define PPC_FEATURE_ARCH_2_05           0x00001000
+#define PPC_FEATURE_PA6T                0x00000800
+#define PPC_FEATURE_HAS_DFP             0x00000400
+#define PPC_FEATURE_POWER6_EXT          0x00000200
+#define PPC_FEATURE_ARCH_2_06           0x00000100
+#define PPC_FEATURE_HAS_VSX             0x00000080
+
+#define PPC_FEATURE_PSERIES_PERFMON_COMPAT \
+                                        0x00000040
+
+#define PPC_FEATURE_TRUE_LE             0x00000002
+#define PPC_FEATURE_PPC_LE              0x00000001
+
 /* Bits present in AT_HWCAP, primarily for Sparc32.  */
 
 #define HWCAP_SPARC_FLUSH       1    /* CPU supports flush instruction. */
@@ -398,6 +479,20 @@
 #define HWCAP_SPARC_V9		16
 #define HWCAP_SPARC_ULTRA3	32
 
+/* Bits present in AT_HWCAP for s390.  */
+
+#define HWCAP_S390_ESAN3        1
+#define HWCAP_S390_ZARCH        2
+#define HWCAP_S390_STFLE        4
+#define HWCAP_S390_MSA          8
+#define HWCAP_S390_LDISP        16
+#define HWCAP_S390_EIMM         32
+#define HWCAP_S390_DFP          64
+#define HWCAP_S390_HPAGE        128
+#define HWCAP_S390_ETF3EH       256
+#define HWCAP_S390_HIGH_GPRS    512
+#define HWCAP_S390_TE           1024
+
 /*
  * 68k ELF relocation types
  */
@@ -520,6 +615,27 @@
 #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
@@ -575,6 +691,133 @@
 /* Keep this the last entry.  */
 #define R_ARM_NUM		256
 
+/* ARM Aarch64 relocation types */
+#define R_AARCH64_NONE                256 /* also accepts R_ARM_NONE (0) */
+/* static data relocations */
+#define R_AARCH64_ABS64               257
+#define R_AARCH64_ABS32               258
+#define R_AARCH64_ABS16               259
+#define R_AARCH64_PREL64              260
+#define R_AARCH64_PREL32              261
+#define R_AARCH64_PREL16              262
+/* static aarch64 group relocations */
+/* group relocs to create unsigned data value or address inline */
+#define R_AARCH64_MOVW_UABS_G0        263
+#define R_AARCH64_MOVW_UABS_G0_NC     264
+#define R_AARCH64_MOVW_UABS_G1        265
+#define R_AARCH64_MOVW_UABS_G1_NC     266
+#define R_AARCH64_MOVW_UABS_G2        267
+#define R_AARCH64_MOVW_UABS_G2_NC     268
+#define R_AARCH64_MOVW_UABS_G3        269
+/* group relocs to create signed data or offset value inline */
+#define R_AARCH64_MOVW_SABS_G0        270
+#define R_AARCH64_MOVW_SABS_G1        271
+#define R_AARCH64_MOVW_SABS_G2        272
+/* relocs to generate 19, 21, and 33 bit PC-relative addresses */
+#define R_AARCH64_LD_PREL_LO19        273
+#define R_AARCH64_ADR_PREL_LO21       274
+#define R_AARCH64_ADR_PREL_PG_HI21    275
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276
+#define R_AARCH64_ADD_ABS_LO12_NC     277
+#define R_AARCH64_LDST8_ABS_LO12_NC   278
+#define R_AARCH64_LDST16_ABS_LO12_NC  284
+#define R_AARCH64_LDST32_ABS_LO12_NC  285
+#define R_AARCH64_LDST64_ABS_LO12_NC  286
+#define R_AARCH64_LDST128_ABS_LO12_NC 299
+/* relocs for control-flow - all offsets as multiple of 4 */
+#define R_AARCH64_TSTBR14             279
+#define R_AARCH64_CONDBR19            280
+#define R_AARCH64_JUMP26              282
+#define R_AARCH64_CALL26              283
+/* group relocs to create pc-relative offset inline */
+#define R_AARCH64_MOVW_PREL_G0        287
+#define R_AARCH64_MOVW_PREL_G0_NC     288
+#define R_AARCH64_MOVW_PREL_G1        289
+#define R_AARCH64_MOVW_PREL_G1_NC     290
+#define R_AARCH64_MOVW_PREL_G2        291
+#define R_AARCH64_MOVW_PREL_G2_NC     292
+#define R_AARCH64_MOVW_PREL_G3        293
+/* group relocs to create a GOT-relative offset inline */
+#define R_AARCH64_MOVW_GOTOFF_G0      300
+#define R_AARCH64_MOVW_GOTOFF_G0_NC   301
+#define R_AARCH64_MOVW_GOTOFF_G1      302
+#define R_AARCH64_MOVW_GOTOFF_G1_NC   303
+#define R_AARCH64_MOVW_GOTOFF_G2      304
+#define R_AARCH64_MOVW_GOTOFF_G2_NC   305
+#define R_AARCH64_MOVW_GOTOFF_G3      306
+/* GOT-relative data relocs */
+#define R_AARCH64_GOTREL64            307
+#define R_AARCH64_GOTREL32            308
+/* GOT-relative instr relocs */
+#define R_AARCH64_GOT_LD_PREL19       309
+#define R_AARCH64_LD64_GOTOFF_LO15    310
+#define R_AARCH64_ADR_GOT_PAGE        311
+#define R_AARCH64_LD64_GOT_LO12_NC    312
+#define R_AARCH64_LD64_GOTPAGE_LO15   313
+/* General Dynamic TLS relocations */
+#define R_AARCH64_TLSGD_ADR_PREL21            512
+#define R_AARCH64_TLSGD_ADR_PAGE21            513
+#define R_AARCH64_TLSGD_ADD_LO12_NC           514
+#define R_AARCH64_TLSGD_MOVW_G1               515
+#define R_AARCH64_TLSGD_MOVW_G0_NC            516
+/* Local Dynamic TLS relocations */
+#define R_AARCH64_TLSLD_ADR_PREL21            517
+#define R_AARCH64_TLSLD_ADR_PAGE21            518
+#define R_AARCH64_TLSLD_ADD_LO12_NC           519
+#define R_AARCH64_TLSLD_MOVW_G1               520
+#define R_AARCH64_TLSLD_MOVW_G0_NC            521
+#define R_AARCH64_TLSLD_LD_PREL19             522
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2        523
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1        524
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC     525
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0        526
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC     527
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12       528
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12       529
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC    530
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12     531
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC  532
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12    533
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12    535
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12    537
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538
+/* initial exec TLS relocations */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1      539
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC   540
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21   541
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19    543
+/* local exec TLS relocations */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2         544
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1         545
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC      546
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0         547
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC      548
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12        549
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12        550
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC     551
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12      552
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC   553
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12     554
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC  555
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12     556
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC  557
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12     558
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC  559
+/* Dynamic Relocations */
+#define R_AARCH64_COPY         1024
+#define R_AARCH64_GLOB_DAT     1025
+#define R_AARCH64_JUMP_SLOT    1026
+#define R_AARCH64_RELATIVE     1027
+#define R_AARCH64_TLS_DTPREL64 1028
+#define R_AARCH64_TLS_DTPMOD64 1029
+#define R_AARCH64_TLS_TPREL64  1030
+#define R_AARCH64_TLS_DTPREL32 1031
+#define R_AARCH64_TLS_DTPMOD32 1032
+#define R_AARCH64_TLS_TPREL32  1033
+
 /* s390 relocations defined by the ABIs */
 #define R_390_NONE		0	/* No reloc.  */
 #define R_390_8			1	/* Direct 8 bit.  */
@@ -998,6 +1241,11 @@
 
 #define EI_NIDENT	16
 
+/* Special value for e_phnum.  This indicates that the real number of
+   program headers is too large to fit into e_phnum.  Instead the real
+   value is in the field sh_info of section 0.  */
+#define PN_XNUM         0xffff
+
 typedef struct elf32_hdr{
   unsigned char	e_ident[EI_NIDENT];
   Elf32_Half	e_type;
@@ -1173,11 +1421,20 @@
 
 /* Notes used in ET_CORE */
 #define NT_PRSTATUS	1
+#define NT_FPREGSET     2
 #define NT_PRFPREG	2
 #define NT_PRPSINFO	3
 #define NT_TASKSTRUCT	4
 #define NT_AUXV		6
 #define NT_PRXFPREG     0x46e62b7f      /* copied from gdb5.1/include/elf/common.h */
+#define NT_S390_PREFIX  0x305           /* s390 prefix register */
+#define NT_S390_CTRS    0x304           /* s390 control registers */
+#define NT_S390_TODPREG 0x303           /* s390 TOD programmable register */
+#define NT_S390_TODCMP  0x302           /* s390 TOD clock comparator register */
+#define NT_S390_TIMER   0x301           /* s390 timer register */
+#define NT_PPC_VMX       0x100          /* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE       0x101          /* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX       0x102          /* PowerPC VSX registers */
 
 
 /* Note header in a PT_NOTE section */
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index a922ebb..a943fcb 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -35,8 +35,6 @@
  * TARGET_WORDS_BIGENDIAN : same for target cpu
  */
 
-#include "fpu/softfloat.h"
-
 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
 #define BSWAP_NEEDED
 #endif
@@ -114,60 +112,6 @@
 #define bswaptls(s) bswap64s(s)
 #endif
 
-typedef union {
-    float32 f;
-    uint32_t l;
-} CPU_FloatU;
-
-/* NOTE: arm FPA is horrible as double 32 bit words are stored in big
-   endian ! */
-typedef union {
-    float64 d;
-#if defined(HOST_WORDS_BIGENDIAN) \
-    || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
-    struct {
-        uint32_t upper;
-        uint32_t lower;
-    } l;
-#else
-    struct {
-        uint32_t lower;
-        uint32_t upper;
-    } l;
-#endif
-    uint64_t ll;
-} CPU_DoubleU;
-
-#ifdef TARGET_SPARC
-typedef union {
-    float128 q;
-#if defined(HOST_WORDS_BIGENDIAN) \
-    || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
-    struct {
-        uint32_t upmost;
-        uint32_t upper;
-        uint32_t lower;
-        uint32_t lowest;
-    } l;
-    struct {
-        uint64_t upper;
-        uint64_t lower;
-    } ll;
-#else
-    struct {
-        uint32_t lowest;
-        uint32_t lower;
-        uint32_t upper;
-        uint32_t upmost;
-    } l;
-    struct {
-        uint64_t lower;
-        uint64_t upper;
-    } ll;
-#endif
-} CPU_QuadU;
-#endif
-
 /* CPU memory access without any memory or io remapping */
 
 /*
@@ -203,392 +147,8 @@
  *   user   : user mode access using soft MMU
  *   kernel : kernel mode access using soft MMU
  */
-static inline int ldub_p(const void *ptr)
-{
-    return *(uint8_t *)ptr;
-}
 
-static inline int ldsb_p(const void *ptr)
-{
-    return *(int8_t *)ptr;
-}
-
-static inline void stb_p(void *ptr, int v)
-{
-    *(uint8_t *)ptr = v;
-}
-
-/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
-   kernel handles unaligned load/stores may give better results, but
-   it is a system wide setting : bad */
-#if defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
-
-/* conservative code for little endian unaligned accesses */
-static inline int lduw_le_p(const void *ptr)
-{
-#ifdef _ARCH_PPC
-    int val;
-    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
-    return val;
-#else
-    const uint8_t *p = ptr;
-    return p[0] | (p[1] << 8);
-#endif
-}
-
-static inline int ldsw_le_p(const void *ptr)
-{
-#ifdef _ARCH_PPC
-    int val;
-    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
-    return (int16_t)val;
-#else
-    const uint8_t *p = ptr;
-    return (int16_t)(p[0] | (p[1] << 8));
-#endif
-}
-
-static inline int ldl_le_p(const void *ptr)
-{
-#ifdef _ARCH_PPC
-    int val;
-    __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
-    return val;
-#else
-    const uint8_t *p = ptr;
-    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
-#endif
-}
-
-static inline uint64_t ldq_le_p(const void *ptr)
-{
-    const uint8_t *p = ptr;
-    uint32_t v1, v2;
-    v1 = ldl_le_p(p);
-    v2 = ldl_le_p(p + 4);
-    return v1 | ((uint64_t)v2 << 32);
-}
-
-static inline void stw_le_p(void *ptr, int v)
-{
-#ifdef _ARCH_PPC
-    __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
-#else
-    uint8_t *p = ptr;
-    p[0] = v;
-    p[1] = v >> 8;
-#endif
-}
-
-static inline void stl_le_p(void *ptr, int v)
-{
-#ifdef _ARCH_PPC
-    __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
-#else
-    uint8_t *p = ptr;
-    p[0] = v;
-    p[1] = v >> 8;
-    p[2] = v >> 16;
-    p[3] = v >> 24;
-#endif
-}
-
-static inline void stq_le_p(void *ptr, uint64_t v)
-{
-    uint8_t *p = ptr;
-    stl_le_p(p, (uint32_t)v);
-    stl_le_p(p + 4, v >> 32);
-}
-
-/* float access */
-
-static inline float32 ldfl_le_p(const void *ptr)
-{
-    union {
-        float32 f;
-        uint32_t i;
-    } u;
-    u.i = ldl_le_p(ptr);
-    return u.f;
-}
-
-static inline void stfl_le_p(void *ptr, float32 v)
-{
-    union {
-        float32 f;
-        uint32_t i;
-    } u;
-    u.f = v;
-    stl_le_p(ptr, u.i);
-}
-
-static inline float64 ldfq_le_p(const void *ptr)
-{
-    CPU_DoubleU u;
-    u.l.lower = ldl_le_p(ptr);
-    u.l.upper = ldl_le_p(ptr + 4);
-    return u.d;
-}
-
-static inline void stfq_le_p(void *ptr, float64 v)
-{
-    CPU_DoubleU u;
-    u.d = v;
-    stl_le_p(ptr, u.l.lower);
-    stl_le_p(ptr + 4, u.l.upper);
-}
-
-#else
-
-static inline int lduw_le_p(const void *ptr)
-{
-    return *(uint16_t *)ptr;
-}
-
-static inline int ldsw_le_p(const void *ptr)
-{
-    return *(int16_t *)ptr;
-}
-
-static inline int ldl_le_p(const void *ptr)
-{
-    return *(uint32_t *)ptr;
-}
-
-static inline uint64_t ldq_le_p(const void *ptr)
-{
-    return *(uint64_t *)ptr;
-}
-
-static inline void stw_le_p(void *ptr, int v)
-{
-    *(uint16_t *)ptr = v;
-}
-
-static inline void stl_le_p(void *ptr, int v)
-{
-    *(uint32_t *)ptr = v;
-}
-
-static inline void stq_le_p(void *ptr, uint64_t v)
-{
-    *(uint64_t *)ptr = v;
-}
-
-/* float access */
-
-static inline float32 ldfl_le_p(const void *ptr)
-{
-    return *(float32 *)ptr;
-}
-
-static inline float64 ldfq_le_p(const void *ptr)
-{
-    return *(float64 *)ptr;
-}
-
-static inline void stfl_le_p(void *ptr, float32 v)
-{
-    *(float32 *)ptr = v;
-}
-
-static inline void stfq_le_p(void *ptr, float64 v)
-{
-    *(float64 *)ptr = v;
-}
-#endif
-
-#if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
-
-static inline int lduw_be_p(const void *ptr)
-{
-#if defined(__i386__)
-    int val;
-    asm volatile ("movzwl %1, %0\n"
-                  "xchgb %b0, %h0\n"
-                  : "=q" (val)
-                  : "m" (*(uint16_t *)ptr));
-    return val;
-#else
-    const uint8_t *b = ptr;
-    return ((b[0] << 8) | b[1]);
-#endif
-}
-
-static inline int ldsw_be_p(const void *ptr)
-{
-#if defined(__i386__)
-    int val;
-    asm volatile ("movzwl %1, %0\n"
-                  "xchgb %b0, %h0\n"
-                  : "=q" (val)
-                  : "m" (*(uint16_t *)ptr));
-    return (int16_t)val;
-#else
-    const uint8_t *b = ptr;
-    return (int16_t)((b[0] << 8) | b[1]);
-#endif
-}
-
-static inline int ldl_be_p(const void *ptr)
-{
-#if defined(__i386__) || defined(__x86_64__)
-    int val;
-    asm volatile ("movl %1, %0\n"
-                  "bswap %0\n"
-                  : "=r" (val)
-                  : "m" (*(uint32_t *)ptr));
-    return val;
-#else
-    const uint8_t *b = ptr;
-    return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
-#endif
-}
-
-static inline uint64_t ldq_be_p(const void *ptr)
-{
-    uint32_t a,b;
-    a = ldl_be_p(ptr);
-    b = ldl_be_p((uint8_t *)ptr + 4);
-    return (((uint64_t)a<<32)|b);
-}
-
-static inline void stw_be_p(void *ptr, int v)
-{
-#if defined(__i386__)
-    asm volatile ("xchgb %b0, %h0\n"
-                  "movw %w0, %1\n"
-                  : "=q" (v)
-                  : "m" (*(uint16_t *)ptr), "0" (v));
-#else
-    uint8_t *d = (uint8_t *) ptr;
-    d[0] = v >> 8;
-    d[1] = v;
-#endif
-}
-
-static inline void stl_be_p(void *ptr, int v)
-{
-#if defined(__i386__) || defined(__x86_64__)
-    asm volatile ("bswap %0\n"
-                  "movl %0, %1\n"
-                  : "=r" (v)
-                  : "m" (*(uint32_t *)ptr), "0" (v));
-#else
-    uint8_t *d = (uint8_t *) ptr;
-    d[0] = v >> 24;
-    d[1] = v >> 16;
-    d[2] = v >> 8;
-    d[3] = v;
-#endif
-}
-
-static inline void stq_be_p(void *ptr, uint64_t v)
-{
-    stl_be_p(ptr, v >> 32);
-    stl_be_p((uint8_t *)ptr + 4, v);
-}
-
-/* float access */
-
-static inline float32 ldfl_be_p(const void *ptr)
-{
-    union {
-        float32 f;
-        uint32_t i;
-    } u;
-    u.i = ldl_be_p(ptr);
-    return u.f;
-}
-
-static inline void stfl_be_p(void *ptr, float32 v)
-{
-    union {
-        float32 f;
-        uint32_t i;
-    } u;
-    u.f = v;
-    stl_be_p(ptr, u.i);
-}
-
-static inline float64 ldfq_be_p(const void *ptr)
-{
-    CPU_DoubleU u;
-    u.l.upper = ldl_be_p(ptr);
-    u.l.lower = ldl_be_p((uint8_t *)ptr + 4);
-    return u.d;
-}
-
-static inline void stfq_be_p(void *ptr, float64 v)
-{
-    CPU_DoubleU u;
-    u.d = v;
-    stl_be_p(ptr, u.l.upper);
-    stl_be_p((uint8_t *)ptr + 4, u.l.lower);
-}
-
-#else
-
-static inline int lduw_be_p(const void *ptr)
-{
-    return *(uint16_t *)ptr;
-}
-
-static inline int ldsw_be_p(const void *ptr)
-{
-    return *(int16_t *)ptr;
-}
-
-static inline int ldl_be_p(const void *ptr)
-{
-    return *(uint32_t *)ptr;
-}
-
-static inline uint64_t ldq_be_p(const void *ptr)
-{
-    return *(uint64_t *)ptr;
-}
-
-static inline void stw_be_p(void *ptr, int v)
-{
-    *(uint16_t *)ptr = v;
-}
-
-static inline void stl_be_p(void *ptr, int v)
-{
-    *(uint32_t *)ptr = v;
-}
-
-static inline void stq_be_p(void *ptr, uint64_t v)
-{
-    *(uint64_t *)ptr = v;
-}
-
-/* float access */
-
-static inline float32 ldfl_be_p(const void *ptr)
-{
-    return *(float32 *)ptr;
-}
-
-static inline float64 ldfq_be_p(const void *ptr)
-{
-    return *(float64 *)ptr;
-}
-
-static inline void stfl_be_p(void *ptr, float32 v)
-{
-    *(float32 *)ptr = v;
-}
-
-static inline void stfq_be_p(void *ptr, float64 v)
-{
-    *(float64 *)ptr = v;
-}
-
-#endif
-
-/* target CPU memory access functions */
+/* target-endianness CPU memory access functions */
 #if defined(TARGET_WORDS_BIGENDIAN)
 #define lduw_p(p) lduw_be_p(p)
 #define ldsw_p(p) ldsw_be_p(p)
@@ -619,7 +179,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 #include <assert.h>
-#include "qemu-types.h"
+#include "exec/user/abitypes.h"
 
 /* On some host systems the guest address space is reserved on the host.
  * This allows the guest address space to be offset to a convenient location.
@@ -636,22 +196,27 @@
 #endif
 
 /* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
-#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
+#define g2h(x) ((void *)((unsigned long)(target_ulong)(x) + GUEST_BASE))
 
 #if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
 #define h2g_valid(x) 1
 #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
 
-#define h2g(x) ({ \
+#define h2g_nocheck(x) ({ \
     unsigned long __ret = (unsigned long)(x) - GUEST_BASE; \
+    (abi_ulong)__ret; \
+})
+
+#define h2g(x) ({ \
     /* Check if given address fits target address space */ \
     assert(h2g_valid(x)); \
-    (abi_ulong)__ret; \
+    h2g_nocheck(x); \
 })
 
 #define saddr(x) g2h(x)
@@ -660,8 +225,8 @@
 #else /* !CONFIG_USER_ONLY */
 /* NOTE: we use double casts if pointers and target_ulong have
    different sizes */
-#define saddr(x) (uint8_t *)(long)(x)
-#define laddr(x) (uint8_t *)(long)(x)
+#define saddr(x) (uint8_t *)(intptr_t)(x)
+#define laddr(x) (uint8_t *)(intptr_t)(x)
 #endif
 
 #define ldub_raw(p) ldub_p(laddr((p)))
@@ -698,12 +263,34 @@
 #define stfl(p, v) stfl_raw(p, v)
 #define stfq(p, v) stfq_raw(p, v)
 
-#define ldub_code(p) ldub_raw(p)
-#define ldsb_code(p) ldsb_raw(p)
-#define lduw_code(p) lduw_raw(p)
-#define ldsw_code(p) ldsw_raw(p)
-#define ldl_code(p) ldl_raw(p)
-#define ldq_code(p) ldq_raw(p)
+#define cpu_ldub_code(env1, p) ldub_raw(p)
+#define cpu_ldsb_code(env1, p) ldsb_raw(p)
+#define cpu_lduw_code(env1, p) lduw_raw(p)
+#define cpu_ldsw_code(env1, p) ldsw_raw(p)
+#define cpu_ldl_code(env1, p) ldl_raw(p)
+#define cpu_ldq_code(env1, p) ldq_raw(p)
+
+#define cpu_ldub_data(env, addr) ldub_raw(addr)
+#define cpu_lduw_data(env, addr) lduw_raw(addr)
+#define cpu_ldsw_data(env, addr) ldsw_raw(addr)
+#define cpu_ldl_data(env, addr) ldl_raw(addr)
+#define cpu_ldq_data(env, addr) ldq_raw(addr)
+
+#define cpu_stb_data(env, addr, data) stb_raw(addr, data)
+#define cpu_stw_data(env, addr, data) stw_raw(addr, data)
+#define cpu_stl_data(env, addr, data) stl_raw(addr, data)
+#define cpu_stq_data(env, addr, data) stq_raw(addr, data)
+
+#define cpu_ldub_kernel(env, addr) ldub_raw(addr)
+#define cpu_lduw_kernel(env, addr) lduw_raw(addr)
+#define cpu_ldsw_kernel(env, addr) ldsw_raw(addr)
+#define cpu_ldl_kernel(env, addr) ldl_raw(addr)
+#define cpu_ldq_kernel(env, addr) ldq_raw(addr)
+
+#define cpu_stb_kernel(env, addr, data) stb_raw(addr, data)
+#define cpu_stw_kernel(env, addr, data) stw_raw(addr, data)
+#define cpu_stl_kernel(env, addr, data) stl_raw(addr, data)
+#define cpu_stq_kernel(env, addr, data) stq_raw(addr, data)
 
 #define ldub_kernel(p) ldub_raw(p)
 #define ldsb_kernel(p) ldsb_raw(p)
@@ -720,6 +307,13 @@
 #define stfl_kernel(p, v) stfl_raw(p, v)
 #define stfq_kernel(p, vt) stfq_raw(p, v)
 
+#define cpu_ldub_data(env, addr) ldub_raw(addr)
+#define cpu_lduw_data(env, addr) lduw_raw(addr)
+#define cpu_ldl_data(env, addr) ldl_raw(addr)
+
+#define cpu_stb_data(env, addr, data) stb_raw(addr, data)
+#define cpu_stw_data(env, addr, data) stw_raw(addr, data)
+#define cpu_stl_data(env, addr, data) stl_raw(addr, data)
 #endif /* defined(CONFIG_USER_ONLY) */
 
 /* page related stuff */
@@ -728,11 +322,10 @@
 #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
 #define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
 
-/* ??? These should be the larger of unsigned long and target_ulong.  */
-extern unsigned long qemu_real_host_page_size;
-extern unsigned long qemu_host_page_bits;
-extern unsigned long qemu_host_page_size;
-extern unsigned long qemu_host_page_mask;
+/* ??? These should be the larger of uintptr_t and target_ulong.  */
+extern uintptr_t qemu_real_host_page_size;
+extern uintptr_t qemu_host_page_size;
+extern uintptr_t qemu_host_page_mask;
 
 #define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
 
@@ -762,28 +355,20 @@
 int page_check_range(target_ulong start, target_ulong len, int flags);
 #endif
 
-CPUState *cpu_copy(CPUState *env);
-CPUState *qemu_get_cpu(int cpu);
+CPUArchState *cpu_copy(CPUArchState *env);
+CPUArchState *qemu_get_cpu(int cpu);
 
 #define CPU_DUMP_CODE 0x00010000
 
-void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
+void cpu_dump_state(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags);
-void cpu_dump_statistics(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
+void cpu_dump_statistics(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
                           int flags);
 
-void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
+void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
-extern CPUState *first_cpu;
-extern CPUState *cpu_single_env;
-
-#define CPU_INTERRUPT_TIMER  0x08 /* internal timer exception pending */
-#define CPU_INTERRUPT_SMI    0x40 /* (x86 only) SMI interrupt pending */
-#define CPU_INTERRUPT_VIRQ   0x100 /* virtual interrupt pending.  */
-#define CPU_INTERRUPT_NMI    0x200 /* NMI pending. */
-#define CPU_INTERRUPT_INIT   0x400 /* INIT pending. */
-#define CPU_INTERRUPT_SIPI   0x800 /* SIPI pending. */
-#define CPU_INTERRUPT_MCE    0x1000 /* (x86 only) MCE pending. */
+extern CPUArchState *first_cpu;
+extern CPUArchState *cpu_single_env;
 
 /* Flags for use in ENV->INTERRUPT_PENDING.
 
@@ -815,15 +400,16 @@
 #define CPU_INTERRUPT_TGT_EXT_4   0x1000
 
 /* Several target-specific internal interrupts.  These differ from the
-   preceeding target-specific interrupts in that they are intended to
+   preceding target-specific interrupts in that they are intended to
    originate from within the cpu itself, typically in response to some
    instruction being executed.  These, therefore, are not masked while
    single-stepping within the debugger.  */
 #define CPU_INTERRUPT_TGT_INT_0   0x0100
 #define CPU_INTERRUPT_TGT_INT_1   0x0400
 #define CPU_INTERRUPT_TGT_INT_2   0x0800
+#define CPU_INTERRUPT_TGT_INT_3   0x2000
 
-/* First unused bit: 0x2000.  */
+/* First unused bit: 0x4000.  */
 
 /* The set of all bits that should be masked when single-stepping.  */
 #define CPU_INTERRUPT_SSTEP_MASK \
@@ -834,12 +420,12 @@
      | CPU_INTERRUPT_TGT_EXT_3   \
      | CPU_INTERRUPT_TGT_EXT_4)
 
-void cpu_interrupt(CPUState *s, int mask);
-void cpu_reset_interrupt(CPUState *env, int mask);
+void cpu_interrupt(CPUOldState *s, int mask);
+void cpu_reset_interrupt(CPUOldState *env, int mask);
 
-void cpu_exit(CPUState *s);
+void cpu_exit(CPUOldState *s);
 
-int qemu_cpu_has_work(CPUState *env);
+int qemu_cpu_has_work(CPUOldState *env);
 
 /* Breakpoint/watchpoint flags */
 #define BP_MEM_READ           0x01
@@ -850,50 +436,26 @@
 #define BP_GDB                0x10
 #define BP_CPU                0x20
 
-int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
+int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
                           CPUBreakpoint **breakpoint);
-int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags);
-void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint);
-void cpu_breakpoint_remove_all(CPUState *env, int mask);
-int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
+int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags);
+void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint);
+void cpu_breakpoint_remove_all(CPUArchState *env, int mask);
+int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
                           int flags, CPUWatchpoint **watchpoint);
-int cpu_watchpoint_remove(CPUState *env, target_ulong addr,
+int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr,
                           target_ulong len, int flags);
-void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint);
-void cpu_watchpoint_remove_all(CPUState *env, int mask);
+void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint);
+void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
 
 #define SSTEP_ENABLE  0x1  /* Enable simulated HW single stepping */
 #define SSTEP_NOIRQ   0x2  /* Do not use IRQ while single stepping */
 #define SSTEP_NOTIMER 0x4  /* Do not Timers while single stepping */
 
-void cpu_single_step(CPUState *env, int enabled);
-void cpu_reset(CPUState *s);
-int cpu_is_stopped(CPUState *env);
-void run_on_cpu(CPUState *env, void (*func)(void *data), void *data);
-
-#define CPU_LOG_TB_OUT_ASM (1 << 0)
-#define CPU_LOG_TB_IN_ASM  (1 << 1)
-#define CPU_LOG_TB_OP      (1 << 2)
-#define CPU_LOG_TB_OP_OPT  (1 << 3)
-#define CPU_LOG_INT        (1 << 4)
-#define CPU_LOG_EXEC       (1 << 5)
-#define CPU_LOG_PCALL      (1 << 6)
-#define CPU_LOG_IOPORT     (1 << 7)
-#define CPU_LOG_TB_CPU     (1 << 8)
-#define CPU_LOG_RESET      (1 << 9)
-
-/* define log items */
-typedef struct CPULogItem {
-    int mask;
-    const char *name;
-    const char *help;
-} CPULogItem;
-
-extern const CPULogItem cpu_log_items[];
-
-void cpu_set_log(int log_flags);
-void cpu_set_log_filename(const char *filename);
-int cpu_str_to_log_mask(const char *str);
+void cpu_single_step(CPUOldState *env, int enabled);
+void cpu_reset(CPUOldState *s);
+int cpu_is_stopped(CPUOldState *env);
+void run_on_cpu(CPUOldState *env, void (*func)(void *data), void *data);
 
 /* IO ports API */
 #include "exec/ioport.h"
@@ -901,7 +463,7 @@
 /* Return the physical page corresponding to a virtual one. Use it
    only for debugging because no protection checks are done. Return -1
    if no page found. */
-hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
+hwaddr cpu_get_phys_page_debug(CPUOldState *env, target_ulong addr);
 
 /* memory API */
 
@@ -934,12 +496,6 @@
 
 /* physical memory access */
 
-/* MMIO pages are identified by a combination of an IO device index and
-   3 flags.  The ROMD code stores the page ram offset in iotlb entry, 
-   so only a limited number of ids are avaiable.  */
-
-#define IO_MEM_NB_ENTRIES  (1 << (TARGET_PAGE_BITS  - IO_MEM_SHIFT))
-
 /* Flags stored in the low bits of the TLB virtual address.  These are
    defined so that fast path ram access is all zeros.  */
 /* Zero if TLB entry is valid.  */
@@ -999,7 +555,7 @@
 
 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
                                      int dirty_flags);
-void cpu_tlb_update_dirty(CPUState *env);
+void cpu_tlb_update_dirty(CPUOldState *env);
 
 int cpu_physical_memory_set_dirty_tracking(int enable);
 
@@ -1035,10 +591,10 @@
 extern int64_t dev_time;
 #endif
 
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
+int cpu_memory_rw_debug(CPUOldState *env, target_ulong addr,
                         void *buf, int len, int is_write);
 
-void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
+void cpu_inject_x86_mce(CPUOldState *cenv, int bank, uint64_t status,
                         uint64_t mcg_status, uint64_t addr, uint64_t misc);
 
 #endif /* CPU_ALL_H */
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 0e58222..b45cfd7 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -1,13 +1,11 @@
 #ifndef CPU_COMMON_H
 #define CPU_COMMON_H 1
 
-/* CPU interfaces that are target indpendent.  */
+#include "qemu-common.h"
 
-#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__)
-#define WORDS_ALIGNED
-#endif
+/* CPU interfaces that are target independent.  */
 
-#ifdef TARGET_PHYS_ADDR_BITS
+#ifndef CONFIG_USER_ONLY
 #include "exec/hwaddr.h"
 #endif
 
@@ -18,13 +16,45 @@
 #include "qemu/bswap.h"
 #include "qemu/queue.h"
 
+/**
+ * CPUListState:
+ * @cpu_fprintf: Print function.
+ * @file: File to print to using @cpu_fprint.
+ *
+ * State commonly used for iterating over CPU models.
+ */
+typedef struct CPUListState {
+    fprintf_function cpu_fprintf;
+    FILE *file;
+} CPUListState;
+
 #if !defined(CONFIG_USER_ONLY)
 
+enum device_endian {
+    DEVICE_NATIVE_ENDIAN,
+    DEVICE_BIG_ENDIAN,
+    DEVICE_LITTLE_ENDIAN,
+};
+
 /* address in the RAM (different from a physical address) */
-typedef unsigned long ram_addr_t;
+#if defined(CONFIG_XEN_BACKEND)
+typedef uint64_t ram_addr_t;
+#  define RAM_ADDR_MAX UINT64_MAX
+#  define RAM_ADDR_FMT "%" PRIx64
+#else
+typedef uintptr_t ram_addr_t;
+#  define RAM_ADDR_MAX UINTPTR_MAX
+#  define RAM_ADDR_FMT "%" PRIxPTR
+#endif
 
 /* memory API */
 
+/* MMIO pages are identified by a combination of an IO device index and
+   3 flags.  The ROMD code stores the page ram offset in iotlb entry,
+   so only a limited number of ids are avaiable.  */
+
+#define IO_MEM_NB_ENTRIES  (1 << (TARGET_PAGE_BITS  - IO_MEM_SHIFT))
+
 typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
 typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
 
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 98ca890..3b784cf 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -190,7 +190,7 @@
     jmp_buf jmp_env;                                                    \
     int exception_index;                                                \
                                                                         \
-    CPUState *next_cpu; /* next CPU sharing TB cache */                 \
+    CPUOldState *next_cpu; /* next CPU sharing TB cache */                 \
     int cpu_index; /* CPU index (informative) */                        \
     uint32_t host_tid; /* host thread ID */                             \
     int numa_node; /* NUMA node this cpu is belonging to  */            \
diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h
new file mode 100644
index 0000000..efe0d9c
--- /dev/null
+++ b/include/exec/cputlb.h
@@ -0,0 +1,50 @@
+/*
+ *  Common CPU TLB handling
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef CPUTLB_H
+#define CPUTLB_H
+
+#if !defined(CONFIG_USER_ONLY)
+/* cputlb.c */
+void tlb_protect_code(ram_addr_t ram_addr);
+void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
+                             target_ulong vaddr);
+void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
+                           uintptr_t length);
+void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length);
+void tlb_set_dirty(CPUArchState *env, target_ulong vaddr);
+extern int tlb_flush_count;
+
+/* exec.c */
+void tb_flush_jmp_cache(CPUArchState *env, target_ulong addr);
+
+#ifndef CONFIG_ANDROID // TODO(digit)
+MemoryRegionSection *
+address_space_translate_for_iotlb(AddressSpace *as, hwaddr addr, hwaddr *xlat,
+                                  hwaddr *plen);
+hwaddr memory_region_section_get_iotlb(CPUArchState *env,
+                                       MemoryRegionSection *section,
+                                       target_ulong vaddr,
+                                       hwaddr paddr, hwaddr xlat,
+                                       int prot,
+                                       target_ulong *address);
+bool memory_region_is_unassigned(MemoryRegion *mr);
+#endif
+
+#endif
+#endif
diff --git a/include/exec/def-helper.h b/include/exec/def-helper.h
index 8a822c7..022a9ce 100644
--- a/include/exec/def-helper.h
+++ b/include/exec/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_env CPUState *
+#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
@@ -118,6 +125,10 @@
     DEF_HELPER_FLAGS_3(name, 0, ret, t1, t2, t3)
 #define DEF_HELPER_4(name, ret, t1, t2, t3, t4) \
     DEF_HELPER_FLAGS_4(name, 0, ret, t1, t2, t3, t4)
+#define DEF_HELPER_5(name, ret, t1, t2, t3, t4, t5) \
+    DEF_HELPER_FLAGS_5(name, 0, ret, t1, t2, t3, t4, t5)
+
+/* MAX_OPC_PARAM_IARGS must be set to n if last entry is DEF_HELPER_FLAGS_n. */
 
 #endif /* DEF_HELPER_H */
 
@@ -140,6 +151,10 @@
 dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
                                    dh_ctype(t4));
 
+#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
+                            dh_ctype(t4), dh_ctype(t5));
+
 #undef GEN_HELPER
 #define GEN_HELPER -1
 
@@ -203,6 +218,22 @@
   tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 4, args); \
 }
 
+#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
+    dh_arg_decl(t1, 1),  dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
+    dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
+{ \
+  TCGArg args[5]; \
+  int sizemask = 0; \
+  dh_sizemask(ret, 0); \
+  dh_arg(t1, 1); \
+  dh_arg(t2, 2); \
+  dh_arg(t3, 3); \
+  dh_arg(t4, 4); \
+  dh_arg(t5, 5); \
+  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 5, args); \
+}
+
 #undef GEN_HELPER
 #define GEN_HELPER -1
 
@@ -224,6 +255,9 @@
 #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
 DEF_HELPER_FLAGS_0(name, flags, ret)
 
+#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
+DEF_HELPER_FLAGS_0(name, flags, ret)
+
 #undef GEN_HELPER
 #define GEN_HELPER -1
 
@@ -235,6 +269,7 @@
 #undef DEF_HELPER_FLAGS_2
 #undef DEF_HELPER_FLAGS_3
 #undef DEF_HELPER_FLAGS_4
+#undef DEF_HELPER_FLAGS_5
 #undef GEN_HELPER
 
 #endif
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index cc5ae84..6822d44 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -21,6 +21,8 @@
 #define _EXEC_ALL_H_
 
 #include "qemu-common.h"
+#include "exec/cpu-common.h"
+#include "exec/cpu-all.h"
 
 /* allow to see translation results - the slowdown should be negligible, so we leave it */
 #define DEBUG_DISAS
@@ -40,6 +42,7 @@
 #define DISAS_UPDATE  2 /* cpu state was modified dynamically */
 #define DISAS_TB_JUMP 3 /* only pc was modified statically */
 
+struct TranslationBlock;
 typedef struct TranslationBlock TranslationBlock;
 
 /* XXX: make safe guess about sizes */
@@ -67,40 +70,46 @@
 
 #include "qemu/log.h"
 
-void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
-void gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
-void restore_state_to_opc(CPUState *env, struct TranslationBlock *tb, int pc_pos);
+void gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb);
+void gen_intermediate_code_pc(CPUArchState *env, struct TranslationBlock *tb);
+void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
+                          int pc_pos);
 
 unsigned long code_gen_max_block_size(void);
 void cpu_gen_init(void);
-int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
+int cpu_gen_code(CPUArchState *env, struct TranslationBlock *tb,
                  int *gen_code_size_ptr);
 int cpu_restore_state(struct TranslationBlock *tb,
-                      CPUState *env, unsigned long searched_pc);
-void cpu_resume_from_signal(CPUState *env1, void *puc);
-void cpu_io_recompile(CPUState *env, void *retaddr);
-TranslationBlock *tb_gen_code(CPUState *env,
+                      CPUArchState *env, unsigned long 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(CPUState *env);
+void cpu_exec_init(CPUArchState *env);
 void QEMU_NORETURN cpu_loop_exit(void);
 int page_unprotect(target_ulong address, unsigned long pc, void *puc);
 void tb_invalidate_phys_page_range(hwaddr start, hwaddr end,
                                    int is_cpu_write_access);
 void tb_invalidate_page_range(target_ulong start, target_ulong end);
-void tlb_flush_page(CPUState *env, target_ulong addr);
-void tlb_flush(CPUState *env, int flush_global);
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
+void tlb_flush_page(CPUArchState *env, target_ulong addr);
+void tlb_flush(CPUArchState *env, int flush_global);
+int tlb_set_page_exec(CPUArchState *env, target_ulong vaddr,
                       hwaddr paddr, int prot,
                       int mmu_idx, int is_softmmu);
-static inline int tlb_set_page(CPUState *env1, target_ulong vaddr,
-                               hwaddr paddr, int prot,
-                               int mmu_idx, int is_softmmu)
-{
-    if (prot & PAGE_READ)
-        prot |= PAGE_EXEC;
-    return tlb_set_page_exec(env1, vaddr, paddr, prot, mmu_idx, is_softmmu);
-}
+int tlb_set_page(CPUArchState *env1, target_ulong vaddr,
+                 hwaddr paddr, int prot,
+                 int mmu_idx, int is_softmmu);
+
+typedef struct PhysPageDesc {
+    /* offset in host memory of the page + io_index in the low bits */
+    ram_addr_t phys_offset;
+    ram_addr_t region_offset;
+} PhysPageDesc;
+
+PhysPageDesc *phys_page_find(hwaddr index);
+
+int io_mem_watch;
 
 #define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */
 
@@ -118,7 +127,10 @@
 #define CODE_GEN_AVG_BLOCK_SIZE 64
 #endif
 
-#if defined(_ARCH_PPC) || defined(__x86_64__) || defined(__arm__) || defined(__i386__)
+#if defined(__arm__) || defined(_ARCH_PPC) \
+    || defined(__x86_64__) || defined(__i386__) \
+    || defined(__sparc__) || defined(__aarch64__) \
+    || defined(CONFIG_TCG_INTERPRETER)
 #define USE_DIRECT_JUMP
 #endif
 
@@ -154,10 +166,7 @@
        jmp_first */
     struct TranslationBlock *jmp_next[2];
     struct TranslationBlock *jmp_first;
-#ifdef CONFIG_TRACE
-    struct BBRec *bb_rec;
-    uint64_t prev_time;
-#endif
+    uint32_t icount;
 
 #ifdef CONFIG_MEMCHECK
     /* Maps PCs in this translation block to corresponding PCs in guest address
@@ -170,8 +179,6 @@
     /* Number of pairs (pc_tb, pc_guest) in tpc2gpc array. */
     unsigned int    tpc2gpc_pairs;
 #endif  // CONFIG_MEMCHECK
-
-    uint32_t icount;
 };
 
 static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
@@ -250,7 +257,7 @@
 
 TranslationBlock *tb_alloc(target_ulong pc);
 void tb_free(TranslationBlock *tb);
-void tb_flush(CPUState *env);
+void tb_flush(CPUArchState *env);
 void tb_link_phys(TranslationBlock *tb,
                   target_ulong phys_pc, target_ulong phys_page2);
 void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr);
@@ -378,7 +385,7 @@
 #endif
 
 #if defined(CONFIG_USER_ONLY)
-static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr)
+static inline target_ulong get_phys_addr_code(CPUArchState *env1, target_ulong addr)
 {
     return addr;
 }
@@ -386,7 +393,7 @@
 /* NOTE: this function can trigger an exception */
 /* NOTE2: the returned address is not exactly the physical address: it
    is the offset relative to phys_ram_base */
-static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr)
+static inline target_ulong get_phys_addr_code(CPUArchState *env1, target_ulong addr)
 {
     int mmu_idx, page_index, pd;
     void *p;
@@ -411,11 +418,25 @@
 }
 #endif
 
-typedef void (CPUDebugExcpHandler)(CPUState *env);
+typedef void (CPUDebugExcpHandler)(CPUArchState *env);
 
 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
 
 /* vl.c */
 extern int singlestep;
 
+/* Deterministic execution requires that IO only be performed on the last
+   instruction of a TB so that interrupts take effect immediately.  */
+static inline int can_do_io(CPUArchState *env)
+{
+    if (!use_icount)
+        return 1;
+
+    /* If not executing code then assume we are ok.  */
+    if (!env->current_tb)
+        return 1;
+
+    return env->can_do_io != 0;
+}
+
 #endif
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 219abda..dd96c6c 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -11,22 +11,24 @@
 #define GDB_WATCHPOINT_ACCESS    4
 
 #ifdef NEED_CPU_H
-typedef void (*gdb_syscall_complete_cb)(CPUState *env,
+#include "cpu.h"
+
+typedef void (*gdb_syscall_complete_cb)(CPUOldState *env,
                                         target_ulong ret, target_ulong err);
 
 void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
 int use_gdb_syscalls(void);
-void gdb_set_stop_cpu(CPUState *env);
-void gdb_exit(CPUState *, int);
+void gdb_set_stop_cpu(CPUOldState *env);
+void gdb_exit(CPUOldState *, int);
 #ifdef CONFIG_USER_ONLY
 int gdb_queuesig (void);
-int gdb_handlesig (CPUState *, int);
-void gdb_signalled(CPUState *, int);
-void gdbserver_fork(CPUState *);
+int gdb_handlesig (CPUOldState *, int);
+void gdb_signalled(CPUOldState *, int);
+void gdbserver_fork(CPUOldState *);
 #endif
 /* Get or set a register.  Returns the size of the register.  */
-typedef int (*gdb_reg_cb)(CPUState *env, uint8_t *buf, int reg);
-void gdb_register_coprocessor(CPUState *env,
+typedef int (*gdb_reg_cb)(CPUOldState *env, uint8_t *buf, int reg);
+void gdb_register_coprocessor(CPUOldState *env,
                               gdb_reg_cb get_reg, gdb_reg_cb set_reg,
                               int num_regs, const char *xml, int g_pos);
 
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 9a668b3..14e0200 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -14,13 +14,13 @@
 
     icount_label = gen_new_label();
     count = tcg_temp_local_new_i32();
-    tcg_gen_ld_i32(count, cpu_env, offsetof(CPUState, icount_decr.u32));
+    tcg_gen_ld_i32(count, cpu_env, offsetof(CPUArchState, icount_decr.u32));
     /* This is a horrid hack to allow fixing up the value later.  */
     icount_arg = gen_opparam_ptr + 1;
     tcg_gen_subi_i32(count, count, 0xdeadbeef);
 
     tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label);
-    tcg_gen_st16_i32(count, cpu_env, offsetof(CPUState, icount_decr.u16.low));
+    tcg_gen_st16_i32(count, cpu_env, offsetof(CPUArchState, icount_decr.u16.low));
     tcg_temp_free_i32(count);
 }
 
@@ -36,13 +36,13 @@
 static inline void gen_io_start(void)
 {
     TCGv_i32 tmp = tcg_const_i32(1);
-    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, can_do_io));
+    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUArchState, can_do_io));
     tcg_temp_free_i32(tmp);
 }
 
 static inline void gen_io_end(void)
 {
     TCGv_i32 tmp = tcg_const_i32(0);
-    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, can_do_io));
+    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUArchState, can_do_io));
     tcg_temp_free_i32(tmp);
 }
diff --git a/include/exec/hax.h b/include/exec/hax.h
index 25ff5a2..c8cd9a2 100644
--- a/include/exec/hax.h
+++ b/include/exec/hax.h
@@ -13,21 +13,21 @@
 int hax_enabled(void);
 int hax_set_ramsize(uint64_t ramsize);
 int hax_init(int smp_cpus);
-int hax_init_vcpu(CPUState *env);
+int hax_init_vcpu(CPUOldState *env);
 /* Execute vcpu in non-root mode */
-int hax_vcpu_exec(CPUState *env);
+int hax_vcpu_exec(CPUOldState *env);
 /* Sync vcpu state with HAX driver */
 int hax_sync_vcpus(void);
-void hax_vcpu_sync_state(CPUState *env, int modified);
+void hax_vcpu_sync_state(CPUOldState *env, int modified);
 int hax_populate_ram(uint64_t va, uint32_t size);
 int hax_set_phys_mem(hwaddr start_addr,
                      ram_addr_t size, ram_addr_t phys_offset);
 /* Check if QEMU need emulate guest execution */
-int hax_vcpu_emulation_mode(CPUState *env);
-int hax_stop_emulation(CPUState *env);
-int hax_stop_translate(CPUState *env);
-int hax_arch_get_registers(CPUState *env);
-void hax_raise_event(CPUState *env);
+int hax_vcpu_emulation_mode(CPUOldState *env);
+int hax_stop_emulation(CPUOldState *env);
+int hax_stop_translate(CPUOldState *env);
+int hax_arch_get_registers(CPUOldState *env);
+void hax_raise_event(CPUOldState *env);
 void hax_reset_vcpu_state(void *opaque);
 
 #include "target-i386/hax-interface.h"
diff --git a/include/exec/hwaddr.h b/include/exec/hwaddr.h
index 9ccf56d..7c4a771 100644
--- a/include/exec/hwaddr.h
+++ b/include/exec/hwaddr.h
@@ -3,6 +3,12 @@
 #ifndef TARGPHYS_H
 #define TARGPHYS_H
 
+#include <stdint.h>
+
+#ifndef TARGET_PHYS_ADDR_BITS
+#define TARGET_PHYS_ADDR_BITS 32
+#endif
+
 #ifdef TARGET_PHYS_ADDR_BITS
 /* hwaddr is the type of a physical address (its size can
    be different from 'target_ulong').  */
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 8fa3ee6..b58caac 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -34,7 +34,7 @@
 #pragma GCC poison TARGET_PAGE_BITS
 #pragma GCC poison TARGET_PAGE_ALIGN
 
-#pragma GCC poison CPUState
+#pragma GCC poison CPUOldState
 #pragma GCC poison env
 
 #pragma GCC poison CPU_INTERRUPT_HARD
diff --git a/include/exec/softmmu-semi.h b/include/exec/softmmu-semi.h
index 79278cc..73f09aa 100644
--- a/include/exec/softmmu-semi.h
+++ b/include/exec/softmmu-semi.h
@@ -7,14 +7,14 @@
  * This code is licenced under the GPL
  */
 
-static inline uint32_t softmmu_tget32(CPUState *env, uint32_t addr)
+static inline uint32_t softmmu_tget32(CPUOldState *env, uint32_t addr)
 {
     uint32_t val;
 
     cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 0);
     return tswap32(val);
 }
-static inline uint32_t softmmu_tget8(CPUState *env, uint32_t addr)
+static inline uint32_t softmmu_tget8(CPUOldState *env, uint32_t addr)
 {
     uint8_t val;
 
@@ -26,7 +26,7 @@
 #define get_user_u8(arg, p) ({ arg = softmmu_tget8(env, p) ; 0; })
 #define get_user_ual(arg, p) get_user_u32(arg, p)
 
-static inline void softmmu_tput32(CPUState *env, uint32_t addr, uint32_t val)
+static inline void softmmu_tput32(CPUOldState *env, uint32_t addr, uint32_t val)
 {
     val = tswap32(val);
     cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 1);
@@ -34,7 +34,7 @@
 #define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
 #define put_user_ual(arg, p) put_user_u32(arg, p)
 
-static void *softmmu_lock_user(CPUState *env, uint32_t addr, uint32_t len,
+static void *softmmu_lock_user(CPUOldState *env, uint32_t addr, uint32_t len,
                                int copy)
 {
     uint8_t *p;
@@ -45,7 +45,7 @@
     return p;
 }
 #define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy)
-static char *softmmu_lock_user_string(CPUState *env, uint32_t addr)
+static char *softmmu_lock_user_string(CPUOldState *env, uint32_t addr)
 {
     char *p;
     char *s;
@@ -60,7 +60,7 @@
     return s;
 }
 #define lock_user_string(p) softmmu_lock_user_string(env, p)
-static void softmmu_unlock_user(CPUState *env, void *p, target_ulong addr,
+static void softmmu_unlock_user(CPUOldState *env, void *p, target_ulong addr,
                                 target_ulong len)
 {
     if (len)
diff --git a/include/hw/android/goldfish/device.h b/include/hw/android/goldfish/device.h
index 2f529b5..5d77e57 100644
--- a/include/hw/android/goldfish/device.h
+++ b/include/hw/android/goldfish/device.h
@@ -12,6 +12,9 @@
 #ifndef GOLDFISH_DEVICE_H
 #define GOLDFISH_DEVICE_H
 
+#include "config.h"
+#include "exec/cpu-common.h"
+
 struct goldfish_device {
     struct goldfish_device *next;
     struct goldfish_device *prev;
diff --git a/include/hw/android/goldfish/trace.h b/include/hw/android/goldfish/trace.h
index 3e92f3e..01c7338 100644
--- a/include/hw/android/goldfish/trace.h
+++ b/include/hw/android/goldfish/trace.h
@@ -13,6 +13,7 @@
 #define _TRACE_DEV_H_
 
 #include "hw/android/goldfish/device.h"
+#include "cpu.h"
 
 #define CLIENT_PAGE_SIZE        4096
 
diff --git a/include/hw/android/goldfish/vmem.h b/include/hw/android/goldfish/vmem.h
index 6be87d7..be7974d 100644
--- a/include/hw/android/goldfish/vmem.h
+++ b/include/hw/android/goldfish/vmem.h
@@ -12,14 +12,16 @@
 #ifndef GOLDFISH_VMEM_H
 #define GOLDFISH_VMEM_H
 
+#include "cpu.h"
+
 // Call these functions instead of cpu_memory_rw_debug and
 // cpu_get_phys_page_debug to ensure virtual address translation always works
 // properly, and efficently, under KVM.
 
-int safe_memory_rw_debug(CPUState *env, target_ulong addr, uint8_t *buf,
+int safe_memory_rw_debug(CPUOldState *env, target_ulong addr, uint8_t *buf,
                          int len, int is_write);
 
-hwaddr safe_get_phys_page_debug(CPUState *env, target_ulong addr);
+hwaddr safe_get_phys_page_debug(CPUOldState *env, target_ulong addr);
 
 
 #endif  /* GOLDFISH_VMEM_H */
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index ab7ed17..10f8414 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -11,10 +11,13 @@
 #ifndef ARM_MISC_H
 #define ARM_MISC_H 1
 
+#include "cpu.h"
+#include "hw/loader.h"
+
 /* The CPU is also modeled as an interrupt controller.  */
 #define ARM_PIC_CPU_IRQ 0
 #define ARM_PIC_CPU_FIQ 1
-qemu_irq *arm_pic_init_cpu(CPUState *env);
+qemu_irq *arm_pic_init_cpu(CPUOldState *env);
 
 /* armv7m.c */
 qemu_irq *armv7m_init(int flash_size, int sram_size,
@@ -37,7 +40,7 @@
     hwaddr initrd_size;
     hwaddr entry;
 };
-void arm_load_kernel(CPUState *env, struct arm_boot_info *info);
+void arm_load_kernel(CPUARMState *env, struct arm_boot_info *info);
 
 /* Multiplication factor to convert from system clock ticks to qemu timer
    ticks.  */
diff --git a/include/hw/arm/pic.h b/include/hw/arm/pic.h
index cde0d25..ab7ef65 100644
--- a/include/hw/arm/pic.h
+++ b/include/hw/arm/pic.h
@@ -14,12 +14,13 @@
 #ifndef ARM_INTERRUPT_H
 #define ARM_INTERRUPT_H 1
 
+#include "cpu.h"
 #include "hw/irq.h"
 
 /* The CPU is also modeled as an interrupt controller.  */
 #define ARM_PIC_CPU_IRQ 0
 #define ARM_PIC_CPU_FIQ 1
-qemu_irq *arm_pic_init_cpu(CPUState *env);
+qemu_irq *arm_pic_init_cpu(CPUOldState *env);
 
 #endif /* !ARM_INTERRUPT_H */
 
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
index f1608ca..e0b7612 100644
--- a/include/hw/arm/pxa.h
+++ b/include/hw/arm/pxa.h
@@ -9,6 +9,8 @@
 #ifndef PXA_H
 # define PXA_H			"hw/arm/pxa.h"
 
+#include "cpu.h"
+
 /* Interrupt numbers */
 # define PXA2XX_PIC_SSP3	0
 # define PXA2XX_PIC_USBH2	2
@@ -63,7 +65,7 @@
 # define PXA2XX_INTERNAL_SIZE	0x40000
 
 /* pxa2xx_pic.c */
-qemu_irq *pxa2xx_pic_init(hwaddr base, CPUState *env);
+qemu_irq *pxa2xx_pic_init(hwaddr base, CPUOldState *env);
 
 /* pxa2xx_timer.c */
 void pxa25x_timer_init(hwaddr base, qemu_irq *irqs);
@@ -72,7 +74,7 @@
 /* pxa2xx_gpio.c */
 typedef struct PXA2xxGPIOInfo PXA2xxGPIOInfo;
 PXA2xxGPIOInfo *pxa2xx_gpio_init(hwaddr base,
-                CPUState *env, qemu_irq *pic, int lines);
+                CPUOldState *env, qemu_irq *pic, int lines);
 qemu_irq *pxa2xx_gpio_in_get(PXA2xxGPIOInfo *s);
 void pxa2xx_gpio_out_set(PXA2xxGPIOInfo *s,
                 int line, qemu_irq handler);
@@ -128,7 +130,7 @@
 typedef struct PXA2xxFIrState PXA2xxFIrState;
 
 typedef struct {
-    CPUState *env;
+    CPUOldState *env;
     qemu_irq *pic;
     qemu_irq reset;
     PXA2xxDMAState *dma;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 8242af6..2077a7c 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -3,6 +3,8 @@
 #ifndef HW_BOARDS_H
 #define HW_BOARDS_H
 
+#include "exec/cpu-common.h"
+
 typedef void QEMUMachineInitFunc(ram_addr_t ram_size,
                                  const char *boot_device,
                                  const char *kernel_filename,
diff --git a/include/hw/hw.h b/include/hw/hw.h
index 45ef74e..82f9767 100644
--- a/include/hw/hw.h
+++ b/include/hw/hw.h
@@ -4,219 +4,12 @@
 
 #include "qemu-common.h"
 #include "hw/irq.h"
+#include "migration/qemu-file.h"
 
-#if defined(TARGET_PHYS_ADDRESS_SPACE_BITS) && !defined(NEED_CPU_H)
+#ifdef NEED_CPU_H
 #include "cpu.h"
 #endif
 
-/* VM Load/Save */
-
-/* This function writes a chunk of data to a file at the given position.
- * The pos argument can be ignored if the file is only being used for
- * streaming.  The handler should try to write all of the data it can.
- */
-typedef int (QEMUFilePutBufferFunc)(void *opaque, const uint8_t *buf,
-                                    int64_t pos, int size);
-
-/* Read a chunk of data from a file at the given position.  The pos argument
- * can be ignored if the file is only be used for streaming.  The number of
- * bytes actually read should be returned.
- */
-typedef int (QEMUFileGetBufferFunc)(void *opaque, uint8_t *buf,
-                                    int64_t pos, int size);
-
-/* Close a file and return an error code */
-typedef int (QEMUFileCloseFunc)(void *opaque);
-
-/* Called to determine if the file has exceeded it's bandwidth allocation.  The
- * bandwidth capping is a soft limit, not a hard limit.
- */
-typedef int (QEMUFileRateLimit)(void *opaque);
-
-/* Called to change the current bandwidth allocation. This function must return
- * the new actual bandwidth. It should be new_rate if everything goes ok, and
- * the old rate otherwise
- */
-typedef int64_t (QEMUFileSetRateLimit)(void *opaque, int64_t new_rate);
-typedef int64_t (QEMUFileGetRateLimit)(void *opaque);
-
-QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
-                         QEMUFileGetBufferFunc *get_buffer,
-                         QEMUFileCloseFunc *close,
-                         QEMUFileRateLimit *rate_limit,
-                         QEMUFileSetRateLimit *set_rate_limit,
-			 QEMUFileGetRateLimit *get_rate_limit);
-QEMUFile *qemu_fopen(const char *filename, const char *mode);
-QEMUFile *qemu_fdopen(int fd, const char *mode);
-QEMUFile *qemu_fopen_socket(int fd);
-QEMUFile *qemu_popen(FILE *popen_file, const char *mode);
-QEMUFile *qemu_popen_cmd(const char *command, const char *mode);
-int qemu_stdio_fd(QEMUFile *f);
-void qemu_fflush(QEMUFile *f);
-int qemu_fclose(QEMUFile *f);
-void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
-void qemu_put_byte(QEMUFile *f, int v);
-
-static inline void qemu_put_ubyte(QEMUFile *f, unsigned int v)
-{
-    qemu_put_byte(f, (int)v);
-}
-
-#define qemu_put_sbyte qemu_put_byte
-
-void qemu_put_be16(QEMUFile *f, unsigned int v);
-void qemu_put_be32(QEMUFile *f, unsigned int v);
-void qemu_put_be64(QEMUFile *f, uint64_t v);
-#ifdef CONFIG_ANDROID
-void qemu_put_float(QEMUFile *f, float v);
-#endif
-int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
-int qemu_get_byte(QEMUFile *f);
-
-static inline unsigned int qemu_get_ubyte(QEMUFile *f)
-{
-    return (unsigned int)qemu_get_byte(f);
-}
-
-#define qemu_get_sbyte qemu_get_byte
-
-unsigned int qemu_get_be16(QEMUFile *f);
-unsigned int qemu_get_be32(QEMUFile *f);
-uint64_t qemu_get_be64(QEMUFile *f);
-#ifdef CONFIG_ANDROID
-float qemu_get_float(QEMUFile *f);
-#endif
-int qemu_file_rate_limit(QEMUFile *f);
-int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate);
-int64_t qemu_file_get_rate_limit(QEMUFile *f);
-int qemu_file_has_error(QEMUFile *f);
-void qemu_file_set_error(QEMUFile *f);
-
-/* Try to send any outstanding data.  This function is useful when output is
- * halted due to rate limiting or EAGAIN errors occur as it can be used to
- * resume output. */
-void qemu_file_put_notify(QEMUFile *f);
-
-static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
-{
-    qemu_put_be64(f, *pv);
-}
-
-static inline void qemu_put_be32s(QEMUFile *f, const uint32_t *pv)
-{
-    qemu_put_be32(f, *pv);
-}
-
-static inline void qemu_put_be16s(QEMUFile *f, const uint16_t *pv)
-{
-    qemu_put_be16(f, *pv);
-}
-
-static inline void qemu_put_8s(QEMUFile *f, const uint8_t *pv)
-{
-    qemu_put_byte(f, *pv);
-}
-
-static inline void qemu_get_be64s(QEMUFile *f, uint64_t *pv)
-{
-    *pv = qemu_get_be64(f);
-}
-
-static inline void qemu_get_be32s(QEMUFile *f, uint32_t *pv)
-{
-    *pv = qemu_get_be32(f);
-}
-
-static inline void qemu_get_be16s(QEMUFile *f, uint16_t *pv)
-{
-    *pv = qemu_get_be16(f);
-}
-
-static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv)
-{
-    *pv = qemu_get_byte(f);
-}
-
-// Signed versions for type safety
-static inline void qemu_put_sbuffer(QEMUFile *f, const int8_t *buf, int size)
-{
-    qemu_put_buffer(f, (const uint8_t *)buf, size);
-}
-
-static inline void qemu_put_sbe16(QEMUFile *f, int v)
-{
-    qemu_put_be16(f, (unsigned int)v);
-}
-
-static inline void qemu_put_sbe32(QEMUFile *f, int v)
-{
-    qemu_put_be32(f, (unsigned int)v);
-}
-
-static inline void qemu_put_sbe64(QEMUFile *f, int64_t v)
-{
-    qemu_put_be64(f, (uint64_t)v);
-}
-
-static inline size_t qemu_get_sbuffer(QEMUFile *f, int8_t *buf, int size)
-{
-    return qemu_get_buffer(f, (uint8_t *)buf, size);
-}
-
-static inline int qemu_get_sbe16(QEMUFile *f)
-{
-    return (int)qemu_get_be16(f);
-}
-
-static inline int qemu_get_sbe32(QEMUFile *f)
-{
-    return (int)qemu_get_be32(f);
-}
-
-static inline int64_t qemu_get_sbe64(QEMUFile *f)
-{
-    return (int64_t)qemu_get_be64(f);
-}
-
-static inline void qemu_put_s8s(QEMUFile *f, const int8_t *pv)
-{
-    qemu_put_8s(f, (const uint8_t *)pv);
-}
-
-static inline void qemu_put_sbe16s(QEMUFile *f, const int16_t *pv)
-{
-    qemu_put_be16s(f, (const uint16_t *)pv);
-}
-
-static inline void qemu_put_sbe32s(QEMUFile *f, const int32_t *pv)
-{
-    qemu_put_be32s(f, (const uint32_t *)pv);
-}
-
-static inline void qemu_put_sbe64s(QEMUFile *f, const int64_t *pv)
-{
-    qemu_put_be64s(f, (const uint64_t *)pv);
-}
-
-static inline void qemu_get_s8s(QEMUFile *f, int8_t *pv)
-{
-    qemu_get_8s(f, (uint8_t *)pv);
-}
-
-static inline void qemu_get_sbe16s(QEMUFile *f, int16_t *pv)
-{
-    qemu_get_be16s(f, (uint16_t *)pv);
-}
-
-static inline void qemu_get_sbe32s(QEMUFile *f, int32_t *pv)
-{
-    qemu_get_be32s(f, (uint32_t *)pv);
-}
-
-static inline void qemu_get_sbe64s(QEMUFile *f, int64_t *pv)
-{
-    qemu_get_be64s(f, (uint64_t *)pv);
-}
 
 #ifdef CONFIG_ANDROID
 void qemu_put_string(QEMUFile *f, const char* str);
@@ -245,9 +38,6 @@
 #endif
 #endif
 
-int64_t qemu_ftell(QEMUFile *f);
-int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence);
-
 typedef void SaveStateHandler(QEMUFile *f, void *opaque);
 typedef int SaveLiveStateHandler(QEMUFile *f, int stage, void *opaque);
 typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index dcbaa8a..4d0e4c6 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -1,7 +1,9 @@
 #ifndef HW_PC_H
 #define HW_PC_H
 
+#include "cpu.h"
 #include "qemu-common.h"
+#include "exec/hwaddr.h"
 
 /* PC-style peripherals (also used by other machines).  */
 
@@ -46,10 +48,10 @@
                              uint8_t delivery_mode,
                              uint8_t vector_num, uint8_t polarity,
                              uint8_t trigger_mode);
-int apic_init(CPUState *env);
-int apic_accept_pic_intr(CPUState *env);
-void apic_deliver_pic_intr(CPUState *env, int level);
-int apic_get_interrupt(CPUState *env);
+int apic_init(CPUOldState *env);
+int apic_accept_pic_intr(CPUOldState *env);
+void apic_deliver_pic_intr(CPUOldState *env, int level);
+int apic_get_interrupt(CPUOldState *env);
 IOAPICState *ioapic_init(void);
 void ioapic_set_irq(void *opaque, int vector, int level);
 void apic_reset_irq_delivered(void);
@@ -162,5 +164,5 @@
 
 void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd);
 
-int cpu_is_bsp(CPUState *env);
+int cpu_is_bsp(CPUOldState *env);
 #endif
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index 4f5bc83..f3f04d0 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -3,6 +3,7 @@
 
 /* ISA bus */
 
+#include "exec/hwaddr.h"
 #include "exec/ioport.h"
 #include "hw/qdev.h"
 
diff --git a/include/hw/loader.h b/include/hw/loader.h
new file mode 100644
index 0000000..6d31ee0
--- /dev/null
+++ b/include/hw/loader.h
@@ -0,0 +1,70 @@
+#ifndef LOADER_H
+#define LOADER_H
+
+#include "cpu.h"
+#include "qapi/qmp/qdict.h"
+#include "hw/nvram/fw_cfg.h"
+
+/* loader.c */
+int get_image_size(const char *filename);
+int load_image(const char *filename, uint8_t *addr); /* deprecated */
+int load_image_targphys(const char *filename, hwaddr,
+                        uint64_t max_sz);
+int load_elf(const char *filename, int64_t address_offset,
+             uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr);
+int load_aout(const char *filename, hwaddr addr, int max_sz);
+int load_uimage(const char *filename, target_ulong *ep, target_ulong *loadaddr,
+                int *is_linux);
+
+/**
+ * load_ramdisk:
+ * @filename: Path to the ramdisk image
+ * @addr: Memory address to load the ramdisk to
+ * @max_sz: Maximum allowed ramdisk size (for non-u-boot ramdisks)
+ *
+ * Load a ramdisk image with U-Boot header to the specified memory
+ * address.
+ *
+ * Returns the size of the loaded image on success, -1 otherwise.
+ */
+int load_ramdisk(const char *filename, hwaddr addr, uint64_t max_sz);
+
+ssize_t read_targphys(const char *name,
+                      int fd, hwaddr dst_addr, size_t nbytes);
+void pstrcpy_targphys(const char *name,
+                      hwaddr dest, int buf_size,
+                      const char *source);
+
+#ifndef CONFIG_ANDROID  // TODO(digit)
+extern bool rom_file_in_ram;
+
+int rom_add_file(const char *file, const char *fw_dir,
+                 hwaddr addr, int32_t bootindex);
+void *rom_add_blob(const char *name, const void *blob, size_t len,
+                   hwaddr addr, const char *fw_file_name,
+                   FWCfgReadCallback fw_callback, void *callback_opaque);
+int rom_add_elf_program(const char *name, void *data, size_t datasize,
+                        size_t romsize, hwaddr addr);
+int rom_load_all(void);
+void rom_load_done(void);
+void rom_set_fw(FWCfgState *f);
+int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
+void *rom_ptr(hwaddr addr);
+void do_info_roms(Monitor *mon, const QDict *qdict);
+
+#define rom_add_file_fixed(_f, _a, _i)          \
+    rom_add_file(_f, NULL, _a, _i)
+#define rom_add_blob_fixed(_f, _b, _l, _a)      \
+    rom_add_blob(_f, _b, _l, _a, NULL, NULL, NULL)
+
+#define PC_ROM_MIN_VGA     0xc0000
+#define PC_ROM_MIN_OPTION  0xc8000
+#define PC_ROM_MAX         0xe0000
+#define PC_ROM_ALIGN       0x800
+#define PC_ROM_SIZE        (PC_ROM_MAX - PC_ROM_MIN_VGA)
+
+int rom_add_vga(const char *file);
+int rom_add_option(const char *file, int32_t bootindex);
+#endif  // !CONFIG_ANDROID
+
+#endif
diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h
index faa86b6..5b45e14 100644
--- a/include/hw/mips/mips.h
+++ b/include/hw/mips/mips.h
@@ -21,10 +21,10 @@
 extern void jazz_led_init(hwaddr base);
 
 /* mips_int.c */
-extern void cpu_mips_irq_init_cpu(CPUState *env);
+extern void cpu_mips_irq_init_cpu(CPUOldState *env);
 
 /* mips_timer.c */
-extern void cpu_mips_clock_init(CPUState *);
+extern void cpu_mips_clock_init(CPUOldState *);
 
 /* rc4030.c */
 typedef struct rc4030DMAState *rc4030_dma;
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 1aef3e3..67b3435 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -200,21 +200,69 @@
                         pci_map_irq_fn map_irq, const char *name);
 
 static inline void
+pci_set_byte(uint8_t *config, uint8_t val)
+{
+    *config = val;
+}
+
+static inline uint8_t
+pci_get_byte(const uint8_t *config)
+{
+    return *config;
+}
+
+static inline void
+pci_set_word(uint8_t *config, uint16_t val)
+{
+    stw_le_p(config, val);
+}
+
+static inline uint16_t
+pci_get_word(const uint8_t *config)
+{
+    return lduw_le_p(config);
+}
+
+static inline void
+pci_set_long(uint8_t *config, uint32_t val)
+{
+    stl_le_p(config, val);
+}
+
+static inline uint32_t
+pci_get_long(const uint8_t *config)
+{
+    return ldl_le_p(config);
+}
+
+static inline void
+pci_set_quad(uint8_t *config, uint64_t val)
+{
+    cpu_to_le64w((uint64_t *)config, val);
+}
+
+static inline uint64_t
+pci_get_quad(const uint8_t *config)
+{
+    return le64_to_cpup((const uint64_t *)config);
+}
+
+static inline void
 pci_config_set_vendor_id(uint8_t *pci_config, uint16_t val)
 {
-    cpu_to_le16wu((uint16_t *)&pci_config[PCI_VENDOR_ID], val);
+    pci_set_word(&pci_config[PCI_VENDOR_ID], val);
 }
 
 static inline void
 pci_config_set_device_id(uint8_t *pci_config, uint16_t val)
 {
-    cpu_to_le16wu((uint16_t *)&pci_config[PCI_DEVICE_ID], val);
+    pci_set_word(&pci_config[PCI_DEVICE_ID], val);
 }
 
 static inline void
 pci_config_set_class(uint8_t *pci_config, uint16_t val)
 {
-    cpu_to_le16wu((uint16_t *)&pci_config[PCI_CLASS_DEVICE], val);
+    pci_set_word(&pci_config[PCI_CLASS_DEVICE], val);
 }
 
 typedef void (*pci_qdev_initfn)(PCIDevice *dev);
diff --git a/include/hw/qdev.h b/include/hw/qdev.h
index fd226c6..6777aa0 100644
--- a/include/hw/qdev.h
+++ b/include/hw/qdev.h
@@ -8,8 +8,6 @@
 
 typedef struct DeviceProperty DeviceProperty;
 
-typedef struct BusState BusState;
-
 /* This structure should not be accessed directly.  We declare it here
    so that it can be embedded in individual device state structures.  */
 struct DeviceState {
diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h
index 105806e..0327a33 100644
--- a/include/hw/sysbus.h
+++ b/include/hw/sysbus.h
@@ -3,6 +3,7 @@
 
 /* Devices attached directly to the main system bus.  */
 
+#include "exec/hwaddr.h"
 #include "hw/qdev.h"
 
 #define QDEV_MAX_MMIO 5
diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
index 682e092..faefe49 100644
--- a/include/migration/qemu-file.h
+++ b/include/migration/qemu-file.h
@@ -1,7 +1,298 @@
-#ifndef _QEMU_FILE_H
-#define _QEMU_FILE_H
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 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 QEMU_FILE_H
+#define QEMU_FILE_H 1
 
-#include "hw/hw.h"
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>  // for FILE
+#include <sys/types.h>  // only for ssize_t, *sigh*
+
+#include "qemu/typedefs.h"  // for QEMUFile
+
+struct iovec;
+
+// Upstream uses this to declare ram_addr_t, but this forces a
+// stupid dependency that generates other conflicts. Instead, this
+// header uses uint64_t instead of ram_addr_t for portability.
+//#include "exec/cpu-common.h"
+
+/* This function writes a chunk of data to a file at the given position.
+ * The pos argument can be ignored if the file is only being used for
+ * streaming.  The handler should try to write all of the data it can.
+ */
+typedef int (QEMUFilePutBufferFunc)(void *opaque, const uint8_t *buf,
+                                    int64_t pos, int size);
+
+/* Read a chunk of data from a file at the given position.  The pos argument
+ * can be ignored if the file is only be used for streaming.  The number of
+ * bytes actually read should be returned.
+ */
+typedef int (QEMUFileGetBufferFunc)(void *opaque, uint8_t *buf,
+                                    int64_t pos, int size);
+
+/* Close a file
+ *
+ * Return negative error number on error, 0 or positive value on success.
+ *
+ * The meaning of return value on success depends on the specific back-end being
+ * used.
+ */
+typedef int (QEMUFileCloseFunc)(void *opaque);
+
+/* Called to return the OS file descriptor associated to the QEMUFile.
+ */
+typedef int (QEMUFileGetFD)(void *opaque);
+
+/*
+ * This function writes an iovec to file.
+ */
+typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov,
+                                           int iovcnt, int64_t pos);
+
+/*
+ * This function provides hooks around different
+ * stages of RAM migration.
+ */
+typedef int (QEMURamHookFunc)(QEMUFile *f, void *opaque, uint64_t flags);
+
+/*
+ * Constants used by ram_control_* hooks
+ */
+#define RAM_CONTROL_SETUP    0
+#define RAM_CONTROL_ROUND    1
+#define RAM_CONTROL_HOOK     2
+#define RAM_CONTROL_FINISH   3
+
+/*
+ * This function allows override of where the RAM page
+ * is saved (such as RDMA, for example.)
+ */
+// NOTE(digit): Upstream uses ram_addr_t instead of uint64_t here.
+typedef size_t (QEMURamSaveFunc)(QEMUFile *f, void *opaque,
+                               uint64_t block_offset,
+                               uint64_t offset,
+                               size_t size,
+                               int *bytes_sent);
+
+typedef struct QEMUFileOps {
+    QEMUFilePutBufferFunc *put_buffer;
+    QEMUFileGetBufferFunc *get_buffer;
+    QEMUFileCloseFunc *close;
+    QEMUFileGetFD *get_fd;
+    QEMUFileWritevBufferFunc *writev_buffer;
+    QEMURamHookFunc *before_ram_iterate;
+    QEMURamHookFunc *after_ram_iterate;
+    QEMURamHookFunc *hook_ram_load;
+    QEMURamSaveFunc *save_page;
+} QEMUFileOps;
+
+QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops);
+QEMUFile *qemu_fopen(const char *filename, const char *mode);
+QEMUFile *qemu_fdopen(int fd, const char *mode);
+QEMUFile *qemu_fopen_socket(int fd, const char *mode);
+QEMUFile *qemu_popen_cmd(const char *command, const char *mode);
+int qemu_get_fd(QEMUFile *f);
+int qemu_fclose(QEMUFile *f);
+int64_t qemu_ftell(QEMUFile *f);
+void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
+void qemu_put_byte(QEMUFile *f, int v);
+
+void qemu_file_set_error(QEMUFile* f, int error);
+int qemu_file_has_error(QEMUFile* f);
+void qemu_file_put_notify(QEMUFile* f);
+
+/*
+ * put_buffer without copying the buffer.
+ * The buffer should be available till it is sent asynchronously.
+ */
+void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size);
+bool qemu_file_mode_is_not_valid(const char *mode);
+
+static inline void qemu_put_ubyte(QEMUFile *f, unsigned int v)
+{
+    qemu_put_byte(f, (int)v);
+}
+
+#define qemu_put_sbyte qemu_put_byte
+
+void qemu_put_be16(QEMUFile *f, unsigned int v);
+void qemu_put_be32(QEMUFile *f, unsigned int v);
+void qemu_put_be64(QEMUFile *f, uint64_t v);
+int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
+int qemu_get_byte(QEMUFile *f);
+#ifdef CONFIG_ANDROID
+void qemu_put_float(QEMUFile *f, float v);
+#endif
+
+void qemu_update_position(QEMUFile *f, size_t size);
+
+static inline unsigned int qemu_get_ubyte(QEMUFile *f)
+{
+    return (unsigned int)qemu_get_byte(f);
+}
+
+#define qemu_get_sbyte qemu_get_byte
+
+unsigned int qemu_get_be16(QEMUFile *f);
+unsigned int qemu_get_be32(QEMUFile *f);
+uint64_t qemu_get_be64(QEMUFile *f);
+#ifdef CONFIG_ANDROID
+float qemu_get_float(QEMUFile *f);
+#endif
+int qemu_file_rate_limit(QEMUFile *f);
+void qemu_file_reset_rate_limit(QEMUFile *f);
+void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate);
+int64_t qemu_file_get_rate_limit(QEMUFile *f);
+int qemu_file_get_error(QEMUFile *f);
+void qemu_fflush(QEMUFile *f);
+
+static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
+{
+    qemu_put_be64(f, *pv);
+}
+
+static inline void qemu_put_be32s(QEMUFile *f, const uint32_t *pv)
+{
+    qemu_put_be32(f, *pv);
+}
+
+static inline void qemu_put_be16s(QEMUFile *f, const uint16_t *pv)
+{
+    qemu_put_be16(f, *pv);
+}
+
+static inline void qemu_put_8s(QEMUFile *f, const uint8_t *pv)
+{
+    qemu_put_byte(f, *pv);
+}
+
+static inline void qemu_get_be64s(QEMUFile *f, uint64_t *pv)
+{
+    *pv = qemu_get_be64(f);
+}
+
+static inline void qemu_get_be32s(QEMUFile *f, uint32_t *pv)
+{
+    *pv = qemu_get_be32(f);
+}
+
+static inline void qemu_get_be16s(QEMUFile *f, uint16_t *pv)
+{
+    *pv = qemu_get_be16(f);
+}
+
+static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv)
+{
+    *pv = qemu_get_byte(f);
+}
+
+// Signed versions for type safety
+static inline void qemu_put_sbuffer(QEMUFile *f, const int8_t *buf, int size)
+{
+    qemu_put_buffer(f, (const uint8_t *)buf, size);
+}
+
+static inline void qemu_put_sbe16(QEMUFile *f, int v)
+{
+    qemu_put_be16(f, (unsigned int)v);
+}
+
+static inline void qemu_put_sbe32(QEMUFile *f, int v)
+{
+    qemu_put_be32(f, (unsigned int)v);
+}
+
+static inline void qemu_put_sbe64(QEMUFile *f, int64_t v)
+{
+    qemu_put_be64(f, (uint64_t)v);
+}
+
+static inline size_t qemu_get_sbuffer(QEMUFile *f, int8_t *buf, int size)
+{
+    return qemu_get_buffer(f, (uint8_t *)buf, size);
+}
+
+static inline int qemu_get_sbe16(QEMUFile *f)
+{
+    return (int)qemu_get_be16(f);
+}
+
+static inline int qemu_get_sbe32(QEMUFile *f)
+{
+    return (int)qemu_get_be32(f);
+}
+
+static inline int64_t qemu_get_sbe64(QEMUFile *f)
+{
+    return (int64_t)qemu_get_be64(f);
+}
+
+static inline void qemu_put_s8s(QEMUFile *f, const int8_t *pv)
+{
+    qemu_put_8s(f, (const uint8_t *)pv);
+}
+
+static inline void qemu_put_sbe16s(QEMUFile *f, const int16_t *pv)
+{
+    qemu_put_be16s(f, (const uint16_t *)pv);
+}
+
+static inline void qemu_put_sbe32s(QEMUFile *f, const int32_t *pv)
+{
+    qemu_put_be32s(f, (const uint32_t *)pv);
+}
+
+static inline void qemu_put_sbe64s(QEMUFile *f, const int64_t *pv)
+{
+    qemu_put_be64s(f, (const uint64_t *)pv);
+}
+
+static inline void qemu_get_s8s(QEMUFile *f, int8_t *pv)
+{
+    qemu_get_8s(f, (uint8_t *)pv);
+}
+
+static inline void qemu_get_sbe16s(QEMUFile *f, int16_t *pv)
+{
+    qemu_get_be16s(f, (uint16_t *)pv);
+}
+
+static inline void qemu_get_sbe32s(QEMUFile *f, int32_t *pv)
+{
+    qemu_get_be32s(f, (uint32_t *)pv);
+}
+
+static inline void qemu_get_sbe64s(QEMUFile *f, int64_t *pv)
+{
+    qemu_get_be64s(f, (uint64_t *)pv);
+}
+
+#ifdef CONFIG_ANDROID
+void qemu_put_string(QEMUFile *f, const char* str);
+char* qemu_get_string(QEMUFile *f);
+#endif
 
 typedef enum {
     Q_FIELD_END,          /* mark end of field list */
@@ -11,13 +302,6 @@
     Q_FIELD_INT64,        /* for 8-byte fields */
     Q_FIELD_BUFFER,       /* for buffer fields */
     Q_FIELD_BUFFER_SIZE,  /* to specify the size of buffers */
-
-#if TARGET_LONG_BITS == 64
-    Q_FIELD_TL = Q_FIELD_INT64,           /* target long, either 4 or 8 bytes */
-#else
-    Q_FIELD_TL = Q_FIELD_INT32
-#endif
-
 } QFieldType;
 
 typedef struct {
diff --git a/include/monitor/readline.h b/include/monitor/readline.h
deleted file mode 100644
index f46f92a..0000000
--- a/include/monitor/readline.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef READLINE_H
-#define READLINE_H
-
-#include "qemu-common.h"
-
-#define READLINE_CMD_BUF_SIZE 4095
-#define READLINE_MAX_CMDS 64
-#define READLINE_MAX_COMPLETIONS 256
-
-typedef void ReadLineFunc(Monitor *mon, const char *str, void *opaque);
-typedef void ReadLineCompletionFunc(const char *cmdline);
-
-typedef struct ReadLineState {
-    char cmd_buf[READLINE_CMD_BUF_SIZE + 1];
-    int cmd_buf_index;
-    int cmd_buf_size;
-
-    char last_cmd_buf[READLINE_CMD_BUF_SIZE + 1];
-    int last_cmd_buf_index;
-    int last_cmd_buf_size;
-
-    int esc_state;
-    int esc_param;
-
-    char *history[READLINE_MAX_CMDS];
-    int hist_entry;
-
-    ReadLineCompletionFunc *completion_finder;
-    char *completions[READLINE_MAX_COMPLETIONS];
-    int nb_completions;
-    int completion_index;
-
-    ReadLineFunc *readline_func;
-    void *readline_opaque;
-    int read_password;
-    char prompt[256];
-    Monitor *mon;
-} ReadLineState;
-
-void readline_add_completion(ReadLineState *rs, const char *str);
-void readline_set_completion_index(ReadLineState *rs, int completion_index);
-
-const char *readline_get_history(ReadLineState *rs, unsigned int index);
-
-void readline_handle_byte(ReadLineState *rs, int ch);
-
-void readline_start(ReadLineState *rs, const char *prompt, int read_password,
-                    ReadLineFunc *readline_func, void *opaque);
-void readline_restart(ReadLineState *rs);
-void readline_show_prompt(ReadLineState *rs);
-
-ReadLineState *readline_init(Monitor *mon,
-                             ReadLineCompletionFunc *completion_finder);
-
-void readline_free(ReadLineState *rs);
-
-#endif /* !READLINE_H */
diff --git a/include/qapi/dealloc-visitor.h b/include/qapi/dealloc-visitor.h
new file mode 100644
index 0000000..cf4c36d
--- /dev/null
+++ b/include/qapi/dealloc-visitor.h
@@ -0,0 +1,26 @@
+/*
+ * Dealloc Visitor
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Michael Roth   <mdroth@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QAPI_DEALLOC_VISITOR_H
+#define QAPI_DEALLOC_VISITOR_H
+
+#include "qapi/visitor.h"
+
+typedef struct QapiDeallocVisitor QapiDeallocVisitor;
+
+QapiDeallocVisitor *qapi_dealloc_visitor_new(void);
+void qapi_dealloc_visitor_cleanup(QapiDeallocVisitor *d);
+
+Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v);
+
+#endif
diff --git a/include/qapi/error.h b/include/qapi/error.h
new file mode 100644
index 0000000..7d4c696
--- /dev/null
+++ b/include/qapi/error.h
@@ -0,0 +1,98 @@
+/*
+ * QEMU Error Objects
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.  See
+ * the COPYING.LIB file in the top-level directory.
+ */
+#ifndef ERROR_H
+#define ERROR_H
+
+#include "qemu/compiler.h"
+#include "qapi-types.h"
+#include <stdbool.h>
+
+/**
+ * A class representing internal errors within QEMU.  An error has a ErrorClass
+ * code and a human message.
+ */
+typedef struct Error Error;
+
+/**
+ * Set an indirect pointer to an error given a ErrorClass value and a
+ * printf-style human message.  This function is not meant to be used outside
+ * of QEMU.
+ */
+void error_set(Error **err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(3, 4);
+
+/**
+ * Set an indirect pointer to an error given a ErrorClass value and a
+ * printf-style human message, followed by a strerror() string if
+ * @os_error is not zero.
+ */
+void error_set_errno(Error **err, int os_error, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5);
+
+#ifdef _WIN32
+/**
+ * Set an indirect pointer to an error given a ErrorClass value and a
+ * printf-style human message, followed by a g_win32_error_message() string if
+ * @win32_err is not zero.
+ */
+void error_set_win32(Error **err, int win32_err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5);
+#endif
+
+/**
+ * Same as error_set(), but sets a generic error
+ */
+#define error_setg(err, fmt, ...) \
+    error_set(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
+#define error_setg_errno(err, os_error, fmt, ...) \
+    error_set_errno(err, os_error, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
+#ifdef _WIN32
+#define error_setg_win32(err, win32_err, fmt, ...) \
+    error_set_win32(err, win32_err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
+#endif
+
+/**
+ * Helper for open() errors
+ */
+void error_setg_file_open(Error **errp, int os_errno, const char *filename);
+
+/**
+ * Returns true if an indirect pointer to an error is pointing to a valid
+ * error object.
+ */
+bool error_is_set(Error **err);
+
+/*
+ * Get the error class of an error object.
+ */
+ErrorClass error_get_class(const 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);
+
+/**
+ * Propagate an error to an indirect pointer to an error.  This function will
+ * always transfer ownership of the error reference and handles the case where
+ * dst_err is NULL correctly.  Errors after the first are discarded.
+ */
+void error_propagate(Error **dst_err, Error *local_err);
+
+/**
+ * Free an error object.
+ */
+void error_free(Error *err);
+
+#endif
diff --git a/include/qapi/opts-visitor.h b/include/qapi/opts-visitor.h
new file mode 100644
index 0000000..fd48c14
--- /dev/null
+++ b/include/qapi/opts-visitor.h
@@ -0,0 +1,37 @@
+/*
+ * Options Visitor
+ *
+ * Copyright Red Hat, Inc. 2012
+ *
+ * Author: Laszlo Ersek <lersek@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef OPTS_VISITOR_H
+#define OPTS_VISITOR_H
+
+#include "qapi/visitor.h"
+#include "qemu/option.h"
+
+/* Inclusive upper bound on the size of any flattened range. This is a safety
+ * (= anti-annoyance) measure; wrong ranges should not cause long startup
+ * delays nor exhaust virtual memory.
+ */
+#define OPTS_VISITOR_RANGE_MAX 65536
+
+typedef struct OptsVisitor OptsVisitor;
+
+/* Contrarily to qemu-option.c::parse_option_number(), OptsVisitor's "int"
+ * parser relies on strtoll() instead of strtoull(). Consequences:
+ * - string representations of negative numbers yield negative values,
+ * - values below INT64_MIN or LLONG_MIN are rejected,
+ * - values above INT64_MAX or LLONG_MAX are rejected.
+ */
+OptsVisitor *opts_visitor_new(const QemuOpts *opts);
+void opts_visitor_cleanup(OptsVisitor *nv);
+Visitor *opts_get_visitor(OptsVisitor *nv);
+
+#endif
diff --git a/include/qapi/qmp-input-visitor.h b/include/qapi/qmp-input-visitor.h
new file mode 100644
index 0000000..3ed499c
--- /dev/null
+++ b/include/qapi/qmp-input-visitor.h
@@ -0,0 +1,29 @@
+/*
+ * Input Visitor
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QMP_INPUT_VISITOR_H
+#define QMP_INPUT_VISITOR_H
+
+#include "qapi/visitor.h"
+#include "qapi/qmp/qobject.h"
+
+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);
+
+#endif
diff --git a/include/qapi/qmp-output-visitor.h b/include/qapi/qmp-output-visitor.h
new file mode 100644
index 0000000..2266770
--- /dev/null
+++ b/include/qapi/qmp-output-visitor.h
@@ -0,0 +1,28 @@
+/*
+ * Output Visitor
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QMP_OUTPUT_VISITOR_H
+#define QMP_OUTPUT_VISITOR_H
+
+#include "qapi/visitor.h"
+#include "qapi/qmp/qobject.h"
+
+typedef struct QmpOutputVisitor QmpOutputVisitor;
+
+QmpOutputVisitor *qmp_output_visitor_new(void);
+void qmp_output_visitor_cleanup(QmpOutputVisitor *v);
+
+QObject *qmp_output_get_qobject(QmpOutputVisitor *v);
+Visitor *qmp_output_get_visitor(QmpOutputVisitor *v);
+
+#endif
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
new file mode 100644
index 0000000..cea3818
--- /dev/null
+++ b/include/qapi/qmp/dispatch.h
@@ -0,0 +1,58 @@
+/*
+ * Core Definitions for QAPI/QMP Dispatch
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QMP_CORE_H
+#define QMP_CORE_H
+
+#include "qapi/qmp/qobject.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/error.h"
+
+typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
+
+typedef enum QmpCommandType
+{
+    QCT_NORMAL,
+} QmpCommandType;
+
+typedef enum QmpCommandOptions
+{
+    QCO_NO_OPTIONS = 0x0,
+    QCO_NO_SUCCESS_RESP = 0x1,
+} QmpCommandOptions;
+
+typedef struct QmpCommand
+{
+    const char *name;
+    QmpCommandType type;
+    QmpCommandFunc *fn;
+    QmpCommandOptions options;
+    QTAILQ_ENTRY(QmpCommand) node;
+    bool enabled;
+} QmpCommand;
+
+void qmp_register_command(const char *name, QmpCommandFunc *fn,
+                          QmpCommandOptions options);
+QmpCommand *qmp_find_command(const char *name);
+QObject *qmp_dispatch(QObject *request);
+void qmp_disable_command(const char *name);
+void qmp_enable_command(const char *name);
+bool qmp_command_is_enabled(const QmpCommand *cmd);
+const char *qmp_command_name(const QmpCommand *cmd);
+bool qmp_has_success_response(const QmpCommand *cmd);
+QObject *qmp_build_error_object(Error *errp);
+typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque);
+void qmp_for_each_command(qmp_cmd_callback_fn fn, void *opaque);
+
+#endif
+
diff --git a/include/qapi/qmp/json-lexer.h b/include/qapi/qmp/json-lexer.h
index cd81943..cdff046 100644
--- a/include/qapi/qmp/json-lexer.h
+++ b/include/qapi/qmp/json-lexer.h
@@ -25,6 +25,7 @@
     JSON_STRING,
     JSON_ESCAPE,
     JSON_SKIP,
+    JSON_ERROR,
 } JSONTokenType;
 
 typedef struct JSONLexer JSONLexer;
diff --git a/include/qapi/qmp/json-parser.h b/include/qapi/qmp/json-parser.h
index 1bbac16..44d88f3 100644
--- a/include/qapi/qmp/json-parser.h
+++ b/include/qapi/qmp/json-parser.h
@@ -16,7 +16,9 @@
 
 #include "qemu-common.h"
 #include "qapi/qmp/qlist.h"
+#include "qapi/error.h"
 
 QObject *json_parser_parse(QList *tokens, va_list *ap);
+QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp);
 
 #endif
diff --git a/include/qapi/qmp/json-streamer.h b/include/qapi/qmp/json-streamer.h
index 209b0ec..823f7d7 100644
--- a/include/qapi/qmp/json-streamer.h
+++ b/include/qapi/qmp/json-streamer.h
@@ -24,6 +24,7 @@
     int brace_count;
     int bracket_count;
     QList *tokens;
+    uint64_t token_size;
 } JSONMessageParser;
 
 void json_message_parser_init(JSONMessageParser *parser,
diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index 6d9a4be..5cefd80 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -64,4 +64,9 @@
 int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value);
 const char *qdict_get_try_str(const QDict *qdict, const char *key);
 
+QDict *qdict_clone_shallow(const QDict *src);
+void qdict_flatten(QDict *qdict);
+
+void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start);
+
 #endif /* QDICT_H */
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 3b51948..c30c2f6 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -15,163 +15,235 @@
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
 #include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "qapi-types.h"
 #include <stdarg.h>
 
-typedef struct QErrorStringTable {
-    const char *desc;
-    const char *error_fmt;
-} QErrorStringTable;
-
 typedef struct QError {
     QObject_HEAD;
-    QDict *error;
     Location loc;
-    int linenr;
-    const char *file;
-    const char *func;
-    const QErrorStringTable *entry;
+    char *err_msg;
+    ErrorClass err_class;
 } QError;
 
-QError *qerror_new(void);
-QError *qerror_from_info(const char *file, int linenr, const char *func,
-                         const char *fmt, va_list *va) GCC_FMT_ATTR(4, 0);
 QString *qerror_human(const QError *qerror);
-void qerror_print(QError *qerror);
-void qerror_report_internal(const char *file, int linenr, const char *func,
-                            const char *fmt, ...) GCC_FMT_ATTR(4, 5);
-#define qerror_report(fmt, ...) \
-    qerror_report_internal(__FILE__, __LINE__, __func__, fmt, ## __VA_ARGS__)
-QError *qobject_to_qerror(const QObject *obj);
+void qerror_report(ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
+void qerror_report_err(Error *err);
+void assert_no_error(Error *err);
 
 /*
  * QError class list
  * Please keep the definitions in alphabetical order.
- * Use "grep '^#define QERR_' qerror.h | sort -c" to check.
+ * Use scripts/check-qerror.sh to check.
  */
-#define QERR_BAD_BUS_FOR_DEVICE \
-    "{ 'class': 'BadBusForDevice', 'data': { 'device': %s, 'bad_bus_type': %s } }"
+#define QERR_ADD_CLIENT_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Could not add client"
 
-#define QERR_BUS_NOT_FOUND \
-    "{ 'class': 'BusNotFound', 'data': { 'bus': %s } }"
+#define QERR_AMBIGUOUS_PATH \
+    ERROR_CLASS_GENERIC_ERROR, "Path '%s' does not uniquely identify an object"
+
+#define QERR_BAD_BUS_FOR_DEVICE \
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' can't go on a %s bus"
+
+#define QERR_BASE_NOT_FOUND \
+    ERROR_CLASS_GENERIC_ERROR, "Base '%s' not found"
+
+#define QERR_BLOCK_JOB_NOT_ACTIVE \
+    ERROR_CLASS_DEVICE_NOT_ACTIVE, "No active block job on device '%s'"
+
+#define QERR_BLOCK_JOB_PAUSED \
+    ERROR_CLASS_GENERIC_ERROR, "The block job for device '%s' is currently paused"
+
+#define QERR_BLOCK_JOB_NOT_READY \
+    ERROR_CLASS_GENERIC_ERROR, "The active block job for device '%s' cannot be completed"
+
+#define QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED \
+    ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by device '%s' does not support feature '%s'"
+
+#define QERR_BUFFER_OVERRUN \
+    ERROR_CLASS_GENERIC_ERROR, "An internal buffer overran"
 
 #define QERR_BUS_NO_HOTPLUG \
-    "{ 'class': 'BusNoHotplug', 'data': { 'bus': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Bus '%s' does not support hotplugging"
+
+#define QERR_BUS_NOT_FOUND \
+    ERROR_CLASS_GENERIC_ERROR, "Bus '%s' not found"
+
+#define QERR_COMMAND_DISABLED \
+    ERROR_CLASS_GENERIC_ERROR, "The command %s has been disabled for this instance"
 
 #define QERR_COMMAND_NOT_FOUND \
-    "{ 'class': 'CommandNotFound', 'data': { 'name': %s } }"
+    ERROR_CLASS_COMMAND_NOT_FOUND, "The command %s has not been found"
 
 #define QERR_DEVICE_ENCRYPTED \
-    "{ 'class': 'DeviceEncrypted', 'data': { 'device': %s } }"
+    ERROR_CLASS_DEVICE_ENCRYPTED, "'%s' (%s) is encrypted"
+
+#define QERR_DEVICE_FEATURE_BLOCKS_MIGRATION \
+    ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when using feature '%s' in device '%s'"
+
+#define QERR_DEVICE_HAS_NO_MEDIUM \
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no medium"
 
 #define QERR_DEVICE_INIT_FAILED \
-    "{ 'class': 'DeviceInitFailed', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' could not be initialized"
 
 #define QERR_DEVICE_IN_USE \
-    "{ 'class': 'DeviceInUse', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is in use"
+
+#define QERR_DEVICE_IS_READ_ONLY \
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is read only"
 
 #define QERR_DEVICE_LOCKED \
-    "{ 'class': 'DeviceLocked', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is locked"
 
 #define QERR_DEVICE_MULTIPLE_BUSSES \
-    "{ 'class': 'DeviceMultipleBusses', 'data': { 'device': %s } }"
-
-#define QERR_DEVICE_NOT_ACTIVE \
-    "{ 'class': 'DeviceNotActive', 'data': { 'device': %s } }"
-
-#define QERR_DEVICE_NOT_ENCRYPTED \
-    "{ 'class': 'DeviceNotEncrypted', 'data': { 'device': %s } }"
-
-#define QERR_DEVICE_NOT_FOUND \
-    "{ 'class': 'DeviceNotFound', 'data': { 'device': %s } }"
-
-#define QERR_DEVICE_NOT_REMOVABLE \
-    "{ 'class': 'DeviceNotRemovable', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' has multiple child busses"
 
 #define QERR_DEVICE_NO_BUS \
-    "{ 'class': 'DeviceNoBus', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no child bus"
 
 #define QERR_DEVICE_NO_HOTPLUG \
-    "{ 'class': 'DeviceNoHotplug', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' does not support hotplugging"
+
+#define QERR_DEVICE_NOT_ACTIVE \
+    ERROR_CLASS_DEVICE_NOT_ACTIVE, "Device '%s' has not been activated"
+
+#define QERR_DEVICE_NOT_ENCRYPTED \
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not encrypted"
+
+#define QERR_DEVICE_NOT_FOUND \
+    ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found"
+
+#define QERR_DEVICE_NOT_REMOVABLE \
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not removable"
 
 #define QERR_DUPLICATE_ID \
-    "{ 'class': 'DuplicateId', 'data': { 'id': %s, 'object': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Duplicate ID '%s' for %s"
 
 #define QERR_FD_NOT_FOUND \
-    "{ 'class': 'FdNotFound', 'data': { 'name': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "File descriptor named '%s' not found"
 
 #define QERR_FD_NOT_SUPPLIED \
-    "{ 'class': 'FdNotSupplied', 'data': {} }"
-
-#define QERR_INVALID_BLOCK_FORMAT \
-    "{ 'class': 'InvalidBlockFormat', 'data': { 'name': %s } }"
-
-#define QERR_INVALID_PARAMETER \
-    "{ 'class': 'InvalidParameter', 'data': { 'name': %s } }"
-
-#define QERR_INVALID_PARAMETER_TYPE \
-    "{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }"
-
-#define QERR_INVALID_PARAMETER_VALUE \
-    "{ 'class': 'InvalidParameterValue', 'data': { 'name': %s, 'expected': %s } }"
-
-#define QERR_INVALID_PASSWORD \
-    "{ 'class': 'InvalidPassword', 'data': {} }"
-
-#define QERR_JSON_PARSING \
-    "{ 'class': 'JSONParsing', 'data': {} }"
-
-#define QERR_KVM_MISSING_CAP \
-    "{ 'class': 'KVMMissingCap', 'data': { 'capability': %s, 'feature': %s } }"
-
-#define QERR_MIGRATION_EXPECTED \
-    "{ 'class': 'MigrationExpected', 'data': {} }"
-
-#define QERR_MISSING_PARAMETER \
-    "{ 'class': 'MissingParameter', 'data': { 'name': %s } }"
-
-#define QERR_NO_BUS_FOR_DEVICE \
-    "{ 'class': 'NoBusForDevice', 'data': { 'device': %s, 'bus': %s } }"
-
-#define QERR_OPEN_FILE_FAILED \
-    "{ 'class': 'OpenFileFailed', 'data': { 'filename': %s } }"
-
-#define QERR_PROPERTY_NOT_FOUND \
-    "{ 'class': 'PropertyNotFound', 'data': { 'device': %s, 'property': %s } }"
-
-#define QERR_PROPERTY_VALUE_BAD \
-    "{ 'class': 'PropertyValueBad', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
-
-#define QERR_PROPERTY_VALUE_IN_USE \
-    "{ 'class': 'PropertyValueInUse', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
-
-#define QERR_PROPERTY_VALUE_NOT_FOUND \
-    "{ 'class': 'PropertyValueNotFound', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
-
-#define QERR_QMP_BAD_INPUT_OBJECT \
-    "{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }"
-
-#define QERR_QMP_BAD_INPUT_OBJECT_MEMBER \
-    "{ 'class': 'QMPBadInputObjectMember', 'data': { 'member': %s, 'expected': %s } }"
-
-#define QERR_QMP_EXTRA_MEMBER \
-    "{ 'class': 'QMPExtraInputObjectMember', 'data': { 'member': %s } }"
-
-#define QERR_SET_PASSWD_FAILED \
-    "{ 'class': 'SetPasswdFailed', 'data': {} }"
-
-#define QERR_TOO_MANY_FILES \
-    "{ 'class': 'TooManyFiles', 'data': {} }"
-
-#define QERR_UNDEFINED_ERROR \
-    "{ 'class': 'UndefinedError', 'data': {} }"
-
-#define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
-    "{ 'class': 'UnknownBlockFormatFeature', 'data': { 'device': %s, 'format': %s, 'feature': %s } }"
-
-#define QERR_VNC_SERVER_FAILED \
-    "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "No file descriptor supplied via SCM_RIGHTS"
 
 #define QERR_FEATURE_DISABLED \
-    "{ 'class': 'FeatureDisabled', 'data': { 'name': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "The feature '%s' is not enabled"
+
+#define QERR_INVALID_BLOCK_FORMAT \
+    ERROR_CLASS_GENERIC_ERROR, "Invalid block format '%s'"
+
+#define QERR_INVALID_OPTION_GROUP \
+    ERROR_CLASS_GENERIC_ERROR, "There is no option group '%s'"
+
+#define QERR_INVALID_PARAMETER \
+    ERROR_CLASS_GENERIC_ERROR, "Invalid parameter '%s'"
+
+#define QERR_INVALID_PARAMETER_COMBINATION \
+    ERROR_CLASS_GENERIC_ERROR, "Invalid parameter combination"
+
+#define QERR_INVALID_PARAMETER_TYPE \
+    ERROR_CLASS_GENERIC_ERROR, "Invalid parameter type for '%s', expected: %s"
+
+#define QERR_INVALID_PARAMETER_VALUE \
+    ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' expects %s"
+
+#define QERR_INVALID_PASSWORD \
+    ERROR_CLASS_GENERIC_ERROR, "Password incorrect"
+
+#define QERR_IO_ERROR \
+    ERROR_CLASS_GENERIC_ERROR, "An IO error has occurred"
+
+#define QERR_JSON_PARSE_ERROR \
+    ERROR_CLASS_GENERIC_ERROR, "JSON parse error, %s"
+
+#define QERR_JSON_PARSING \
+    ERROR_CLASS_GENERIC_ERROR, "Invalid JSON syntax"
+
+#define QERR_KVM_MISSING_CAP \
+    ERROR_CLASS_K_V_M_MISSING_CAP, "Using KVM without %s, %s unavailable"
+
+#define QERR_MIGRATION_ACTIVE \
+    ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress"
+
+#define QERR_MIGRATION_NOT_SUPPORTED \
+    ERROR_CLASS_GENERIC_ERROR, "State blocked by non-migratable device '%s'"
+
+#define QERR_MISSING_PARAMETER \
+    ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' is missing"
+
+#define QERR_NO_BUS_FOR_DEVICE \
+    ERROR_CLASS_GENERIC_ERROR, "No '%s' bus found for device '%s'"
+
+#define QERR_NOT_SUPPORTED \
+    ERROR_CLASS_GENERIC_ERROR, "Not supported"
+
+#define QERR_PERMISSION_DENIED \
+    ERROR_CLASS_GENERIC_ERROR, "Insufficient permission to perform this operation"
+
+#define QERR_PROPERTY_NOT_FOUND \
+    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' not found"
+
+#define QERR_PROPERTY_VALUE_BAD \
+    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' doesn't take value '%s'"
+
+#define QERR_PROPERTY_VALUE_IN_USE \
+    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't take value '%s', it's in use"
+
+#define QERR_PROPERTY_VALUE_NOT_FOUND \
+    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't find value '%s'"
+
+#define QERR_PROPERTY_VALUE_NOT_POWER_OF_2 \
+    ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2"
+
+#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
+    ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", maximum: %" PRId64 ")"
+
+#define QERR_QGA_COMMAND_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Guest agent command failed, error was '%s'"
+
+#define QERR_QGA_LOGGING_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Guest agent failed to log non-optional log statement"
+
+#define QERR_QMP_BAD_INPUT_OBJECT \
+    ERROR_CLASS_GENERIC_ERROR, "Expected '%s' in QMP input"
+
+#define QERR_QMP_BAD_INPUT_OBJECT_MEMBER \
+    ERROR_CLASS_GENERIC_ERROR, "QMP input object member '%s' expects '%s'"
+
+#define QERR_QMP_EXTRA_MEMBER \
+    ERROR_CLASS_GENERIC_ERROR, "QMP input object member '%s' is unexpected"
+
+#define QERR_RESET_REQUIRED \
+    ERROR_CLASS_GENERIC_ERROR, "Resetting the Virtual Machine is required"
+
+#define QERR_SET_PASSWD_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Could not set password"
+
+#define QERR_TOO_MANY_FILES \
+    ERROR_CLASS_GENERIC_ERROR, "Too many open files"
+
+#define QERR_UNDEFINED_ERROR \
+    ERROR_CLASS_GENERIC_ERROR, "An undefined error has occurred"
+
+#define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
+    ERROR_CLASS_GENERIC_ERROR, "'%s' uses a %s feature which is not supported by this qemu version: %s"
+
+#define QERR_UNSUPPORTED \
+    ERROR_CLASS_GENERIC_ERROR, "this feature or command is not currently supported"
+
+#define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
+    ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when VirtFS export path '%s' is mounted in the guest using mount_tag '%s'"
+
+#define QERR_SOCKET_CONNECT_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Failed to connect to socket"
+
+#define QERR_SOCKET_LISTEN_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Failed to set socket to listening mode"
+
+#define QERR_SOCKET_BIND_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Failed to bind socket"
+
+#define QERR_SOCKET_CREATE_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Failed to create socket"
 
 #endif /* QERROR_H */
diff --git a/include/qapi/qmp/qjson.h b/include/qapi/qmp/qjson.h
index 0bebab4..73351ed 100644
--- a/include/qapi/qmp/qjson.h
+++ b/include/qapi/qmp/qjson.h
@@ -15,6 +15,7 @@
 #define QJSON_H
 
 #include <stdarg.h>
+#include "qemu/compiler.h"
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp/qstring.h"
 
diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h
index 08eaea1..6cc4831 100644
--- a/include/qapi/qmp/qlist.h
+++ b/include/qapi/qmp/qlist.h
@@ -15,7 +15,6 @@
 
 #include "qapi/qmp/qobject.h"
 #include "qemu/queue.h"
-#include "qemu-common.h"
 
 typedef struct QListEntry {
     QObject *value;
@@ -48,6 +47,17 @@
 QObject *qlist_pop(QList *qlist);
 QObject *qlist_peek(QList *qlist);
 int qlist_empty(const QList *qlist);
+size_t qlist_size(const QList *qlist);
 QList *qobject_to_qlist(const QObject *obj);
 
+static inline const QListEntry *qlist_first(const QList *qlist)
+{
+    return QTAILQ_FIRST(&qlist->head);
+}
+
+static inline const QListEntry *qlist_next(const QListEntry *entry)
+{
+    return QTAILQ_NEXT(entry, next);
+}
+
 #endif /* QLIST_H */
diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
index d42386d..d0bbc7c 100644
--- a/include/qapi/qmp/qobject.h
+++ b/include/qapi/qmp/qobject.h
@@ -44,6 +44,7 @@
     QTYPE_QFLOAT,
     QTYPE_QBOOL,
     QTYPE_QERROR,
+    QTYPE_MAX,
 } qtype_code;
 
 struct QObject;
@@ -71,7 +72,7 @@
 
 /* High-level interface for qobject_decref() */
 #define QDECREF(obj)              \
-    qobject_decref(QOBJECT(obj))
+    qobject_decref(obj ? QOBJECT(obj) : NULL)
 
 /* Initialize an object to default values */
 #define QOBJECT_INIT(obj, qtype_type)   \
diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h
index 0e690f4..1bc3666 100644
--- a/include/qapi/qmp/qstring.h
+++ b/include/qapi/qmp/qstring.h
@@ -26,6 +26,7 @@
 QString *qstring_new(void);
 QString *qstring_from_str(const char *str);
 QString *qstring_from_substr(const char *str, int start, int end);
+size_t qstring_get_length(const QString *qstring);
 const char *qstring_get_str(const QString *qstring);
 void qstring_append_int(QString *qstring, int64_t value);
 void qstring_append(QString *qstring, const char *str);
diff --git a/include/qapi/string-input-visitor.h b/include/qapi/string-input-visitor.h
new file mode 100644
index 0000000..089243c
--- /dev/null
+++ b/include/qapi/string-input-visitor.h
@@ -0,0 +1,25 @@
+/*
+ * String parsing Visitor
+ *
+ * Copyright Red Hat, Inc. 2012
+ *
+ * Author: Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef STRING_INPUT_VISITOR_H
+#define STRING_INPUT_VISITOR_H
+
+#include "qapi/visitor.h"
+
+typedef struct StringInputVisitor StringInputVisitor;
+
+StringInputVisitor *string_input_visitor_new(const char *str);
+void string_input_visitor_cleanup(StringInputVisitor *v);
+
+Visitor *string_input_get_visitor(StringInputVisitor *v);
+
+#endif
diff --git a/include/qapi/string-output-visitor.h b/include/qapi/string-output-visitor.h
new file mode 100644
index 0000000..ec81e42
--- /dev/null
+++ b/include/qapi/string-output-visitor.h
@@ -0,0 +1,26 @@
+/*
+ * String printing Visitor
+ *
+ * Copyright Red Hat, Inc. 2012
+ *
+ * Author: Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef STRING_OUTPUT_VISITOR_H
+#define STRING_OUTPUT_VISITOR_H
+
+#include "qapi/visitor.h"
+
+typedef struct StringOutputVisitor StringOutputVisitor;
+
+StringOutputVisitor *string_output_visitor_new(void);
+void string_output_visitor_cleanup(StringOutputVisitor *v);
+
+char *string_output_get_string(StringOutputVisitor *v);
+Visitor *string_output_get_visitor(StringOutputVisitor *v);
+
+#endif
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
new file mode 100644
index 0000000..f3fa420
--- /dev/null
+++ b/include/qapi/visitor-impl.h
@@ -0,0 +1,69 @@
+/*
+ * Core Definitions for QAPI Visitor implementations
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Author: Paolo Bonizni <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+#ifndef QAPI_VISITOR_IMPL_H
+#define QAPI_VISITOR_IMPL_H
+
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+
+struct Visitor
+{
+    /* Must be set */
+    void (*start_struct)(Visitor *v, void **obj, const char *kind,
+                         const char *name, size_t size, Error **errp);
+    void (*end_struct)(Visitor *v, Error **errp);
+
+    void (*start_implicit_struct)(Visitor *v, void **obj, size_t size,
+                                  Error **errp);
+    void (*end_implicit_struct)(Visitor *v, Error **errp);
+
+    void (*start_list)(Visitor *v, const char *name, Error **errp);
+    GenericList *(*next_list)(Visitor *v, GenericList **list, Error **errp);
+    void (*end_list)(Visitor *v, Error **errp);
+
+    void (*type_enum)(Visitor *v, int *obj, const char *strings[],
+                      const char *kind, const char *name, Error **errp);
+    void (*get_next_type)(Visitor *v, int *kind, const int *qobjects,
+                          const char *name, Error **errp);
+
+    void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp);
+    void (*type_bool)(Visitor *v, bool *obj, const char *name, Error **errp);
+    void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
+    void (*type_number)(Visitor *v, double *obj, const char *name,
+                        Error **errp);
+
+    /* May be NULL */
+    void (*start_optional)(Visitor *v, bool *present, const char *name,
+                           Error **errp);
+    void (*end_optional)(Visitor *v, Error **errp);
+
+    void (*start_handle)(Visitor *v, void **obj, const char *kind,
+                         const char *name, Error **errp);
+    void (*end_handle)(Visitor *v, Error **errp);
+    void (*type_uint8)(Visitor *v, uint8_t *obj, const char *name, Error **errp);
+    void (*type_uint16)(Visitor *v, uint16_t *obj, const char *name, Error **errp);
+    void (*type_uint32)(Visitor *v, uint32_t *obj, const char *name, Error **errp);
+    void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
+    void (*type_int8)(Visitor *v, int8_t *obj, const char *name, Error **errp);
+    void (*type_int16)(Visitor *v, int16_t *obj, const char *name, Error **errp);
+    void (*type_int32)(Visitor *v, int32_t *obj, const char *name, Error **errp);
+    void (*type_int64)(Visitor *v, int64_t *obj, const char *name, Error **errp);
+    /* visit_type_size() falls back to (*type_uint64)() if type_size is unset */
+    void (*type_size)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
+};
+
+void input_type_enum(Visitor *v, int *obj, const char *strings[],
+                     const char *kind, const char *name, Error **errp);
+void output_type_enum(Visitor *v, int *obj, const char *strings[],
+                      const char *kind, const char *name, Error **errp);
+
+#endif
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
new file mode 100644
index 0000000..48a2a2e
--- /dev/null
+++ b/include/qapi/visitor.h
@@ -0,0 +1,64 @@
+/*
+ * Core Definitions for QAPI Visitor Classes
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+#ifndef QAPI_VISITOR_CORE_H
+#define QAPI_VISITOR_CORE_H
+
+#include "qapi/qmp/qobject.h"
+#include "qapi/error.h"
+#include <stdlib.h>
+
+typedef struct GenericList
+{
+    union {
+        void *value;
+        uint64_t padding;
+    };
+    struct GenericList *next;
+} GenericList;
+
+typedef struct Visitor Visitor;
+
+void visit_start_handle(Visitor *v, void **obj, const char *kind,
+                        const char *name, Error **errp);
+void visit_end_handle(Visitor *v, Error **errp);
+void visit_start_struct(Visitor *v, void **obj, const char *kind,
+                        const char *name, size_t size, Error **errp);
+void visit_end_struct(Visitor *v, Error **errp);
+void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
+                                 Error **errp);
+void visit_end_implicit_struct(Visitor *v, Error **errp);
+void visit_start_list(Visitor *v, const char *name, Error **errp);
+GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp);
+void visit_end_list(Visitor *v, Error **errp);
+void visit_start_optional(Visitor *v, bool *present, const char *name,
+                          Error **errp);
+void visit_end_optional(Visitor *v, Error **errp);
+void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
+                         const char *name, Error **errp);
+void visit_type_enum(Visitor *v, int *obj, const char *strings[],
+                     const char *kind, const char *name, Error **errp);
+void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp);
+void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp);
+void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp);
+void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp);
+void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp);
+void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp);
+void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp);
+void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp);
+void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp);
+void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp);
+void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp);
+void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp);
+void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp);
+
+#endif
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 92c7a2e..5ba641b 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -1,25 +1,31 @@
-/* Common header file that is included by all of qemu.  */
+
+/* Common header file that is included by all of QEMU.
+ *
+ * This file is supposed to be included only by .c files. No header file should
+ * depend on qemu-common.h, as this would easily lead to circular header
+ * dependencies.
+ *
+ * If a header file uses a definition from qemu-common.h, that definition
+ * must be moved to a separate header file, and the header that uses it
+ * must include that header.
+ */
 #ifndef QEMU_COMMON_H
 #define QEMU_COMMON_H
 
-#include "config-host.h"
+#include <setjmp.h>
 
-#define QEMU_NORETURN __attribute__ ((__noreturn__))
-#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT
-#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
-#else
-#define QEMU_WARN_UNUSED_RESULT
+#include "qemu/compiler.h"
+#include "config-host.h"
+#include "qemu/typedefs.h"
+#include "qemu/osdep.h"
+#include "qemu/bswap.h"
+
+
+#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__)
+#define WORDS_ALIGNED
 #endif
 
-#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1];
-
-typedef struct QEMUTimer QEMUTimer;
-typedef struct QEMUFile QEMUFile;
-typedef struct QEMUBH QEMUBH;
-typedef struct DeviceState DeviceState;
-
-struct Monitor;
-typedef struct Monitor Monitor;
+#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
 /* we put basic includes here to avoid repeating them in device drivers */
 #include <stdlib.h>
@@ -38,7 +44,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <assert.h>
-
+#include <signal.h>
 #include <glib.h>
 
 #ifdef _WIN32
@@ -64,48 +70,28 @@
 #if !defined(ENOTSUP)
 #define ENOTSUP 4096
 #endif
+#if !defined(ECANCELED)
+#define ECANCELED 4097
+#endif
+#if !defined(EMEDIUMTYPE)
+#define EMEDIUMTYPE 4098
+#endif
 #ifndef TIME_MAX
 #define TIME_MAX LONG_MAX
 #endif
 
-#ifndef CONFIG_IOVEC
-#define CONFIG_IOVEC
-struct iovec {
-    void *iov_base;
-    size_t iov_len;
-};
-/*
- * Use the same value as Linux for now.
- */
-#define IOV_MAX		1024
-#else
-#include <sys/uio.h>
-#endif
-
-#if defined __GNUC__
-# if (__GNUC__ < 4) || \
-     defined(__GNUC_MINOR__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 4)
-   /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */
-#  define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2)))
-#  define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m)))
-# else
-   /* Use gnu_printf when supported (qemu uses standard format strings). */
-#  define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2)))
-#  define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
-# endif
-#else
-#define GCC_ATTR /**/
-#define GCC_FMT_ATTR(n, m)
-#endif
-
 typedef int (*fprintf_function)(FILE *f, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 
 #ifdef _WIN32
 #define fsync _commit
-#define lseek _lseeki64
+#if !defined(lseek)
+# define lseek _lseeki64
+#endif
 int qemu_ftruncate64(int, int64_t);
-#define ftruncate qemu_ftruncate64
+#if !defined(ftruncate)
+# define ftruncate qemu_ftruncate64
+#endif
 
 static inline char *realpath(const char *path, char *resolved_path)
 {
@@ -119,19 +105,6 @@
 #define PRIo64 "I64o"
 #endif
 
-/* FIXME: Remove NEED_CPU_H.  */
-#ifndef NEED_CPU_H
-
-#include <setjmp.h>
-#include "qemu/osdep.h"
-#include "qemu/bswap.h"
-
-#else
-
-#include "cpu.h"
-
-#endif /* !defined(NEED_CPU_H) */
-
 /* bottom halves */
 typedef void QEMUBHFunc(void *opaque);
 
@@ -156,16 +129,41 @@
 void qemu_get_timedate(struct tm *tm, int offset);
 int qemu_timedate_diff(struct tm *tm);
 
+/**
+ * is_help_option:
+ * @s: string to test
+ *
+ * Check whether @s is one of the standard strings which indicate
+ * that the user is asking for a list of the valid values for a
+ * command option like -cpu or -M. The current accepted strings
+ * are 'help' and '?'. '?' is deprecated (it is a shell wildcard
+ * which makes it annoying to use in a reliable way) but provided
+ * for backwards compatibility.
+ *
+ * Returns: true if @s is a request for a list.
+ */
+static inline bool is_help_option(const char *s)
+{
+    return !strcmp(s, "?") || !strcmp(s, "help");
+}
+
 /* cutils.c */
 void pstrcpy(char *buf, int buf_size, const char *str);
+void strpadcpy(char *buf, int buf_size, const char *str, char pad);
 char *pstrcat(char *buf, int buf_size, const char *s);
 int strstart(const char *str, const char *val, const char **ptr);
 int stristart(const char *str, const char *val, const char **ptr);
 int qemu_strnlen(const char *s, int max_len);
+char *qemu_strsep(char **input, const char *delim);
 time_t mktimegm(struct tm *tm);
 int qemu_fls(int i);
 int qemu_fdatasync(int fd);
 int fcntl_setfl(int fd, int flag);
+int qemu_parse_fd(const char *param);
+
+int parse_uint(const char *s, unsigned long long *value, char **endptr,
+               int base);
+int parse_uint_full(const char *s, unsigned long long *value, int base);
 
 /*
  * strtosz() suffixes used to specify the default treatment of an
@@ -174,6 +172,8 @@
  * A-Z, as strtosz() will use qemu_toupper() on the given argument
  * prior to comparison.
  */
+#define STRTOSZ_DEFSUFFIX_EB	'E'
+#define STRTOSZ_DEFSUFFIX_PB	'P'
 #define STRTOSZ_DEFSUFFIX_TB	'T'
 #define STRTOSZ_DEFSUFFIX_GB	'G'
 #define STRTOSZ_DEFSUFFIX_MB	'M'
@@ -181,6 +181,11 @@
 #define STRTOSZ_DEFSUFFIX_B	'B'
 int64_t strtosz(const char *nptr, char **end);
 int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix);
+int64_t strtosz_suffix_unit(const char *nptr, char **end,
+                            const char default_suffix, int64_t unit);
+
+/* used to print char* safely */
+#define STR_OR_NULL(str) ((str) ? (str) : "null")
 
 /* path.c */
 void init_paths(const char *prefix);
@@ -213,6 +218,10 @@
 int qemu_open(const char *name, int flags, ...);
 ssize_t qemu_write_full(int fd, const void *buf, size_t count)
     QEMU_WARN_UNUSED_RESULT;
+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
@@ -221,6 +230,36 @@
 int qemu_pipe(int pipefd[2]);
 #endif
 
+#ifdef CONFIG_ANDROID
+int qemu_recv(int sock, void* buf, size_t len, int flags);
+
+int qemu_getsockopt(int sockfd, int level, int optname,
+                    void* optval, size_t* optlen);
+
+int qemu_setsockopt(int sockfd, int level, int optname,
+                    const void* optval, size_t optlen);
+
+#else  // !CONFIG_ANDROID
+#ifdef _WIN32
+/* MinGW needs type casts for the 'buf' and 'optval' arguments. */
+#define qemu_getsockopt(sockfd, level, optname, optval, optlen) \
+    getsockopt(sockfd, level, optname, optval, optlen);
+#define qemu_setsockopt(sockfd, level, optname, optval, optlen) \
+    setsockopt(sockfd, level, optname, (const void *)optval, optlen)
+#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags)
+#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
+    sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen)
+#else
+#define qemu_getsockopt(sockfd, level, optname, optval, optlen) \
+    getsockopt(sockfd, level, optname, optval, optlen)
+#define qemu_setsockopt(sockfd, level, optname, optval, optlen) \
+    setsockopt(sockfd, level, optname, optval, optlen)
+#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags)
+#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
+    sendto(sockfd, buf, len, flags, destaddr, addrlen)
+#endif
+#endif  // !CONFIG_ANDROID
+
 void *get_mmap_addr(unsigned long size);
 
 
@@ -243,41 +282,6 @@
 
 typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size);
 
-/* A load of opaque types so that device init declarations don't have to
-   pull in all the real definitions.  */
-typedef struct NICInfo NICInfo;
-typedef struct HCIInfo HCIInfo;
-typedef struct AudioState AudioState;
-typedef struct BlockDriverState BlockDriverState;
-typedef struct DriveInfo DriveInfo;
-typedef struct DisplayState DisplayState;
-typedef struct DisplayChangeListener DisplayChangeListener;
-typedef struct DisplaySurface DisplaySurface;
-typedef struct DisplayAllocator DisplayAllocator;
-typedef struct PixelFormat PixelFormat;
-typedef struct TextConsole TextConsole;
-typedef TextConsole QEMUConsole;
-typedef struct CharDriverState CharDriverState;
-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 SMBusDevice SMBusDevice;
-typedef struct PCIHostState PCIHostState;
-typedef struct PCIExpressHost PCIExpressHost;
-typedef struct PCIBus PCIBus;
-typedef struct PCIDevice PCIDevice;
-typedef struct SerialState SerialState;
-typedef struct IRQState *qemu_irq;
-typedef struct PCMCIACardState PCMCIACardState;
-typedef struct MouseTransformInfo MouseTransformInfo;
-typedef struct uWireSlave uWireSlave;
-typedef struct I2SCodec I2SCodec;
-typedef struct SSIBus SSIBus;
-typedef struct EventNotifier EventNotifier;
-typedef struct VirtIODevice VirtIODevice;
-
 typedef uint64_t pcibus_t;
 
 typedef enum {
@@ -286,15 +290,28 @@
     IF_COUNT
 } BlockInterfaceType;
 
+typedef enum LostTickPolicy {
+    LOST_TICK_DISCARD,
+    LOST_TICK_DELAY,
+    LOST_TICK_MERGE,
+    LOST_TICK_SLEW,
+    LOST_TICK_MAX
+} LostTickPolicy;
+
+typedef struct PCIHostDeviceAddress {
+    unsigned int domain;
+    unsigned int bus;
+    unsigned int slot;
+    unsigned int function;
+} PCIHostDeviceAddress;
+
+
 void cpu_exec_init_all(unsigned long tb_size);
 
 /* CPU save/load.  */
 void cpu_save(QEMUFile *f, void *opaque);
 int cpu_load(QEMUFile *f, void *opaque, int version_id);
 
-/* Force QEMU to stop what it's doing and service IO */
-void qemu_service_io(void);
-
 /* Force QEMU to process pending events */
 void qemu_notify_event(void);
 
@@ -326,16 +343,25 @@
 void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint);
 void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov);
 void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len);
-void qemu_iovec_copy(QEMUIOVector *dst, QEMUIOVector *src, uint64_t skip,
-    size_t size);
-void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size);
+void qemu_iovec_concat(QEMUIOVector *dst,
+                       QEMUIOVector *src, size_t soffset, size_t sbytes);
+void qemu_iovec_concat_iov(QEMUIOVector *dst,
+                           struct iovec *src_iov, unsigned int src_cnt,
+                           size_t soffset, size_t sbytes);
 void qemu_iovec_destroy(QEMUIOVector *qiov);
 void qemu_iovec_reset(QEMUIOVector *qiov);
-void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf);
-void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count);
-void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count);
-void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count,
-                            size_t skip);
+size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset,
+                         void *buf, size_t bytes);
+size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset,
+                           const void *buf, size_t bytes);
+size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
+                         int fillc, size_t bytes);
+
+bool buffer_is_zero(const void *buf, size_t len);
+
+#define QEMU_FILE_TYPE_BIOS   0
+#define QEMU_FILE_TYPE_KEYMAP 1
+char *qemu_find_file(int type, const char *name);
 
 /* OS specific functions */
 void os_setup_early_signal_handling(void);
@@ -378,16 +404,42 @@
     return res.ll;
 }
 
+/* Round number down to multiple */
+#define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
+
+/* Round number up to multiple */
+#define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m))
+
+static inline bool is_power_of_2(uint64_t value)
+{
+    if (!value) {
+        return 0;
+    }
+
+    return !(value & (value - 1));
+}
+
+/* round down to the nearest power of 2*/
+int64_t pow2floor(int64_t value);
+
 #include "qemu/module.h"
 
-typedef enum DisplayType
-{
-    DT_DEFAULT,
-    DT_CURSES,
-    DT_SDL,
-    DT_VNC,
-    DT_NOGRAPHIC,
-} DisplayType;
+/*
+ * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128)
+ * Input is limited to 14-bit numbers
+ */
+
+int uleb128_encode_small(uint8_t *out, uint32_t n);
+int uleb128_decode_small(const uint8_t *in, uint32_t *n);
+
+/* unicode.c */
+int mod_utf8_codepoint(const char *s, size_t n, char **end);
+
+/*
+ * Hexdump a buffer to a file. An optional string prefix is added to every line
+ */
+
+void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size);
 
 /*
  * A fixer for timeout value passed to select() on Mac. The issue is that Mac's
@@ -418,4 +470,48 @@
 #define GLOBAL_REGISTER_VARIABLE_DECL register
 #endif /* __clang__ || __llvm__ */
 
+/* vector definitions */
+#ifdef __ALTIVEC__
+#include <altivec.h>
+/* The altivec.h header says we're allowed to undef these for
+ * C++ compatibility.  Here we don't care about C++, but we
+ * undef them anyway to avoid namespace pollution.
+ */
+#undef vector
+#undef pixel
+#undef bool
+#define VECTYPE        __vector unsigned char
+#define SPLAT(p)       vec_splat(vec_ld(0, p), 0)
+#define ALL_EQ(v1, v2) vec_all_eq(v1, v2)
+/* altivec.h may redefine the bool macro as vector type.
+ * Reset it to POSIX semantics. */
+#define bool _Bool
+#elif defined __SSE2__
+#include <emmintrin.h>
+#define VECTYPE        __m128i
+#define SPLAT(p)       _mm_set1_epi8(*(p))
+#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0xFFFF)
+#else
+#define VECTYPE        unsigned long
+#define SPLAT(p)       (*(p) * (~0UL / 255))
+#define ALL_EQ(v1, v2) ((v1) == (v2))
+#endif
+
+#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8
+static inline bool
+can_use_buffer_find_nonzero_offset(const void *buf, size_t len)
+{
+    return (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR
+                   * sizeof(VECTYPE)) == 0
+            && ((uintptr_t) buf) % sizeof(VECTYPE) == 0);
+}
+size_t buffer_find_nonzero_offset(const void *buf, size_t len);
+
+/*
+ * helper to parse debug environment variables
+ */
+int parse_debug_env(const char *name, int max, int initial);
+
+extern int use_icount;
+
 #endif
diff --git a/include/qemu/acl.h b/include/qemu/acl.h
deleted file mode 100644
index 116487e..0000000
--- a/include/qemu/acl.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * QEMU access control list management
- *
- * Copyright (C) 2009 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef __QEMU_ACL_H__
-#define __QEMU_ACL_H__
-
-#include "qemu/queue.h"
-
-typedef struct qemu_acl_entry qemu_acl_entry;
-typedef struct qemu_acl qemu_acl;
-
-struct qemu_acl_entry {
-    char *match;
-    int deny;
-
-    QTAILQ_ENTRY(qemu_acl_entry) next;
-};
-
-struct qemu_acl {
-    char *aclname;
-    unsigned int nentries;
-    QTAILQ_HEAD(,qemu_acl_entry) entries;
-    int defaultDeny;
-};
-
-qemu_acl *qemu_acl_init(const char *aclname);
-
-qemu_acl *qemu_acl_find(const char *aclname);
-
-int qemu_acl_party_is_allowed(qemu_acl *acl,
-			      const char *party);
-
-void qemu_acl_reset(qemu_acl *acl);
-
-int qemu_acl_append(qemu_acl *acl,
-		    int deny,
-		    const char *match);
-int qemu_acl_insert(qemu_acl *acl,
-		    int deny,
-		    const char *match,
-		    int index);
-int qemu_acl_remove(qemu_acl *acl,
-		    const char *match);
-
-#endif /* __QEMU_ACL_H__ */
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
diff --git a/include/qemu/aes.h b/include/qemu/aes.h
index a0167eb..e79c707 100644
--- a/include/qemu/aes.h
+++ b/include/qemu/aes.h
@@ -23,4 +23,23 @@
 		     const unsigned long length, const AES_KEY *key,
 		     unsigned char *ivec, const int enc);
 
+/*
+AES_Te0[x] = S [x].[02, 01, 01, 03];
+AES_Te1[x] = S [x].[03, 02, 01, 01];
+AES_Te2[x] = S [x].[01, 03, 02, 01];
+AES_Te3[x] = S [x].[01, 01, 03, 02];
+AES_Te4[x] = S [x].[01, 01, 01, 01];
+
+AES_Td0[x] = Si[x].[0e, 09, 0d, 0b];
+AES_Td1[x] = Si[x].[0b, 0e, 09, 0d];
+AES_Td2[x] = Si[x].[0d, 0b, 0e, 09];
+AES_Td3[x] = Si[x].[09, 0d, 0b, 0e];
+AES_Td4[x] = Si[x].[01, 01, 01, 01];
+*/
+
+extern const uint32_t AES_Te0[256], AES_Te1[256], AES_Te2[256],
+                      AES_Te3[256], AES_Te4[256];
+extern const uint32_t AES_Td0[256], AES_Td1[256], AES_Td2[256],
+                      AES_Td3[256], AES_Td4[256];
+
 #endif
diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index b77fce2..492bce1 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -1,10 +1,202 @@
-#ifndef __QEMU_BARRIER_H
-#define __QEMU_BARRIER_H 1
+/*
+ * Simple interface for atomic operations.
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * Author: 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.
+ *
+ */
 
-/* FIXME: arch dependant, x86 version */
-#define smp_wmb()   asm volatile("" ::: "memory")
+#ifndef __QEMU_ATOMIC_H
+#define __QEMU_ATOMIC_H 1
+
+#include "qemu/compiler.h"
+
+/* For C11 atomic ops */
 
 /* Compiler barrier */
-#define barrier()   asm volatile("" ::: "memory")
+#define barrier()   ({ asm volatile("" ::: "memory"); (void)0; })
+
+#ifndef __ATOMIC_RELAXED
+
+/*
+ * We use GCC builtin if it's available, as that can use mfence on
+ * 32-bit as well, e.g. if built with -march=pentium-m. However, on
+ * i386 the spec is buggy, and the implementation followed it until
+ * 4.3 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36793).
+ */
+#if defined(__i386__) || defined(__x86_64__)
+#if !QEMU_GNUC_PREREQ(4, 4)
+#if defined __x86_64__
+#define smp_mb()    ({ asm volatile("mfence" ::: "memory"); (void)0; })
+#else
+#define smp_mb()    ({ asm volatile("lock; addl $0,0(%%esp) " ::: "memory"); (void)0; })
+#endif
+#endif
+#endif
+
+
+#ifdef __alpha__
+#define smp_read_barrier_depends()   asm volatile("mb":::"memory")
+#endif
+
+#if defined(__i386__) || defined(__x86_64__) || defined(__s390x__)
+
+/*
+ * Because of the strongly ordered storage model, wmb() and rmb() are nops
+ * here (a compiler barrier only).  QEMU doesn't do accesses to write-combining
+ * qemu memory or non-temporal load/stores from C code.
+ */
+#define smp_wmb()   barrier()
+#define smp_rmb()   barrier()
+
+/*
+ * __sync_lock_test_and_set() is documented to be an acquire barrier only,
+ * but it is a full barrier at the hardware level.  Add a compiler barrier
+ * to make it a full barrier also at the compiler level.
+ */
+#define atomic_xchg(ptr, i)    (barrier(), __sync_lock_test_and_set(ptr, i))
+
+/*
+ * Load/store with Java volatile semantics.
+ */
+#define atomic_mb_set(ptr, i)  ((void)atomic_xchg(ptr, i))
+
+#elif defined(_ARCH_PPC)
+
+/*
+ * We use an eieio() for wmb() on powerpc.  This assumes we don't
+ * need to order cacheable and non-cacheable stores with respect to
+ * each other.
+ *
+ * smp_mb has the same problem as on x86 for not-very-new GCC
+ * (http://patchwork.ozlabs.org/patch/126184/, Nov 2011).
+ */
+#define smp_wmb()   ({ asm volatile("eieio" ::: "memory"); (void)0; })
+#if defined(__powerpc64__)
+#define smp_rmb()   ({ asm volatile("lwsync" ::: "memory"); (void)0; })
+#else
+#define smp_rmb()   ({ asm volatile("sync" ::: "memory"); (void)0; })
+#endif
+#define smp_mb()    ({ asm volatile("sync" ::: "memory"); (void)0; })
+
+#endif /* _ARCH_PPC */
+
+#endif /* C11 atomics */
+
+/*
+ * For (host) platforms we don't have explicit barrier definitions
+ * for, we use the gcc __sync_synchronize() primitive to generate a
+ * full barrier.  This should be safe on all platforms, though it may
+ * be overkill for smp_wmb() and smp_rmb().
+ */
+#ifndef smp_mb
+#define smp_mb()    __sync_synchronize()
+#endif
+
+#ifndef smp_wmb
+#ifdef __ATOMIC_RELEASE
+#define smp_wmb()   __atomic_thread_fence(__ATOMIC_RELEASE)
+#else
+#define smp_wmb()   __sync_synchronize()
+#endif
+#endif
+
+#ifndef smp_rmb
+#ifdef __ATOMIC_ACQUIRE
+#define smp_rmb()   __atomic_thread_fence(__ATOMIC_ACQUIRE)
+#else
+#define smp_rmb()   __sync_synchronize()
+#endif
+#endif
+
+#ifndef smp_read_barrier_depends
+#ifdef __ATOMIC_CONSUME
+#define smp_read_barrier_depends()   __atomic_thread_fence(__ATOMIC_CONSUME)
+#else
+#define smp_read_barrier_depends()   barrier()
+#endif
+#endif
+
+#ifndef atomic_read
+#define atomic_read(ptr)       (*(__typeof__(*ptr) *volatile) (ptr))
+#endif
+
+#ifndef atomic_set
+#define atomic_set(ptr, i)     ((*(__typeof__(*ptr) *volatile) (ptr)) = (i))
+#endif
+
+/* These have the same semantics as Java volatile variables.
+ * See http://gee.cs.oswego.edu/dl/jmm/cookbook.html:
+ * "1. Issue a StoreStore barrier (wmb) before each volatile store."
+ *  2. Issue a StoreLoad barrier after each volatile store.
+ *     Note that you could instead issue one before each volatile load, but
+ *     this would be slower for typical programs using volatiles in which
+ *     reads greatly outnumber writes. Alternatively, if available, you
+ *     can implement volatile store as an atomic instruction (for example
+ *     XCHG on x86) and omit the barrier. This may be more efficient if
+ *     atomic instructions are cheaper than StoreLoad barriers.
+ *  3. Issue LoadLoad and LoadStore barriers after each volatile load."
+ *
+ * If you prefer to think in terms of "pairing" of memory barriers,
+ * an atomic_mb_read pairs with an atomic_mb_set.
+ *
+ * And for the few ia64 lovers that exist, an atomic_mb_read is a ld.acq,
+ * while an atomic_mb_set is a st.rel followed by a memory barrier.
+ *
+ * These are a bit weaker than __atomic_load/store with __ATOMIC_SEQ_CST
+ * (see docs/atomics.txt), and I'm not sure that __ATOMIC_ACQ_REL is enough.
+ * Just always use the barriers manually by the rules above.
+ */
+#ifndef atomic_mb_read
+#define atomic_mb_read(ptr)    ({           \
+    typeof(*ptr) _val = atomic_read(ptr);   \
+    smp_rmb();                              \
+    _val;                                   \
+})
+#endif
+
+#ifndef atomic_mb_set
+#define atomic_mb_set(ptr, i)  do {         \
+    smp_wmb();                              \
+    atomic_set(ptr, i);                     \
+    smp_mb();                               \
+} while (0)
+#endif
+
+#ifndef atomic_xchg
+#if defined(__clang__)
+#define atomic_xchg(ptr, i)    __sync_swap(ptr, i)
+#elif defined(__ATOMIC_SEQ_CST)
+#define atomic_xchg(ptr, i)    ({                           \
+    typeof(*ptr) _new = (i), _old;                          \
+    __atomic_exchange(ptr, &_new, &_old, __ATOMIC_SEQ_CST); \
+    _old;                                                   \
+})
+#else
+/* __sync_lock_test_and_set() is documented to be an acquire barrier only.  */
+#define atomic_xchg(ptr, i)    (smp_mb(), __sync_lock_test_and_set(ptr, i))
+#endif
+#endif
+
+/* Provide shorter names for GCC atomic builtins.  */
+#define atomic_fetch_inc(ptr)  __sync_fetch_and_add(ptr, 1)
+#define atomic_fetch_dec(ptr)  __sync_fetch_and_add(ptr, -1)
+#define atomic_fetch_add       __sync_fetch_and_add
+#define atomic_fetch_sub       __sync_fetch_and_sub
+#define atomic_fetch_and       __sync_fetch_and_and
+#define atomic_fetch_or        __sync_fetch_and_or
+#define atomic_cmpxchg         __sync_val_compare_and_swap
+
+/* And even shorter names that return void.  */
+#define atomic_inc(ptr)        ((void) __sync_fetch_and_add(ptr, 1))
+#define atomic_dec(ptr)        ((void) __sync_fetch_and_add(ptr, -1))
+#define atomic_add(ptr, n)     ((void) __sync_fetch_and_add(ptr, n))
+#define atomic_sub(ptr, n)     ((void) __sync_fetch_and_sub(ptr, n))
+#define atomic_and(ptr, n)     ((void) __sync_fetch_and_and(ptr, n))
+#define atomic_or(ptr, n)      ((void) __sync_fetch_and_or(ptr, n))
 
 #endif
diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
new file mode 100644
index 0000000..304c90c
--- /dev/null
+++ b/include/qemu/bitops.h
@@ -0,0 +1,406 @@
+/*
+ * Bitops Module
+ *
+ * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
+ *
+ * Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef BITOPS_H
+#define BITOPS_H
+
+#include "qemu-common.h"
+#include "host-utils.h"
+
+#define BITS_PER_BYTE           CHAR_BIT
+#define BITS_PER_LONG           (sizeof (unsigned long) * BITS_PER_BYTE)
+
+#define BIT(nr)			(1UL << (nr))
+#define BIT_MASK(nr)		(1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr)		((nr) / BITS_PER_LONG)
+#define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
+
+/**
+ * set_bit - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ */
+static inline void set_bit(int nr, unsigned long *addr)
+{
+	unsigned long mask = BIT_MASK(nr);
+        unsigned long *p = addr + BIT_WORD(nr);
+
+	*p  |= mask;
+}
+
+/**
+ * clear_bit - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ */
+static inline void clear_bit(int nr, unsigned long *addr)
+{
+	unsigned long mask = BIT_MASK(nr);
+        unsigned long *p = addr + BIT_WORD(nr);
+
+	*p &= ~mask;
+}
+
+/**
+ * change_bit - Toggle a bit in memory
+ * @nr: Bit to change
+ * @addr: Address to start counting from
+ */
+static inline void change_bit(int nr, unsigned long *addr)
+{
+	unsigned long mask = BIT_MASK(nr);
+        unsigned long *p = addr + BIT_WORD(nr);
+
+	*p ^= mask;
+}
+
+/**
+ * test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ */
+static inline int test_and_set_bit(int nr, unsigned long *addr)
+{
+	unsigned long mask = BIT_MASK(nr);
+        unsigned long *p = addr + BIT_WORD(nr);
+	unsigned long old = *p;
+
+	*p = old | mask;
+	return (old & mask) != 0;
+}
+
+/**
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ */
+static inline int test_and_clear_bit(int nr, unsigned long *addr)
+{
+	unsigned long mask = BIT_MASK(nr);
+        unsigned long *p = addr + BIT_WORD(nr);
+	unsigned long old = *p;
+
+	*p = old & ~mask;
+	return (old & mask) != 0;
+}
+
+/**
+ * test_and_change_bit - Change a bit and return its old value
+ * @nr: Bit to change
+ * @addr: Address to count from
+ */
+static inline int test_and_change_bit(int nr, unsigned long *addr)
+{
+	unsigned long mask = BIT_MASK(nr);
+        unsigned long *p = addr + BIT_WORD(nr);
+	unsigned long old = *p;
+
+	*p = old ^ mask;
+	return (old & mask) != 0;
+}
+
+/**
+ * test_bit - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
+ */
+static inline int test_bit(int nr, const unsigned long *addr)
+{
+	return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+}
+
+/**
+ * find_last_bit - find the last set bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit number of the first set bit, or size.
+ */
+unsigned long find_last_bit(const unsigned long *addr,
+                            unsigned long size);
+
+/**
+ * find_next_bit - find the next set bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The bitmap size in bits
+ */
+unsigned long find_next_bit(const unsigned long *addr,
+				   unsigned long size, unsigned long offset);
+
+/**
+ * find_next_zero_bit - find the next cleared bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The bitmap size in bits
+ */
+
+unsigned long find_next_zero_bit(const unsigned long *addr,
+                                 unsigned long size,
+                                 unsigned long offset);
+
+/**
+ * find_first_bit - find the first set bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit number of the first set bit.
+ */
+static inline unsigned long find_first_bit(const unsigned long *addr,
+                                           unsigned long size)
+{
+    return find_next_bit(addr, size, 0);
+}
+
+/**
+ * find_first_zero_bit - find the first cleared bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit number of the first cleared bit.
+ */
+static inline unsigned long find_first_zero_bit(const unsigned long *addr,
+                                                unsigned long size)
+{
+    return find_next_zero_bit(addr, size, 0);
+}
+
+static inline unsigned long hweight_long(unsigned long w)
+{
+    unsigned long count;
+
+    for (count = 0; w; w >>= 1) {
+        count += w & 1;
+    }
+    return count;
+}
+
+/**
+ * rol8 - rotate an 8-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline uint8_t rol8(uint8_t word, unsigned int shift)
+{
+    return (word << shift) | (word >> (8 - shift));
+}
+
+/**
+ * ror8 - rotate an 8-bit value right
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline uint8_t ror8(uint8_t word, unsigned int shift)
+{
+    return (word >> shift) | (word << (8 - shift));
+}
+
+/**
+ * rol16 - rotate a 16-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline uint16_t rol16(uint16_t word, unsigned int shift)
+{
+    return (word << shift) | (word >> (16 - shift));
+}
+
+/**
+ * ror16 - rotate a 16-bit value right
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline uint16_t ror16(uint16_t word, unsigned int shift)
+{
+    return (word >> shift) | (word << (16 - shift));
+}
+
+/**
+ * rol32 - rotate a 32-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline uint32_t rol32(uint32_t word, unsigned int shift)
+{
+    return (word << shift) | (word >> (32 - shift));
+}
+
+/**
+ * ror32 - rotate a 32-bit value right
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline uint32_t ror32(uint32_t word, unsigned int shift)
+{
+    return (word >> shift) | (word << (32 - shift));
+}
+
+/**
+ * rol64 - rotate a 64-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline uint64_t rol64(uint64_t word, unsigned int shift)
+{
+    return (word << shift) | (word >> (64 - shift));
+}
+
+/**
+ * ror64 - rotate a 64-bit value right
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline uint64_t ror64(uint64_t word, unsigned int shift)
+{
+    return (word >> shift) | (word << (64 - shift));
+}
+
+/**
+ * extract32:
+ * @value: the value to extract the bit field from
+ * @start: the lowest bit in the bit field (numbered from 0)
+ * @length: the length of the bit field
+ *
+ * Extract from the 32 bit input @value the bit field specified by the
+ * @start and @length parameters, and return it. The bit field must
+ * lie entirely within the 32 bit word. It is valid to request that
+ * all 32 bits are returned (ie @length 32 and @start 0).
+ *
+ * Returns: the value of the bit field extracted from the input value.
+ */
+static inline uint32_t extract32(uint32_t value, int start, int length)
+{
+    assert(start >= 0 && length > 0 && length <= 32 - start);
+    return (value >> start) & (~0U >> (32 - length));
+}
+
+/**
+ * extract64:
+ * @value: the value to extract the bit field from
+ * @start: the lowest bit in the bit field (numbered from 0)
+ * @length: the length of the bit field
+ *
+ * Extract from the 64 bit input @value the bit field specified by the
+ * @start and @length parameters, and return it. The bit field must
+ * lie entirely within the 64 bit word. It is valid to request that
+ * all 64 bits are returned (ie @length 64 and @start 0).
+ *
+ * Returns: the value of the bit field extracted from the input value.
+ */
+static inline uint64_t extract64(uint64_t value, int start, int length)
+{
+    assert(start >= 0 && length > 0 && length <= 64 - start);
+    return (value >> start) & (~0ULL >> (64 - length));
+}
+
+/**
+ * sextract32:
+ * @value: the value to extract the bit field from
+ * @start: the lowest bit in the bit field (numbered from 0)
+ * @length: the length of the bit field
+ *
+ * Extract from the 32 bit input @value the bit field specified by the
+ * @start and @length parameters, and return it, sign extended to
+ * an int32_t (ie with the most significant bit of the field propagated
+ * to all the upper bits of the return value). The bit field must lie
+ * entirely within the 32 bit word. It is valid to request that
+ * all 32 bits are returned (ie @length 32 and @start 0).
+ *
+ * Returns: the sign extended value of the bit field extracted from the
+ * input value.
+ */
+static inline int32_t sextract32(uint32_t value, int start, int length)
+{
+    assert(start >= 0 && length > 0 && length <= 32 - start);
+    /* Note that this implementation relies on right shift of signed
+     * integers being an arithmetic shift.
+     */
+    return ((int32_t)(value << (32 - length - start))) >> (32 - length);
+}
+
+/**
+ * sextract64:
+ * @value: the value to extract the bit field from
+ * @start: the lowest bit in the bit field (numbered from 0)
+ * @length: the length of the bit field
+ *
+ * Extract from the 64 bit input @value the bit field specified by the
+ * @start and @length parameters, and return it, sign extended to
+ * an int64_t (ie with the most significant bit of the field propagated
+ * to all the upper bits of the return value). The bit field must lie
+ * entirely within the 64 bit word. It is valid to request that
+ * all 64 bits are returned (ie @length 64 and @start 0).
+ *
+ * Returns: the sign extended value of the bit field extracted from the
+ * input value.
+ */
+static inline uint64_t sextract64(uint64_t value, int start, int length)
+{
+    assert(start >= 0 && length > 0 && length <= 64 - start);
+    /* Note that this implementation relies on right shift of signed
+     * integers being an arithmetic shift.
+     */
+    return ((int64_t)(value << (64 - length - start))) >> (64 - length);
+}
+
+/**
+ * deposit32:
+ * @value: initial value to insert bit field into
+ * @start: the lowest bit in the bit field (numbered from 0)
+ * @length: the length of the bit field
+ * @fieldval: the value to insert into the bit field
+ *
+ * Deposit @fieldval into the 32 bit @value at the bit field specified
+ * by the @start and @length parameters, and return the modified
+ * @value. Bits of @value outside the bit field are not modified.
+ * Bits of @fieldval above the least significant @length bits are
+ * ignored. The bit field must lie entirely within the 32 bit word.
+ * It is valid to request that all 32 bits are modified (ie @length
+ * 32 and @start 0).
+ *
+ * Returns: the modified @value.
+ */
+static inline uint32_t deposit32(uint32_t value, int start, int length,
+                                 uint32_t fieldval)
+{
+    uint32_t mask;
+    assert(start >= 0 && length > 0 && length <= 32 - start);
+    mask = (~0U >> (32 - length)) << start;
+    return (value & ~mask) | ((fieldval << start) & mask);
+}
+
+/**
+ * deposit64:
+ * @value: initial value to insert bit field into
+ * @start: the lowest bit in the bit field (numbered from 0)
+ * @length: the length of the bit field
+ * @fieldval: the value to insert into the bit field
+ *
+ * Deposit @fieldval into the 64 bit @value at the bit field specified
+ * by the @start and @length parameters, and return the modified
+ * @value. Bits of @value outside the bit field are not modified.
+ * Bits of @fieldval above the least significant @length bits are
+ * ignored. The bit field must lie entirely within the 64 bit word.
+ * It is valid to request that all 64 bits are modified (ie @length
+ * 64 and @start 0).
+ *
+ * Returns: the modified @value.
+ */
+static inline uint64_t deposit64(uint64_t value, int start, int length,
+                                 uint64_t fieldval)
+{
+    uint64_t mask;
+    assert(start >= 0 && length > 0 && length <= 64 - start);
+    mask = (~0ULL >> (64 - length)) << start;
+    return (value & ~mask) | ((fieldval << start) & mask);
+}
+
+#endif
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 82a7951..437b8e0 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -2,52 +2,17 @@
 #define BSWAP_H
 
 #include "config-host.h"
-
 #include <inttypes.h>
+#include <limits.h>
+#include <string.h>
+#include "fpu/softfloat.h"
 
 #ifdef CONFIG_MACHINE_BSWAP_H
-#include <sys/endian.h>
-#include <sys/types.h>
-#include <machine/bswap.h>
-#else
-
-#ifdef CONFIG_BYTESWAP_H
-#include <byteswap.h>
-#else
-
-#define bswap_16(x) \
-({ \
-	uint16_t __x = (x); \
-	((uint16_t)( \
-		(((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
-		(((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
-})
-
-#define bswap_32(x) \
-({ \
-	uint32_t __x = (x); \
-	((uint32_t)( \
-		(((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
-		(((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
-		(((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
-		(((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
-})
-
-#define bswap_64(x) \
-({ \
-	uint64_t __x = (x); \
-	((uint64_t)( \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) <<  8) | \
-	        (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >>  8) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
-})
-
-#endif /* !CONFIG_BYTESWAP_H */
+# include <sys/endian.h>
+# include <sys/types.h>
+# include <machine/bswap.h>
+#elif defined(CONFIG_BYTESWAP_H)
+# include <byteswap.h>
 
 static inline uint16_t bswap16(uint16_t x)
 {
@@ -63,7 +28,32 @@
 {
     return bswap_64(x);
 }
+# else
+static inline uint16_t bswap16(uint16_t x)
+{
+    return (((x & 0x00ff) << 8) |
+            ((x & 0xff00) >> 8));
+}
 
+static inline uint32_t bswap32(uint32_t x)
+{
+    return (((x & 0x000000ffU) << 24) |
+            ((x & 0x0000ff00U) <<  8) |
+            ((x & 0x00ff0000U) >>  8) |
+            ((x & 0xff000000U) >> 24));
+}
+
+static inline uint64_t bswap64(uint64_t x)
+{
+    return (((x & 0x00000000000000ffULL) << 56) |
+            ((x & 0x000000000000ff00ULL) << 40) |
+            ((x & 0x0000000000ff0000ULL) << 24) |
+            ((x & 0x00000000ff000000ULL) <<  8) |
+            ((x & 0x000000ff00000000ULL) >>  8) |
+            ((x & 0x0000ff0000000000ULL) >> 24) |
+            ((x & 0x00ff000000000000ULL) >> 40) |
+            ((x & 0xff00000000000000ULL) >> 56));
+}
 #endif /* ! CONFIG_MACHINE_BSWAP_H */
 
 static inline void bswap16s(uint16_t *s)
@@ -83,45 +73,45 @@
 
 #if defined(HOST_WORDS_BIGENDIAN)
 #define be_bswap(v, size) (v)
-#define le_bswap(v, size) bswap ## size(v)
+#define le_bswap(v, size) glue(bswap, size)(v)
 #define be_bswaps(v, size)
-#define le_bswaps(p, size) *p = bswap ## size(*p);
+#define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
 #else
 #define le_bswap(v, size) (v)
-#define be_bswap(v, size) bswap ## size(v)
+#define be_bswap(v, size) glue(bswap, size)(v)
 #define le_bswaps(v, size)
-#define be_bswaps(p, size) *p = bswap ## size(*p);
+#define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
 #endif
 
 #define CPU_CONVERT(endian, size, type)\
 static inline type endian ## size ## _to_cpu(type v)\
 {\
-    return endian ## _bswap(v, size);\
+    return glue(endian, _bswap)(v, size);\
 }\
 \
 static inline type cpu_to_ ## endian ## size(type v)\
 {\
-    return endian ## _bswap(v, size);\
+    return glue(endian, _bswap)(v, size);\
 }\
 \
 static inline void endian ## size ## _to_cpus(type *p)\
 {\
-    endian ## _bswaps(p, size)\
+    glue(endian, _bswaps)(p, size);\
 }\
 \
 static inline void cpu_to_ ## endian ## size ## s(type *p)\
 {\
-    endian ## _bswaps(p, size)\
+    glue(endian, _bswaps)(p, size);\
 }\
 \
 static inline type endian ## size ## _to_cpup(const type *p)\
 {\
-    return endian ## size ## _to_cpu(*p);\
+    return glue(glue(endian, size), _to_cpu)(*p);\
 }\
 \
 static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
 {\
-     *p = cpu_to_ ## endian ## size(v);\
+    *p = glue(glue(cpu_to_, endian), size)(v);\
 }
 
 CPU_CONVERT(be, 16, uint16_t)
@@ -132,109 +122,310 @@
 CPU_CONVERT(le, 32, uint32_t)
 CPU_CONVERT(le, 64, uint64_t)
 
-/* unaligned versions (optimized for frequent unaligned accesses)*/
-
-#if defined(__i386__) || defined(_ARCH_PPC)
-
-#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
-#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
-#define le16_to_cpupu(p) le16_to_cpup(p)
-#define le32_to_cpupu(p) le32_to_cpup(p)
-#define be32_to_cpupu(p) be32_to_cpup(p)
-
-#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
-#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
-#define cpu_to_be64wu(p, v) cpu_to_be64w(p, v)
-
-#else
-
-static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
-{
-    uint8_t *p1 = (uint8_t *)p;
-
-    p1[0] = v & 0xff;
-    p1[1] = v >> 8;
-}
-
-static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
-{
-    uint8_t *p1 = (uint8_t *)p;
-
-    p1[0] = v & 0xff;
-    p1[1] = v >> 8;
-    p1[2] = v >> 16;
-    p1[3] = v >> 24;
-}
-
-static inline uint16_t le16_to_cpupu(const uint16_t *p)
-{
-    const uint8_t *p1 = (const uint8_t *)p;
-    return p1[0] | (p1[1] << 8);
-}
-
-static inline uint32_t le32_to_cpupu(const uint32_t *p)
-{
-    const uint8_t *p1 = (const uint8_t *)p;
-    return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
-}
-
-static inline uint32_t be32_to_cpupu(const uint32_t *p)
-{
-    const uint8_t *p1 = (const uint8_t *)p;
-    return p1[3] | (p1[2] << 8) | (p1[1] << 16) | (p1[0] << 24);
-}
-
-static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
-{
-    uint8_t *p1 = (uint8_t *)p;
-
-    p1[0] = v >> 8;
-    p1[1] = v & 0xff;
-}
-
-static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
-{
-    uint8_t *p1 = (uint8_t *)p;
-
-    p1[0] = v >> 24;
-    p1[1] = v >> 16;
-    p1[2] = v >> 8;
-    p1[3] = v & 0xff;
-}
-
-static inline void cpu_to_be64wu(uint64_t *p, uint64_t v)
-{
-    uint8_t *p1 = (uint8_t *)p;
-
-    p1[0] = v >> 56;
-    p1[1] = v >> 48;
-    p1[2] = v >> 40;
-    p1[3] = v >> 32;
-    p1[4] = v >> 24;
-    p1[5] = v >> 16;
-    p1[6] = v >> 8;
-    p1[7] = v & 0xff;
-}
-
-#endif
-
-#ifdef HOST_WORDS_BIGENDIAN
-#define cpu_to_32wu cpu_to_be32wu
-#define leul_to_cpu(v) glue(glue(le,HOST_LONG_BITS),_to_cpu)(v)
-#else
-#define cpu_to_32wu cpu_to_le32wu
-#define leul_to_cpu(v) (v)
-#endif
-
-#undef le_bswap
-#undef be_bswap
-#undef le_bswaps
-#undef be_bswaps
-
 /* len must be one of 1, 2, 4 */
 static inline uint32_t qemu_bswap_len(uint32_t value, int len)
 {
     return bswap32(value) >> (32 - 8 * len);
 }
 
+/* Unions for reinterpreting between floats and integers.  */
+
+typedef union {
+    float32 f;
+    uint32_t l;
+} CPU_FloatU;
+
+typedef union {
+    float64 d;
+#if defined(HOST_WORDS_BIGENDIAN)
+    struct {
+        uint32_t upper;
+        uint32_t lower;
+    } l;
+#else
+    struct {
+        uint32_t lower;
+        uint32_t upper;
+    } l;
+#endif
+    uint64_t ll;
+} CPU_DoubleU;
+
+typedef union {
+     floatx80 d;
+     struct {
+         uint64_t lower;
+         uint16_t upper;
+     } l;
+} CPU_LDoubleU;
+
+typedef union {
+    float128 q;
+#if defined(HOST_WORDS_BIGENDIAN)
+    struct {
+        uint32_t upmost;
+        uint32_t upper;
+        uint32_t lower;
+        uint32_t lowest;
+    } l;
+    struct {
+        uint64_t upper;
+        uint64_t lower;
+    } ll;
+#else
+    struct {
+        uint32_t lowest;
+        uint32_t lower;
+        uint32_t upper;
+        uint32_t upmost;
+    } l;
+    struct {
+        uint64_t lower;
+        uint64_t upper;
+    } ll;
+#endif
+} CPU_QuadU;
+
+/* unaligned/endian-independent pointer access */
+
+/*
+ * the generic syntax is:
+ *
+ * load: ld{type}{sign}{size}{endian}_p(ptr)
+ *
+ * store: st{type}{size}{endian}_p(ptr, val)
+ *
+ * Note there are small differences with the softmmu access API!
+ *
+ * type is:
+ * (empty): integer access
+ *   f    : float access
+ *
+ * sign is:
+ * (empty): for floats or 32 bit size
+ *   u    : unsigned
+ *   s    : signed
+ *
+ * size is:
+ *   b: 8 bits
+ *   w: 16 bits
+ *   l: 32 bits
+ *   q: 64 bits
+ *
+ * endian is:
+ * (empty): host endian
+ *   be   : big endian
+ *   le   : little endian
+ */
+
+static inline int ldub_p(const void *ptr)
+{
+    return *(uint8_t *)ptr;
+}
+
+static inline int ldsb_p(const void *ptr)
+{
+    return *(int8_t *)ptr;
+}
+
+static inline void stb_p(void *ptr, int v)
+{
+    *(uint8_t *)ptr = v;
+}
+
+/* Any compiler worth its salt will turn these memcpy into native unaligned
+   operations.  Thus we don't need to play games with packed attributes, or
+   inline byte-by-byte stores.  */
+
+static inline int lduw_p(const void *ptr)
+{
+    uint16_t r;
+    memcpy(&r, ptr, sizeof(r));
+    return r;
+}
+
+static inline int ldsw_p(const void *ptr)
+{
+    int16_t r;
+    memcpy(&r, ptr, sizeof(r));
+    return r;
+}
+
+static inline void stw_p(void *ptr, uint16_t v)
+{
+    memcpy(ptr, &v, sizeof(v));
+}
+
+static inline int ldl_p(const void *ptr)
+{
+    int32_t r;
+    memcpy(&r, ptr, sizeof(r));
+    return r;
+}
+
+static inline void stl_p(void *ptr, uint32_t v)
+{
+    memcpy(ptr, &v, sizeof(v));
+}
+
+static inline uint64_t ldq_p(const void *ptr)
+{
+    uint64_t r;
+    memcpy(&r, ptr, sizeof(r));
+    return r;
+}
+
+static inline void stq_p(void *ptr, uint64_t v)
+{
+    memcpy(ptr, &v, sizeof(v));
+}
+
+static inline int lduw_le_p(const void *ptr)
+{
+    return (uint16_t)le_bswap(lduw_p(ptr), 16);
+}
+
+static inline int ldsw_le_p(const void *ptr)
+{
+    return (int16_t)le_bswap(lduw_p(ptr), 16);
+}
+
+static inline int ldl_le_p(const void *ptr)
+{
+    return le_bswap(ldl_p(ptr), 32);
+}
+
+static inline uint64_t ldq_le_p(const void *ptr)
+{
+    return le_bswap(ldq_p(ptr), 64);
+}
+
+static inline void stw_le_p(void *ptr, int v)
+{
+    stw_p(ptr, le_bswap(v, 16));
+}
+
+static inline void stl_le_p(void *ptr, int v)
+{
+    stl_p(ptr, le_bswap(v, 32));
+}
+
+static inline void stq_le_p(void *ptr, uint64_t v)
+{
+    stq_p(ptr, le_bswap(v, 64));
+}
+
+/* float access */
+
+static inline float32 ldfl_le_p(const void *ptr)
+{
+    CPU_FloatU u;
+    u.l = ldl_le_p(ptr);
+    return u.f;
+}
+
+static inline void stfl_le_p(void *ptr, float32 v)
+{
+    CPU_FloatU u;
+    u.f = v;
+    stl_le_p(ptr, u.l);
+}
+
+static inline float64 ldfq_le_p(const void *ptr)
+{
+    CPU_DoubleU u;
+    u.ll = ldq_le_p(ptr);
+    return u.d;
+}
+
+static inline void stfq_le_p(void *ptr, float64 v)
+{
+    CPU_DoubleU u;
+    u.d = v;
+    stq_le_p(ptr, u.ll);
+}
+
+static inline int lduw_be_p(const void *ptr)
+{
+    return (uint16_t)be_bswap(lduw_p(ptr), 16);
+}
+
+static inline int ldsw_be_p(const void *ptr)
+{
+    return (int16_t)be_bswap(lduw_p(ptr), 16);
+}
+
+static inline int ldl_be_p(const void *ptr)
+{
+    return be_bswap(ldl_p(ptr), 32);
+}
+
+static inline uint64_t ldq_be_p(const void *ptr)
+{
+    return be_bswap(ldq_p(ptr), 64);
+}
+
+static inline void stw_be_p(void *ptr, int v)
+{
+    stw_p(ptr, be_bswap(v, 16));
+}
+
+static inline void stl_be_p(void *ptr, int v)
+{
+    stl_p(ptr, be_bswap(v, 32));
+}
+
+static inline void stq_be_p(void *ptr, uint64_t v)
+{
+    stq_p(ptr, be_bswap(v, 64));
+}
+
+/* float access */
+
+static inline float32 ldfl_be_p(const void *ptr)
+{
+    CPU_FloatU u;
+    u.l = ldl_be_p(ptr);
+    return u.f;
+}
+
+static inline void stfl_be_p(void *ptr, float32 v)
+{
+    CPU_FloatU u;
+    u.f = v;
+    stl_be_p(ptr, u.l);
+}
+
+static inline float64 ldfq_be_p(const void *ptr)
+{
+    CPU_DoubleU u;
+    u.ll = ldq_be_p(ptr);
+    return u.d;
+}
+
+static inline void stfq_be_p(void *ptr, float64 v)
+{
+    CPU_DoubleU u;
+    u.d = v;
+    stq_be_p(ptr, u.ll);
+}
+
+static inline unsigned long leul_to_cpu(unsigned long v)
+{
+    /* In order to break an include loop between here and
+       qemu-common.h, don't rely on HOST_LONG_BITS.  */
+#if ULONG_MAX == UINT32_MAX
+    return le_bswap(v, 32);
+#elif ULONG_MAX == UINT64_MAX
+    return le_bswap(v, 64);
+#else
+# error Unknown sizeof long
+#endif
+}
+
+#undef le_bswap
+#undef be_bswap
+#undef le_bswaps
+#undef be_bswaps
+
 #endif /* BSWAP_H */
diff --git a/include/qemu/cache-utils.h b/include/qemu/cache-utils.h
index 0b65907..211245b 100644
--- a/include/qemu/cache-utils.h
+++ b/include/qemu/cache-utils.h
@@ -2,6 +2,9 @@
 #define QEMU_CACHE_UTILS_H
 
 #if defined(_ARCH_PPC)
+
+#include <stdint.h> /* uintptr_t */
+
 struct qemu_cache_conf {
     unsigned long dcache_bsize;
     unsigned long icache_bsize;
@@ -9,10 +12,10 @@
 
 extern struct qemu_cache_conf qemu_cache_conf;
 
-void qemu_cache_utils_init(char **envp);
+void qemu_cache_utils_init(void);
 
 /* mildly adjusted code from tcg-dyngen.c */
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
+static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 {
     unsigned long p, start1, stop1;
     unsigned long dsize = qemu_cache_conf.dcache_bsize;
@@ -35,7 +38,7 @@
 }
 
 #else
-#define qemu_cache_utils_init(envp) do { (void) (envp); } while (0)
+#define qemu_cache_utils_init() do { } while (0)
 #endif
 
 #endif /* QEMU_CACHE_UTILS_H */
diff --git a/include/qemu/compatfd.h b/include/qemu/compatfd.h
index fc37915..6b04877 100644
--- a/include/qemu/compatfd.h
+++ b/include/qemu/compatfd.h
@@ -39,5 +39,6 @@
 };
 
 int qemu_signalfd(const sigset_t *mask);
+bool qemu_signalfd_available(void);
 
 #endif
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
new file mode 100644
index 0000000..155b358
--- /dev/null
+++ b/include/qemu/compiler.h
@@ -0,0 +1,55 @@
+/* public domain */
+
+#ifndef COMPILER_H
+#define COMPILER_H
+
+#include "config-host.h"
+
+/*----------------------------------------------------------------------------
+| The macro QEMU_GNUC_PREREQ tests for minimum version of the GNU C compiler.
+| The code is a copy of SOFTFLOAT_GNUC_PREREQ, see softfloat-macros.h.
+*----------------------------------------------------------------------------*/
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define QEMU_GNUC_PREREQ(maj, min) \
+         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+# define QEMU_GNUC_PREREQ(maj, min) 0
+#endif
+
+#define QEMU_NORETURN __attribute__ ((__noreturn__))
+
+#if QEMU_GNUC_PREREQ(3, 4)
+#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define QEMU_WARN_UNUSED_RESULT
+#endif
+
+#if defined(_WIN32)
+# define QEMU_PACKED __attribute__((gcc_struct, packed))
+#else
+# define QEMU_PACKED __attribute__((packed))
+#endif
+
+#define cat(x,y) x ## y
+#define cat2(x,y) cat(x,y)
+#define QEMU_BUILD_BUG_ON(x) \
+    typedef char cat2(qemu_build_bug_on__,__LINE__)[(x)?-1:1] __attribute__((unused));
+
+#if defined __GNUC__
+# if !QEMU_GNUC_PREREQ(4, 4)
+   /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */
+#  define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m)))
+# else
+   /* Use gnu_printf when supported (qemu uses standard format strings). */
+#  define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
+#  if defined(_WIN32)
+    /* Map __printf__ to __gnu_printf__ because we want standard format strings
+     * even when MinGW or GLib include files use __printf__. */
+#   define __printf__ __gnu_printf__
+#  endif
+# endif
+#else
+#define GCC_FMT_ATTR(n, m)
+#endif
+
+#endif /* COMPILER_H */
diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h
index 4d5c537..3b098a9 100644
--- a/include/qemu/error-report.h
+++ b/include/qemu/error-report.h
@@ -13,6 +13,10 @@
 #ifndef QEMU_ERROR_H
 #define QEMU_ERROR_H
 
+#include <stdarg.h>
+#include <stdbool.h>
+#include "qemu/compiler.h"
+
 typedef struct Location {
     /* all members are private to qemu-error.c */
     enum { LOC_NONE, LOC_CMDLINE, LOC_FILE } kind;
@@ -36,5 +40,7 @@
 void error_print_loc(void);
 void error_set_progname(const char *argv0);
 void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
+const char *error_get_progname(void);
+extern bool enable_timestamp_msg;
 
 #endif
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 7ff1617..0f688c1 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -22,41 +22,46 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+#ifndef HOST_UTILS_H
+#define HOST_UTILS_H 1
 
-#include "qemu/osdep.h"
+#include "qemu/compiler.h"   /* QEMU_GNUC_PREREQ */
+#include <limits.h>
 
-#if defined(__x86_64__)
-#define __HAVE_FAST_MULU64__
+#ifdef CONFIG_INT128
 static inline void mulu64(uint64_t *plow, uint64_t *phigh,
                           uint64_t a, uint64_t b)
 {
-    __asm__ ("mul %0\n\t"
-             : "=d" (*phigh), "=a" (*plow)
-             : "a" (a), "0" (b));
+    __uint128_t r = (__uint128_t)a * b;
+    *plow = r;
+    *phigh = r >> 64;
 }
-#define __HAVE_FAST_MULS64__
+
 static inline void muls64(uint64_t *plow, uint64_t *phigh,
                           int64_t a, int64_t b)
 {
-    __asm__ ("imul %0\n\t"
-             : "=d" (*phigh), "=a" (*plow)
-             : "a" (a), "0" (b));
+    __int128_t r = (__int128_t)a * b;
+    *plow = r;
+    *phigh = r >> 64;
 }
 #else
 void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
 void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
 #endif
 
-/* Binary search for leading zeros.  */
-
+/**
+ * clz32 - count leading zeros in a 32-bit value.
+ * @val: The value to search
+ *
+ * Returns 32 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ */
 static inline int clz32(uint32_t val)
 {
 #if QEMU_GNUC_PREREQ(3, 4)
-    if (val)
-        return __builtin_clz(val);
-    else
-        return 32;
+    return val ? __builtin_clz(val) : 32;
 #else
+    /* Binary search for the leading one bit.  */
     int cnt = 0;
 
     if (!(val & 0xFFFF0000U)) {
@@ -86,18 +91,28 @@
 #endif
 }
 
+/**
+ * clo32 - count leading ones in a 32-bit value.
+ * @val: The value to search
+ *
+ * Returns 32 if the value is -1.
+ */
 static inline int clo32(uint32_t val)
 {
     return clz32(~val);
 }
 
+/**
+ * clz64 - count leading zeros in a 64-bit value.
+ * @val: The value to search
+ *
+ * Returns 64 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ */
 static inline int clz64(uint64_t val)
 {
 #if QEMU_GNUC_PREREQ(3, 4)
-    if (val)
-        return __builtin_clzll(val);
-    else
-        return 64;
+    return val ? __builtin_clzll(val) : 64;
 #else
     int cnt = 0;
 
@@ -111,19 +126,30 @@
 #endif
 }
 
+/**
+ * clo64 - count leading ones in a 64-bit value.
+ * @val: The value to search
+ *
+ * Returns 64 if the value is -1.
+ */
 static inline int clo64(uint64_t val)
 {
     return clz64(~val);
 }
 
+/**
+ * ctz32 - count trailing zeros in a 32-bit value.
+ * @val: The value to search
+ *
+ * Returns 32 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ */
 static inline int ctz32(uint32_t val)
 {
 #if QEMU_GNUC_PREREQ(3, 4)
-    if (val)
-        return __builtin_ctz(val);
-    else
-        return 32;
+    return val ? __builtin_ctz(val) : 32;
 #else
+    /* Binary search for the trailing one bit.  */
     int cnt;
 
     cnt = 0;
@@ -155,18 +181,28 @@
 #endif
 }
 
+/**
+ * cto32 - count trailing ones in a 32-bit value.
+ * @val: The value to search
+ *
+ * Returns 32 if the value is -1.
+ */
 static inline int cto32(uint32_t val)
 {
     return ctz32(~val);
 }
 
+/**
+ * ctz64 - count trailing zeros in a 64-bit value.
+ * @val: The value to search
+ *
+ * Returns 64 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ */
 static inline int ctz64(uint64_t val)
 {
 #if QEMU_GNUC_PREREQ(3, 4)
-    if (val)
-        return __builtin_ctzll(val);
-    else
-        return 64;
+    return val ? __builtin_ctzll(val) : 64;
 #else
     int cnt;
 
@@ -180,30 +216,56 @@
 #endif
 }
 
+/**
+ * ctz64 - count trailing ones in a 64-bit value.
+ * @val: The value to search
+ *
+ * Returns 64 if the value is -1.
+ */
 static inline int cto64(uint64_t val)
 {
     return ctz64(~val);
 }
 
+/**
+ * ctpop8 - count the population of one bits in an 8-bit value.
+ * @val: The value to search
+ */
 static inline int ctpop8(uint8_t val)
 {
+#if QEMU_GNUC_PREREQ(3, 4)
+    return __builtin_popcount(val);
+#else
     val = (val & 0x55) + ((val >> 1) & 0x55);
     val = (val & 0x33) + ((val >> 2) & 0x33);
     val = (val & 0x0f) + ((val >> 4) & 0x0f);
 
     return val;
+#endif
 }
 
+/**
+ * ctpop16 - count the population of one bits in a 16-bit value.
+ * @val: The value to search
+ */
 static inline int ctpop16(uint16_t val)
 {
+#if QEMU_GNUC_PREREQ(3, 4)
+    return __builtin_popcount(val);
+#else
     val = (val & 0x5555) + ((val >> 1) & 0x5555);
     val = (val & 0x3333) + ((val >> 2) & 0x3333);
     val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
     val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
 
     return val;
+#endif
 }
 
+/**
+ * ctpop32 - count the population of one bits in a 32-bit value.
+ * @val: The value to search
+ */
 static inline int ctpop32(uint32_t val)
 {
 #if QEMU_GNUC_PREREQ(3, 4)
@@ -219,6 +281,10 @@
 #endif
 }
 
+/**
+ * ctpop64 - count the population of one bits in a 64-bit value.
+ * @val: The value to search
+ */
 static inline int ctpop64(uint64_t val)
 {
 #if QEMU_GNUC_PREREQ(3, 4)
@@ -234,3 +300,23 @@
     return val;
 #endif
 }
+
+/* Host type specific sizes of these routines.  */
+
+#if ULONG_MAX == UINT32_MAX
+# define clzl   clz32
+# define ctzl   ctz32
+# define clol   clo32
+# define ctol   cto32
+# define ctpopl ctpop32
+#elif ULONG_MAX == UINT64_MAX
+# define clzl   clz64
+# define ctzl   ctz64
+# define clol   clo64
+# define ctol   cto64
+# define ctpopl ctpop64
+#else
+# error Unknown sizeof long
+#endif
+
+#endif
diff --git a/include/qemu/int128.h b/include/qemu/int128.h
new file mode 100644
index 0000000..9ed47aa
--- /dev/null
+++ b/include/qemu/int128.h
@@ -0,0 +1,144 @@
+#ifndef INT128_H
+#define INT128_H
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef struct Int128 Int128;
+
+struct Int128 {
+    uint64_t lo;
+    int64_t hi;
+};
+
+static inline Int128 int128_make64(uint64_t a)
+{
+    return (Int128) { a, 0 };
+}
+
+static inline uint64_t int128_get64(Int128 a)
+{
+    assert(!a.hi);
+    return a.lo;
+}
+
+static inline Int128 int128_zero(void)
+{
+    return int128_make64(0);
+}
+
+static inline Int128 int128_one(void)
+{
+    return int128_make64(1);
+}
+
+static inline Int128 int128_2_64(void)
+{
+    return (Int128) { 0, 1 };
+}
+
+static inline Int128 int128_and(Int128 a, Int128 b)
+{
+    return (Int128) { a.lo & b.lo, a.hi & b.hi };
+}
+
+static inline Int128 int128_rshift(Int128 a, int n)
+{
+    int64_t h;
+    if (!n) {
+        return a;
+    }
+    h = a.hi >> (n & 63);
+    if (n >= 64) {
+        return (Int128) { h, h >> 63 };
+    } else {
+        return (Int128) { (a.lo >> n) | (a.hi << (64 - n)), h };
+    }
+}
+
+static inline Int128 int128_add(Int128 a, Int128 b)
+{
+    uint64_t lo = a.lo + b.lo;
+
+    /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64).  Hence,
+     * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
+     * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
+     *
+     * So the carry is lo < a.lo.
+     */
+    return (Int128) { lo, (uint64_t)a.hi + b.hi + (lo < a.lo) };
+}
+
+static inline Int128 int128_neg(Int128 a)
+{
+    uint64_t lo = -a.lo;
+    return (Int128) { lo, ~(uint64_t)a.hi + !lo };
+}
+
+static inline Int128 int128_sub(Int128 a, Int128 b)
+{
+    return (Int128){ a.lo - b.lo, a.hi - b.hi - (a.lo < b.lo) };
+}
+
+static inline bool int128_nonneg(Int128 a)
+{
+    return a.hi >= 0;
+}
+
+static inline bool int128_eq(Int128 a, Int128 b)
+{
+    return a.lo == b.lo && a.hi == b.hi;
+}
+
+static inline bool int128_ne(Int128 a, Int128 b)
+{
+    return !int128_eq(a, b);
+}
+
+static inline bool int128_ge(Int128 a, Int128 b)
+{
+    return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
+}
+
+static inline bool int128_lt(Int128 a, Int128 b)
+{
+    return !int128_ge(a, b);
+}
+
+static inline bool int128_le(Int128 a, Int128 b)
+{
+    return int128_ge(b, a);
+}
+
+static inline bool int128_gt(Int128 a, Int128 b)
+{
+    return !int128_le(a, b);
+}
+
+static inline bool int128_nz(Int128 a)
+{
+    return a.lo || a.hi;
+}
+
+static inline Int128 int128_min(Int128 a, Int128 b)
+{
+    return int128_le(a, b) ? a : b;
+}
+
+static inline Int128 int128_max(Int128 a, Int128 b)
+{
+    return int128_ge(a, b) ? a : b;
+}
+
+static inline void int128_addto(Int128 *a, Int128 b)
+{
+    *a = int128_add(*a, b);
+}
+
+static inline void int128_subfrom(Int128 *a, Int128 b)
+{
+    *a = int128_sub(*a, b);
+}
+
+#endif
diff --git a/include/qemu/iov.h b/include/qemu/iov.h
new file mode 100644
index 0000000..68d25f2
--- /dev/null
+++ b/include/qemu/iov.h
@@ -0,0 +1,115 @@
+/*
+ * Helpers for using (partial) iovecs.
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * Author(s):
+ *  Amit Shah <amit.shah@redhat.com>
+ *  Michael Tokarev <mjt@tls.msk.ru>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#ifndef IOV_H
+#define IOV_H
+
+#include "qemu-common.h"
+
+/**
+ * count and return data size, in bytes, of an iovec
+ * starting at `iov' of `iov_cnt' number of elements.
+ */
+size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
+
+/**
+ * Copy from single continuous buffer to scatter-gather vector of buffers
+ * (iovec) and back like memcpy() between two continuous memory regions.
+ * Data in single continuous buffer starting at address `buf' and
+ * `bytes' bytes long will be copied to/from an iovec `iov' with
+ * `iov_cnt' number of elements, starting at byte position `offset'
+ * within the iovec.  If the iovec does not contain enough space,
+ * only part of data will be copied, up to the end of the iovec.
+ * Number of bytes actually copied will be returned, which is
+ *  min(bytes, iov_size(iov)-offset)
+ * `Offset' must point to the inside of iovec.
+ * It is okay to use very large value for `bytes' since we're
+ * limited by the size of the iovec anyway, provided that the
+ * buffer pointed to by buf has enough space.  One possible
+ * such "large" value is -1 (sinice size_t is unsigned),
+ * so specifying `-1' as `bytes' means 'up to the end of iovec'.
+ */
+size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
+                    size_t offset, const void *buf, size_t bytes);
+size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
+                  size_t offset, void *buf, size_t bytes);
+
+/**
+ * Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
+ * starting at byte offset `start', to value `fillc', repeating it
+ * `bytes' number of times.  `Offset' must point to the inside of iovec.
+ * If `bytes' is large enough, only last bytes portion of iovec,
+ * up to the end of it, will be filled with the specified value.
+ * Function return actual number of bytes processed, which is
+ * min(size, iov_size(iov) - offset).
+ * Again, it is okay to use large value for `bytes' to mean "up to the end".
+ */
+size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
+                  size_t offset, int fillc, size_t bytes);
+
+/*
+ * Send/recv data from/to iovec buffers directly
+ *
+ * `offset' bytes in the beginning of iovec buffer are skipped and
+ * next `bytes' bytes are used, which must be within data of iovec.
+ *
+ *   r = iov_send_recv(sockfd, iov, iovcnt, offset, bytes, true);
+ *
+ * is logically equivalent to
+ *
+ *   char *buf = malloc(bytes);
+ *   iov_to_buf(iov, iovcnt, offset, buf, bytes);
+ *   r = send(sockfd, buf, bytes, 0);
+ *   free(buf);
+ *
+ * For iov_send_recv() _whole_ area being sent or received
+ * should be within the iovec, not only beginning of it.
+ */
+ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt,
+                      size_t offset, size_t bytes, bool do_send);
+#define iov_recv(sockfd, iov, iov_cnt, offset, bytes) \
+  iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, false)
+#define iov_send(sockfd, iov, iov_cnt, offset, bytes) \
+  iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, true)
+
+/**
+ * Produce a text hexdump of iovec `iov' with `iov_cnt' number of elements
+ * in file `fp', prefixing each line with `prefix' and processing not more
+ * than `limit' data bytes.
+ */
+void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt,
+                 FILE *fp, const char *prefix, size_t limit);
+
+/*
+ * Partial copy of vector from iov to dst_iov (data is not copied).
+ * dst_iov overlaps iov at a specified offset.
+ * size of dst_iov is at most bytes. dst vector count is returned.
+ */
+unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
+                 const struct iovec *iov, unsigned int iov_cnt,
+                 size_t offset, size_t bytes);
+
+/*
+ * Remove a given number of bytes from the front or back of a vector.
+ * This may update iov and/or iov_cnt to exclude iovec elements that are
+ * no longer required.
+ *
+ * The number of bytes actually discarded is returned.  This number may be
+ * smaller than requested if the vector is too small.
+ */
+size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt,
+                         size_t bytes);
+size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt,
+                        size_t bytes);
+
+#endif
diff --git a/include/qemu/log.h b/include/qemu/log.h
index fccfb110..0d27cf9 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -1,10 +1,18 @@
 #ifndef QEMU_LOG_H
 #define QEMU_LOG_H
 
-/* The deprecated global variables: */
-extern FILE *logfile;
-extern int loglevel;
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include "qemu/compiler.h"
+#ifdef NEED_CPU_H
+// TODO(digit): #include "qom/cpu.h"
+#include "disas/disas.h"
+#endif
 
+/* Private global variables, don't use */
+extern FILE *qemu_logfile;
+extern int qemu_loglevel;
 
 /* 
  * The new API:
@@ -15,79 +23,162 @@
 
 /* Returns true if qemu_log() will really write somewhere
  */
-#define qemu_log_enabled() (logfile != NULL)
+static inline bool qemu_log_enabled(void)
+{
+    return qemu_logfile != NULL;
+}
+
+#define CPU_LOG_TB_OUT_ASM (1 << 0)
+#define CPU_LOG_TB_IN_ASM  (1 << 1)
+#define CPU_LOG_TB_OP      (1 << 2)
+#define CPU_LOG_TB_OP_OPT  (1 << 3)
+#define CPU_LOG_INT        (1 << 4)
+#define CPU_LOG_EXEC       (1 << 5)
+#define CPU_LOG_PCALL      (1 << 6)
+#define CPU_LOG_IOPORT     (1 << 7)
+#define CPU_LOG_TB_CPU     (1 << 8)
+#define CPU_LOG_RESET      (1 << 9)
+#define LOG_UNIMP          (1 << 10)
+#define LOG_GUEST_ERROR    (1 << 11)
 
 /* Returns true if a bit is set in the current loglevel mask
  */
-#define qemu_loglevel_mask(b) ((loglevel & (b)) != 0)
-
+static inline bool qemu_loglevel_mask(int mask)
+{
+    return (qemu_loglevel & mask) != 0;
+}
 
 /* Logging functions: */
 
 /* main logging function
  */
-#define qemu_log(...) do {                 \
-        if (logfile)                       \
-            fprintf(logfile, ## __VA_ARGS__); \
-    } while (0)
+void GCC_FMT_ATTR(1, 2) qemu_log(const char *fmt, ...);
 
 /* vfprintf-like logging function
  */
-#define qemu_log_vprintf(fmt, va) do {     \
-        if (logfile)                       \
-            vfprintf(logfile, fmt, va);    \
-    } while (0)
+static inline void GCC_FMT_ATTR(1, 0)
+qemu_log_vprintf(const char *fmt, va_list va)
+{
+    if (qemu_logfile) {
+        vfprintf(qemu_logfile, fmt, va);
+    }
+}
 
 /* log only if a bit is set on the current loglevel mask
  */
-#define qemu_log_mask(b, ...) do {         \
-        if (loglevel & (b))                \
-            fprintf(logfile, ## __VA_ARGS__); \
-    } while (0)
-
-
+void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...);
 
 
 /* Special cases: */
 
+#ifdef NEED_CPU_H
+
 /* cpu_dump_state() logging functions: */
-#define log_cpu_state(env, f) cpu_dump_state((env), logfile, fprintf, (f));
-#define log_cpu_state_mask(b, env, f) do {           \
-      if (loglevel & (b)) log_cpu_state((env), (f)); \
-  } while (0)
+/**
+ * log_cpu_state:
+ * @cpu: The CPU whose state is to be logged.
+ * @flags: Flags what to log.
+ *
+ * Logs the output of cpu_dump_state().
+ */
+static inline void log_cpu_state(CPUOldState *cpu, int flags)
+{
+    if (qemu_log_enabled()) {
+        cpu_dump_state(cpu, qemu_logfile, fprintf, flags);
+    }
+}
+/**
+ * log_cpu_state_mask:
+ * @mask: Mask when to log.
+ * @cpu: The CPU whose state is to be logged.
+ * @flags: Flags what to log.
+ *
+ * Logs the output of cpu_dump_state() if loglevel includes @mask.
+ */
+static inline void log_cpu_state_mask(int mask, CPUOldState *cpu, int flags)
+{
+    if (qemu_loglevel & mask) {
+        log_cpu_state(cpu, flags);
+    }
+}
 
-/* disas() and target_disas() to logfile: */
-#define log_target_disas(start, len, flags) \
-        target_disas(logfile, (start), (len), (flags))
-#define log_disas(start, len) \
-        disas(logfile, (start), (len))
+/* disas() and target_disas() to qemu_logfile: */
+static inline void log_target_disas(CPUArchState *env, target_ulong start,
+                                    target_ulong len, int flags)
+{
+    target_disas(qemu_logfile, env, start, len, flags);
+}
 
+static inline void log_disas(void *code, unsigned long size)
+{
+    disas(qemu_logfile, code, size);
+}
+
+#if defined(CONFIG_USER_ONLY)
 /* page_dump() output to the log file: */
-#define log_page_dump() page_dump(logfile)
-
+static inline void log_page_dump(void)
+{
+    page_dump(qemu_logfile);
+}
+#endif
+#endif  // NEED_CPU_H
 
 
 /* Maintenance: */
 
 /* fflush() the log file */
-#define qemu_log_flush() fflush(logfile)
+static inline void qemu_log_flush(void)
+{
+    fflush(qemu_logfile);
+}
 
 /* Close the log file */
-#define qemu_log_close() do { \
-        fclose(logfile);      \
-        logfile = NULL;       \
-    } while (0)
+static inline void qemu_log_close(void)
+{
+    if (qemu_logfile) {
+        if (qemu_logfile != stderr) {
+            fclose(qemu_logfile);
+        }
+        qemu_logfile = NULL;
+    }
+}
 
 /* Set up a new log file */
-#define qemu_log_set_file(f) do { \
-        logfile = (f);            \
-    } while (0)
+static inline void qemu_log_set_file(FILE *f)
+{
+    qemu_logfile = f;
+}
 
-/* Set up a new log file, only if none is set */
-#define qemu_log_try_set_file(f) do { \
-        if (!logfile)                 \
-            logfile = (f);            \
-    } while (0)
+/* define log items */
+typedef struct QEMULogItem {
+    int mask;
+    const char *name;
+    const char *help;
+} QEMULogItem;
 
+extern const QEMULogItem qemu_log_items[];
+
+/* This is the function that actually does the work of
+ * changing the log level; it should only be accessed via
+ * the qemu_set_log() wrapper.
+ */
+void do_qemu_set_log(int log_flags, bool use_own_buffers);
+
+static inline void qemu_set_log(int log_flags)
+{
+#ifdef CONFIG_USER_ONLY
+    do_qemu_set_log(log_flags, true);
+#else
+    do_qemu_set_log(log_flags, false);
+#endif
+}
+
+void qemu_set_log_filename(const char *filename);
+int qemu_str_to_log_mask(const char *str);
+
+/* Print a usage message listing all the valid logging categories
+ * to the specified FILE*.
+ */
+void qemu_print_log_usage(FILE *f);
 
 #endif
diff --git a/include/qemu/module.h b/include/qemu/module.h
index 9263f1c..0e1044c 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -22,14 +22,18 @@
 
 typedef enum {
     MODULE_INIT_BLOCK,
-    MODULE_INIT_DEVICE,
+    MODULE_INIT_DEVICE,  // TODO(digit): Remove this.
     MODULE_INIT_MACHINE,
+    MODULE_INIT_QAPI,
+    MODULE_INIT_QOM,
     MODULE_INIT_MAX
 } module_init_type;
 
 #define block_init(function) module_init(function, MODULE_INIT_BLOCK)
-#define device_init(function) module_init(function, MODULE_INIT_DEVICE)
+#define device_init(function) module_init(function, MODULE_INIT_DEVICE)  // TODO(digit): Remove this.
 #define machine_init(function) module_init(function, MODULE_INIT_MACHINE)
+#define qapi_init(function) module_init(function, MODULE_INIT_QAPI)
+#define type_init(function) module_init(function, MODULE_INIT_QOM)
 
 void register_module_init(void (*fn)(void), module_init_type type);
 
diff --git a/include/qemu/notify.h b/include/qemu/notify.h
index f3e4faa..a3d73e4 100644
--- a/include/qemu/notify.h
+++ b/include/qemu/notify.h
@@ -20,24 +20,53 @@
 
 struct Notifier
 {
-    void (*notify)(Notifier *notifier);
-    QTAILQ_ENTRY(Notifier) node;
+    void (*notify)(Notifier *notifier, void *data);
+    QLIST_ENTRY(Notifier) node;
 };
 
 typedef struct NotifierList
 {
-    QTAILQ_HEAD(, Notifier) notifiers;
+    QLIST_HEAD(, Notifier) notifiers;
 } NotifierList;
 
 #define NOTIFIER_LIST_INITIALIZER(head) \
-    { QTAILQ_HEAD_INITIALIZER((head).notifiers) }
+    { QLIST_HEAD_INITIALIZER((head).notifiers) }
 
 void notifier_list_init(NotifierList *list);
 
 void notifier_list_add(NotifierList *list, Notifier *notifier);
 
-void notifier_list_remove(NotifierList *list, Notifier *notifier);
+void notifier_remove(Notifier *notifier);
 
-void notifier_list_notify(NotifierList *list);
+void notifier_list_notify(NotifierList *list, void *data);
+
+/* Same as Notifier but allows .notify() to return errors */
+typedef struct NotifierWithReturn NotifierWithReturn;
+
+struct NotifierWithReturn {
+    /**
+     * Return 0 on success (next notifier will be invoked), otherwise
+     * notifier_with_return_list_notify() will stop and return the value.
+     */
+    int (*notify)(NotifierWithReturn *notifier, void *data);
+    QLIST_ENTRY(NotifierWithReturn) node;
+};
+
+typedef struct NotifierWithReturnList {
+    QLIST_HEAD(, NotifierWithReturn) notifiers;
+} NotifierWithReturnList;
+
+#define NOTIFIER_WITH_RETURN_LIST_INITIALIZER(head) \
+    { QLIST_HEAD_INITIALIZER((head).notifiers) }
+
+void notifier_with_return_list_init(NotifierWithReturnList *list);
+
+void notifier_with_return_list_add(NotifierWithReturnList *list,
+                                   NotifierWithReturn *notifier);
+
+void notifier_with_return_remove(NotifierWithReturn *notifier);
+
+int notifier_with_return_list_notify(NotifierWithReturnList *list,
+                                     void *data);
 
 #endif
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 3fe88fe..2d6ff85 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -1,15 +1,31 @@
 #ifndef QEMU_OSDEP_H
 #define QEMU_OSDEP_H
 
+#include "config-host.h"
 #include <stdarg.h>
 #include <stddef.h>
-#ifdef __OpenBSD__
+#include <stdbool.h>
 #include <sys/types.h>
+#ifdef __OpenBSD__
 #include <sys/signal.h>
 #endif
 
+#ifndef _WIN32
+#include <sys/wait.h>
+#else
+#define WIFEXITED(x)   1
+#define WEXITSTATUS(x) (x)
+#endif
+
 #include <sys/time.h>
 
+#if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10
+/* [u]int_fast*_t not in <sys/int_types.h> */
+typedef unsigned char           uint_fast8_t;
+typedef unsigned int            uint_fast16_t;
+typedef signed int              int_fast16_t;
+#endif
+
 #ifndef glue
 #define xglue(x, y) x ## y
 #define glue(x, y) xglue(x, y)
@@ -26,9 +42,6 @@
 #define unlikely(x)   __builtin_expect(!!(x), 0)
 #endif
 
-#ifdef CONFIG_NEED_OFFSETOF
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)
-#endif
 #ifndef container_of
 #define container_of(ptr, type, member) ({                      \
         const typeof(((type *) 0)->member) *__mptr = (ptr);     \
@@ -55,6 +68,10 @@
 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
 #endif
 
+#ifndef ROUND_UP
+#define ROUND_UP(n,d) (((n) + (d) - 1) & -(d))
+#endif
+
 #ifndef DIV_ROUND_UP
 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
 #endif
@@ -66,10 +83,12 @@
 #ifndef always_inline
 #if !((__GNUC__ < 3) || defined(__APPLE__))
 #ifdef __OPTIMIZE__
+#undef inline
 #define inline __attribute__ (( always_inline )) __inline__
 #endif
 #endif
 #else
+#undef inline
 #define inline always_inline
 #endif
 
@@ -81,16 +100,12 @@
 
 #define qemu_printf printf
 
-#if defined (__GNUC__) && defined (__GNUC_MINOR__)
-# define QEMU_GNUC_PREREQ(maj, min) \
-         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
-#else
-# define QEMU_GNUC_PREREQ(maj, min) 0
-#endif
-
+int qemu_daemon(int nochdir, int noclose);
 void *qemu_memalign(size_t alignment, size_t size);
 void *qemu_vmalloc(size_t size);
+void *qemu_anon_ram_alloc(size_t size);
 void qemu_vfree(void *ptr);
+void qemu_anon_ram_free(void *ptr, size_t size);
 
 #define QEMU_MADV_INVALID -1
 
@@ -108,6 +123,16 @@
 #else
 #define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
 #endif
+#ifdef MADV_DONTDUMP
+#define QEMU_MADV_DONTDUMP MADV_DONTDUMP
+#else
+#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
+#endif
+#ifdef MADV_HUGEPAGE
+#define QEMU_MADV_HUGEPAGE MADV_HUGEPAGE
+#else
+#define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID
+#endif
 
 #elif defined(CONFIG_POSIX_MADVISE)
 
@@ -115,6 +140,8 @@
 #define QEMU_MADV_DONTNEED  POSIX_MADV_DONTNEED
 #define QEMU_MADV_DONTFORK  QEMU_MADV_INVALID
 #define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
+#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
+#define QEMU_MADV_HUGEPAGE  QEMU_MADV_INVALID
 
 #else /* no-op */
 
@@ -122,14 +149,43 @@
 #define QEMU_MADV_DONTNEED  QEMU_MADV_INVALID
 #define QEMU_MADV_DONTFORK  QEMU_MADV_INVALID
 #define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
+#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
+#define QEMU_MADV_HUGEPAGE  QEMU_MADV_INVALID
 
 #endif
 
 int qemu_madvise(void *addr, size_t len, int advice);
 
+int qemu_open(const char *name, int flags, ...);
+int qemu_close(int fd);
+
+#if defined(__HAIKU__) && defined(__i386__)
+#define FMT_pid "%ld"
+#elif defined(WIN64)
+#define FMT_pid "%" PRId64
+#else
+#define FMT_pid "%d"
+#endif
+
 int qemu_create_pidfile(const char *filename);
 int qemu_get_thread_id(void);
 
+#ifndef CONFIG_IOVEC
+struct iovec {
+    void *iov_base;
+    size_t iov_len;
+};
+/*
+ * Use the same value as Linux for now.
+ */
+#define IOV_MAX 1024
+
+ssize_t readv(int fd, const struct iovec *iov, int iov_cnt);
+ssize_t writev(int fd, const struct iovec *iov, int iov_cnt);
+#else
+#include <sys/uio.h>
+#endif
+
 #ifdef _WIN32
 static inline void qemu_timersub(const struct timeval *val1,
                                  const struct timeval *val2,
@@ -148,9 +204,48 @@
 #define ffs __builtin_ffs
 #endif
 
-/* in osdep.c */
-#ifdef _WIN32
-int asprintf(char**, const char*, ...);
+void qemu_set_cloexec(int fd);
+
+void qemu_set_version(const char *);
+const char *qemu_get_version(void);
+
+void fips_set_state(bool requested);
+bool fips_get_state(void);
+
+/* Return a dynamically allocated pathname denoting a file or directory that is
+ * appropriate for storing local state.
+ *
+ * @relative_pathname need not start with a directory separator; one will be
+ * added automatically.
+ *
+ * The caller is responsible for releasing the value returned with g_free()
+ * after use.
+ */
+char *qemu_get_local_state_pathname(const char *relative_pathname);
+
+/**
+ * qemu_getauxval:
+ * @type: the auxiliary vector key to lookup
+ *
+ * Search the auxiliary vector for @type, returning the value
+ * or 0 if @type is not present.
+ */
+#if defined(CONFIG_GETAUXVAL) || defined(__linux__)
+unsigned long qemu_getauxval(unsigned long type);
+#else
+static inline unsigned long qemu_getauxval(unsigned long type) { return 0; }
+#endif
+
+/**
+ * qemu_init_auxval:
+ * @envp: the third argument to main
+ *
+ * If supported and required, locate the auxiliary vector at program startup.
+ */
+#if defined(CONFIG_GETAUXVAL) || !defined(__linux__)
+static inline void qemu_init_auxval(char **envp) { }
+#else
+void qemu_init_auxval(char **envp);
 #endif
 
 #endif
diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index 1d07745..d433b90 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -1,9 +1,9 @@
 /*      $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
- * the implementations.  Left in lists, simple queues, tail queues and
- * circular queues.
+ * QEMU version: Copy from netbsd, removed debug code, removed some of
+ * the implementations.  Left in singly-linked lists, lists, simple
+ * queues, and tail queues.
  */
 
 /*
@@ -41,8 +41,18 @@
 #define QEMU_SYS_QUEUE_H_
 
 /*
- * This file defines four types of data structures:
- * lists, simple queues, tail queues, and circular queues.
+ * This file defines four types of data structures: singly-linked lists,
+ * lists, simple queues, and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The
+ * elements are singly linked for minimum space and pointer manipulation
+ * overhead at the expense of O(n) removal for arbitrary elements. New
+ * elements can be added to the list after an existing element or at the
+ * head of the list.  Elements being removed from the head of the list
+ * should use the explicit macro for this purpose for optimum
+ * efficiency. A singly-linked list may only be traversed in the forward
+ * direction.  Singly-linked lists are ideal for applications with large
+ * datasets and few or no removals or for implementing a LIFO queue.
  *
  * A list is headed by a single forward pointer (or an array of forward
  * pointers for a hash table header). The elements are doubly linked
@@ -65,17 +75,11 @@
  * after an existing element, at the head of the list, or at the end of
  * the list. A tail queue may be traversed in either direction.
  *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
  * For details on the use of these macros, see the queue(3) manual page.
  */
 
+#include "qemu/atomic.h" /* for smp_wmb() */
+
 /*
  * List definitions.
  */
@@ -122,6 +126,17 @@
         (elm)->field.le_prev = &(head)->lh_first;                       \
 } while (/*CONSTCOND*/0)
 
+#define QLIST_INSERT_HEAD_RCU(head, elm, field) do {                    \
+        (elm)->field.le_prev = &(head)->lh_first;                       \
+        (elm)->field.le_next = (head)->lh_first;                        \
+        smp_wmb(); /* fill elm before linking it */                     \
+        if ((head)->lh_first != NULL)  {                                \
+            (head)->lh_first->field.le_prev = &(elm)->field.le_next;    \
+        }                                                               \
+        (head)->lh_first = (elm);                                       \
+        smp_wmb();                                                      \
+} while (/* CONSTCOND*/0)
+
 #define QLIST_REMOVE(elm, field) do {                                   \
         if ((elm)->field.le_next != NULL)                               \
                 (elm)->field.le_next->field.le_prev =                   \
@@ -148,6 +163,64 @@
 
 
 /*
+ * Singly-linked List definitions.
+ */
+#define QSLIST_HEAD(name, type)                                          \
+struct name {                                                           \
+        struct type *slh_first; /* first element */                     \
+}
+
+#define QSLIST_HEAD_INITIALIZER(head)                                    \
+        { NULL }
+
+#define QSLIST_ENTRY(type)                                               \
+struct {                                                                \
+        struct type *sle_next;  /* next element */                      \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define QSLIST_INIT(head) do {                                           \
+        (head)->slh_first = NULL;                                       \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_INSERT_AFTER(slistelm, elm, field) do {                   \
+        (elm)->field.sle_next = (slistelm)->field.sle_next;             \
+        (slistelm)->field.sle_next = (elm);                             \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_INSERT_HEAD(head, elm, field) do {                        \
+        (elm)->field.sle_next = (head)->slh_first;                      \
+        (head)->slh_first = (elm);                                      \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_REMOVE_HEAD(head, field) do {                             \
+        (head)->slh_first = (head)->slh_first->field.sle_next;          \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_REMOVE_AFTER(slistelm, field) do {                        \
+        (slistelm)->field.sle_next =                                    \
+            QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field);           \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_FOREACH(var, head, field)                                 \
+        for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
+
+#define QSLIST_FOREACH_SAFE(var, head, field, tvar)                      \
+        for ((var) = QSLIST_FIRST((head));                               \
+            (var) && ((tvar) = QSLIST_NEXT((var), field), 1);            \
+            (var) = (tvar))
+
+/*
+ * Singly-linked List access methods.
+ */
+#define QSLIST_EMPTY(head)       ((head)->slh_first == NULL)
+#define QSLIST_FIRST(head)       ((head)->slh_first)
+#define QSLIST_NEXT(elm, field)  ((elm)->field.sle_next)
+
+
+/*
  * Simple queue definitions.
  */
 #define QSIMPLEQ_HEAD(name, type)                                       \
@@ -338,112 +411,4 @@
 #define QTAILQ_PREV(elm, headname, field) \
         (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
 
-
-/*
- * Circular queue definitions.
- */
-#define QCIRCLEQ_HEAD(name, type)                                       \
-struct name {                                                           \
-        struct type *cqh_first;         /* first element */             \
-        struct type *cqh_last;          /* last element */              \
-}
-
-#define QCIRCLEQ_HEAD_INITIALIZER(head)                                 \
-        { (void *)&head, (void *)&head }
-
-#define QCIRCLEQ_ENTRY(type)                                            \
-struct {                                                                \
-        struct type *cqe_next;          /* next element */              \
-        struct type *cqe_prev;          /* previous element */          \
-}
-
-/*
- * Circular queue functions.
- */
-#define QCIRCLEQ_INIT(head) do {                                        \
-        (head)->cqh_first = (void *)(head);                             \
-        (head)->cqh_last = (void *)(head);                              \
-} while (/*CONSTCOND*/0)
-
-#define QCIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {           \
-        (elm)->field.cqe_next = (listelm)->field.cqe_next;              \
-        (elm)->field.cqe_prev = (listelm);                              \
-        if ((listelm)->field.cqe_next == (void *)(head))                \
-                (head)->cqh_last = (elm);                               \
-        else                                                            \
-                (listelm)->field.cqe_next->field.cqe_prev = (elm);      \
-        (listelm)->field.cqe_next = (elm);                              \
-} while (/*CONSTCOND*/0)
-
-#define QCIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {          \
-        (elm)->field.cqe_next = (listelm);                              \
-        (elm)->field.cqe_prev = (listelm)->field.cqe_prev;              \
-        if ((listelm)->field.cqe_prev == (void *)(head))                \
-                (head)->cqh_first = (elm);                              \
-        else                                                            \
-                (listelm)->field.cqe_prev->field.cqe_next = (elm);      \
-        (listelm)->field.cqe_prev = (elm);                              \
-} while (/*CONSTCOND*/0)
-
-#define QCIRCLEQ_INSERT_HEAD(head, elm, field) do {                     \
-        (elm)->field.cqe_next = (head)->cqh_first;                      \
-        (elm)->field.cqe_prev = (void *)(head);                         \
-        if ((head)->cqh_last == (void *)(head))                         \
-                (head)->cqh_last = (elm);                               \
-        else                                                            \
-                (head)->cqh_first->field.cqe_prev = (elm);              \
-        (head)->cqh_first = (elm);                                      \
-} while (/*CONSTCOND*/0)
-
-#define QCIRCLEQ_INSERT_TAIL(head, elm, field) do {                     \
-        (elm)->field.cqe_next = (void *)(head);                         \
-        (elm)->field.cqe_prev = (head)->cqh_last;                       \
-        if ((head)->cqh_first == (void *)(head))                        \
-                (head)->cqh_first = (elm);                              \
-        else                                                            \
-                (head)->cqh_last->field.cqe_next = (elm);               \
-        (head)->cqh_last = (elm);                                       \
-} while (/*CONSTCOND*/0)
-
-#define QCIRCLEQ_REMOVE(head, elm, field) do {                          \
-        if ((elm)->field.cqe_next == (void *)(head))                    \
-                (head)->cqh_last = (elm)->field.cqe_prev;               \
-        else                                                            \
-                (elm)->field.cqe_next->field.cqe_prev =                 \
-                    (elm)->field.cqe_prev;                              \
-        if ((elm)->field.cqe_prev == (void *)(head))                    \
-                (head)->cqh_first = (elm)->field.cqe_next;              \
-        else                                                            \
-                (elm)->field.cqe_prev->field.cqe_next =                 \
-                    (elm)->field.cqe_next;                              \
-} while (/*CONSTCOND*/0)
-
-#define QCIRCLEQ_FOREACH(var, head, field)                              \
-        for ((var) = ((head)->cqh_first);                               \
-                (var) != (const void *)(head);                          \
-                (var) = ((var)->field.cqe_next))
-
-#define QCIRCLEQ_FOREACH_REVERSE(var, head, field)                      \
-        for ((var) = ((head)->cqh_last);                                \
-                (var) != (const void *)(head);                          \
-                (var) = ((var)->field.cqe_prev))
-
-/*
- * Circular queue access methods.
- */
-#define QCIRCLEQ_EMPTY(head)             ((head)->cqh_first == (void *)(head))
-#define QCIRCLEQ_FIRST(head)             ((head)->cqh_first)
-#define QCIRCLEQ_LAST(head)              ((head)->cqh_last)
-#define QCIRCLEQ_NEXT(elm, field)        ((elm)->field.cqe_next)
-#define QCIRCLEQ_PREV(elm, field)        ((elm)->field.cqe_prev)
-
-#define QCIRCLEQ_LOOP_NEXT(head, elm, field)                            \
-        (((elm)->field.cqe_next == (void *)(head))                      \
-            ? ((head)->cqh_first)                                       \
-            : (elm->field.cqe_next))
-#define QCIRCLEQ_LOOP_PREV(head, elm, field)                            \
-        (((elm)->field.cqe_prev == (void *)(head))                      \
-            ? ((head)->cqh_last)                                        \
-            : (elm->field.cqe_prev))
-
 #endif  /* !QEMU_SYS_QUEUE_H_ */
diff --git a/include/qemu/range.h b/include/qemu/range.h
new file mode 100644
index 0000000..aae9720
--- /dev/null
+++ b/include/qemu/range.h
@@ -0,0 +1,63 @@
+#ifndef QEMU_RANGE_H
+#define QEMU_RANGE_H
+
+#include <inttypes.h>
+#include <qemu/typedefs.h>
+
+/*
+ * Operations on 64 bit address ranges.
+ * Notes:
+ *   - ranges must not wrap around 0, but can include the last byte ~0x0LL.
+ *   - this can not represent a full 0 to ~0x0LL range.
+ */
+
+/* A structure representing a range of addresses. */
+struct Range {
+    uint64_t begin; /* First byte of the range, or 0 if empty. */
+    uint64_t end;   /* 1 + the last byte. 0 if range empty or ends at ~0x0LL. */
+};
+
+static inline void range_extend(Range *range, Range *extend_by)
+{
+    if (!extend_by->begin && !extend_by->end) {
+        return;
+    }
+    if (!range->begin && !range->end) {
+        *range = *extend_by;
+        return;
+    }
+    if (range->begin > extend_by->begin) {
+        range->begin = extend_by->begin;
+    }
+    /* Compare last byte in case region ends at ~0x0LL */
+    if (range->end - 1 < extend_by->end - 1) {
+        range->end = extend_by->end;
+    }
+}
+
+/* Get last byte of a range from offset + length.
+ * Undefined for ranges that wrap around 0. */
+static inline uint64_t range_get_last(uint64_t offset, uint64_t len)
+{
+    return offset + len - 1;
+}
+
+/* Check whether a given range covers a given byte. */
+static inline int range_covers_byte(uint64_t offset, uint64_t len,
+                                    uint64_t byte)
+{
+    return offset <= byte && byte <= range_get_last(offset, len);
+}
+
+/* Check whether 2 given ranges overlap.
+ * Undefined if ranges that wrap around 0. */
+static inline int ranges_overlap(uint64_t first1, uint64_t len1,
+                                 uint64_t first2, uint64_t len2)
+{
+    uint64_t last1 = range_get_last(first1, len1);
+    uint64_t last2 = range_get_last(first2, len2);
+
+    return !(last2 < first1 || last1 < first2);
+}
+
+#endif
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 27a6f64..0639464 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -27,4 +27,6 @@
 int parse_host_src_port(SockAddress*  haddr, SockAddress*  saddr,
                         const char *str);
 
+void qemu_set_block(int fd);
+
 #endif /* QEMU__SOCKET_H */
diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h
new file mode 100644
index 0000000..eb5c7a1
--- /dev/null
+++ b/include/qemu/thread-posix.h
@@ -0,0 +1,36 @@
+#ifndef __QEMU_THREAD_POSIX_H
+#define __QEMU_THREAD_POSIX_H 1
+#include "pthread.h"
+#include <semaphore.h>
+
+struct QemuMutex {
+    pthread_mutex_t lock;
+};
+
+struct QemuCond {
+    pthread_cond_t cond;
+};
+
+struct QemuSemaphore {
+#if defined(__APPLE__) || defined(__NetBSD__)
+    pthread_mutex_t lock;
+    pthread_cond_t cond;
+    unsigned int count;
+#else
+    sem_t sem;
+#endif
+};
+
+struct QemuEvent {
+#ifndef __linux__
+    pthread_mutex_t lock;
+    pthread_cond_t cond;
+#endif
+    unsigned value;
+};
+
+struct QemuThread {
+    pthread_t thread;
+};
+
+#endif
diff --git a/include/qemu/thread-win32.h b/include/qemu/thread-win32.h
new file mode 100644
index 0000000..3d58081
--- /dev/null
+++ b/include/qemu/thread-win32.h
@@ -0,0 +1,33 @@
+#ifndef __QEMU_THREAD_WIN32_H
+#define __QEMU_THREAD_WIN32_H 1
+#include "windows.h"
+
+struct QemuMutex {
+    CRITICAL_SECTION lock;
+    LONG owner;
+};
+
+struct QemuCond {
+    LONG waiters, target;
+    HANDLE sema;
+    HANDLE continue_event;
+};
+
+struct QemuSemaphore {
+    HANDLE sema;
+};
+
+struct QemuEvent {
+    HANDLE event;
+};
+
+typedef struct QemuThreadData QemuThreadData;
+struct QemuThread {
+    QemuThreadData *data;
+    unsigned tid;
+};
+
+/* Only valid for joinable threads.  */
+HANDLE qemu_thread_get_handle(QemuThread *thread);
+
+#endif
diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index 19bb30c..6ff266a 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -1,24 +1,24 @@
 #ifndef __QEMU_THREAD_H
 #define __QEMU_THREAD_H 1
-#include "semaphore.h"
-#include "pthread.h"
 
-struct QemuMutex {
-    pthread_mutex_t lock;
-};
-
-struct QemuCond {
-    pthread_cond_t cond;
-};
-
-struct QemuThread {
-    pthread_t thread;
-};
+#include <inttypes.h>
+#include <stdbool.h>
 
 typedef struct QemuMutex QemuMutex;
 typedef struct QemuCond QemuCond;
+typedef struct QemuSemaphore QemuSemaphore;
+typedef struct QemuEvent QemuEvent;
 typedef struct QemuThread QemuThread;
 
+#ifdef _WIN32
+#include "qemu/thread-win32.h"
+#else
+#include "qemu/thread-posix.h"
+#endif
+
+#define QEMU_THREAD_JOINABLE 0
+#define QEMU_THREAD_DETACHED 1
+
 void qemu_mutex_init(QemuMutex *mutex);
 void qemu_mutex_destroy(QemuMutex *mutex);
 void qemu_mutex_lock(QemuMutex *mutex);
@@ -26,19 +26,40 @@
 int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs);
 void qemu_mutex_unlock(QemuMutex *mutex);
 
+#define rcu_read_lock() do { } while (0)
+#define rcu_read_unlock() do { } while (0)
+
 void qemu_cond_init(QemuCond *cond);
 void qemu_cond_destroy(QemuCond *cond);
+
+/*
+ * IMPORTANT: The implementation does not guarantee that pthread_cond_signal
+ * and pthread_cond_broadcast can be called except while the same mutex is
+ * held as in the corresponding pthread_cond_wait calls!
+ */
 void qemu_cond_signal(QemuCond *cond);
 void qemu_cond_broadcast(QemuCond *cond);
 void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex);
 int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs);
 
+void qemu_sem_init(QemuSemaphore *sem, int init);
+void qemu_sem_post(QemuSemaphore *sem);
+void qemu_sem_wait(QemuSemaphore *sem);
+int qemu_sem_timedwait(QemuSemaphore *sem, int ms);
+void qemu_sem_destroy(QemuSemaphore *sem);
+
+void qemu_event_init(QemuEvent *ev, bool init);
+void qemu_event_set(QemuEvent *ev);
+void qemu_event_reset(QemuEvent *ev);
+void qemu_event_wait(QemuEvent *ev);
+void qemu_event_destroy(QemuEvent *ev);
+
 void qemu_thread_create(QemuThread *thread,
-                       void *(*start_routine)(void*),
-                       void *arg);
-void qemu_thread_signal(QemuThread *thread, int sig);
-void qemu_thread_self(QemuThread *thread);
-int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2);
+                        void *(*start_routine)(void *),
+                        void *arg, int mode);
+void *qemu_thread_join(QemuThread *thread);
+void qemu_thread_get_self(QemuThread *thread);
+bool qemu_thread_is_self(QemuThread *thread);
 void qemu_thread_exit(void *retval);
 
 #endif
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index c84673a..cab38fa 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -36,10 +36,22 @@
    the virtual clock. */
 extern QEMUClock *host_clock;
 
+// TODO(digit): Hide this implementation detail.
+#define QEMU_CLOCK_REALTIME 0
+#define QEMU_CLOCK_VIRTUAL  1
+#define QEMU_CLOCK_HOST     2
+#define QEMU_NUM_CLOCKS 3
+
+extern QEMUTimer *active_timers[QEMU_NUM_CLOCKS];
+
 int64_t qemu_get_clock(QEMUClock *clock);
 int64_t qemu_get_clock_ns(QEMUClock *clock);
 void qemu_clock_enable(QEMUClock *clock, int enabled);
-void qemu_clock_warp(QEMUClock *clock);
+//void qemu_clock_warp(QEMUClock *clock);
+
+QEMUTimer* qemu_clock_get_warp_timer(QEMUClock *clock);
+int qemu_clock_has_active_timer(QEMUClock* clock);
+int64_t qemu_clock_next_deadline(QEMUClock* clock);
 
 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
                           QEMUTimerCB *cb, void *opaque);
@@ -50,6 +62,9 @@
 int qemu_timer_pending(QEMUTimer *ts);
 int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
 int qemu_timer_alarm_pending(void);
+void qemu_run_timers(QEMUClock *clock);
+
+void qemu_timer_register_savevm(void);
 
 void qemu_run_all_timers(void);
 int qemu_alarm_pending(void);
@@ -132,6 +147,8 @@
 }
 #endif
 
+extern int64_t cpu_get_clock(void);
+
 void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
 void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
 
@@ -313,19 +330,6 @@
 #endif
 
 #ifdef NEED_CPU_H
-/* Deterministic execution requires that IO only be performed on the last
-   instruction of a TB so that interrupts take effect immediately.  */
-static inline int can_do_io(CPUState *env)
-{
-    if (!use_icount)
-        return 1;
-
-    /* If not executing code then assume we are ok.  */
-    if (!env->current_tb)
-        return 1;
-
-    return env->can_do_io != 0;
-}
 #endif
 
 #ifdef CONFIG_PROFILER
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
new file mode 100644
index 0000000..db7f1d1
--- /dev/null
+++ b/include/qemu/typedefs.h
@@ -0,0 +1,81 @@
+#ifndef QEMU_TYPEDEFS_H
+#define QEMU_TYPEDEFS_H
+
+/* A load of opaque types so that device init declarations don't have to
+   pull in all the real definitions.  */
+typedef struct QEMUTimer QEMUTimer;
+typedef struct QEMUTimerListGroup QEMUTimerListGroup;
+typedef struct QEMUFile QEMUFile;
+typedef struct QEMUBH QEMUBH;
+
+typedef struct AioContext AioContext;
+
+struct Monitor;
+typedef struct Monitor Monitor;
+typedef struct MigrationParams MigrationParams;
+
+typedef struct Property Property;
+typedef struct PropertyInfo PropertyInfo;
+typedef struct CompatProperty CompatProperty;
+typedef struct DeviceState DeviceState;
+typedef struct BusState BusState;
+typedef struct BusClass BusClass;
+
+typedef struct AddressSpace AddressSpace;
+typedef struct MemoryRegion MemoryRegion;
+typedef struct MemoryRegionSection MemoryRegionSection;
+
+typedef struct MemoryMappingList MemoryMappingList;
+
+typedef struct NICInfo NICInfo;
+typedef struct HCIInfo HCIInfo;
+typedef struct AudioState AudioState;
+typedef struct BlockDriverState BlockDriverState;
+typedef struct DriveInfo DriveInfo;
+typedef struct DisplayState DisplayState;
+typedef struct DisplayChangeListener DisplayChangeListener;
+typedef struct DisplaySurface DisplaySurface;
+typedef struct PixelFormat PixelFormat;
+//typedef struct QemuConsole QemuConsole;  (see below)
+typedef struct CharDriverState CharDriverState;
+typedef struct MACAddr MACAddr;
+typedef struct NetClientState NetClientState;
+typedef struct i2c_bus i2c_bus;
+typedef struct ISABus ISABus;
+typedef struct ISADevice ISADevice;
+typedef struct SMBusDevice SMBusDevice;
+typedef struct PCIHostState PCIHostState;
+typedef struct PCIExpressHost PCIExpressHost;
+typedef struct PCIBus PCIBus;
+typedef struct PCIDevice PCIDevice;
+typedef struct PCIExpressDevice PCIExpressDevice;
+typedef struct PCIBridge PCIBridge;
+typedef struct PCIEAERMsg PCIEAERMsg;
+typedef struct PCIEAERLog PCIEAERLog;
+typedef struct PCIEAERErr PCIEAERErr;
+typedef struct PCIEPort PCIEPort;
+typedef struct PCIESlot PCIESlot;
+typedef struct MSIMessage MSIMessage;
+typedef struct SerialState SerialState;
+typedef struct PCMCIACardState PCMCIACardState;
+typedef struct MouseTransformInfo MouseTransformInfo;
+typedef struct uWireSlave uWireSlave;
+typedef struct I2SCodec I2SCodec;
+typedef struct SSIBus SSIBus;
+typedef struct EventNotifier EventNotifier;
+typedef struct VirtIODevice VirtIODevice;
+typedef struct QEMUSGList QEMUSGList;
+typedef struct SHPCDevice SHPCDevice;
+typedef struct FWCfgState FWCfgState;
+typedef struct PcGuestInfo PcGuestInfo;
+typedef struct Range Range;
+
+// NOTE(digit): Remove typedefs below when everything is upstreamed.
+typedef struct DisplayAllocator DisplayAllocator;
+typedef struct IRQState *qemu_irq;
+typedef struct TextConsole TextConsole;
+typedef TextConsole QEMUConsole;
+typedef struct VLANState VLANState;
+typedef struct VLANClientState VLANClientState;
+
+#endif /* QEMU_TYPEDEFS_H */
diff --git a/include/qom/object.h b/include/qom/object.h
new file mode 100644
index 0000000..a275db2
--- /dev/null
+++ b/include/qom/object.h
@@ -0,0 +1,1194 @@
+/*
+ * QEMU Object Model
+ *
+ * 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 QEMU_OBJECT_H
+#define QEMU_OBJECT_H
+
+#include <glib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "qemu/queue.h"
+#include "qapi/error.h"
+
+struct Visitor;
+
+struct TypeImpl;
+typedef struct TypeImpl *Type;
+
+typedef struct ObjectClass ObjectClass;
+typedef struct Object Object;
+
+typedef struct TypeInfo TypeInfo;
+
+typedef struct InterfaceClass InterfaceClass;
+typedef struct InterfaceInfo InterfaceInfo;
+
+#define TYPE_OBJECT "object"
+
+/**
+ * SECTION:object.h
+ * @title:Base Object Type System
+ * @short_description: interfaces for creating new types and objects
+ *
+ * The QEMU Object Model provides a framework for registering user creatable
+ * types and instantiating objects from those types.  QOM provides the following
+ * features:
+ *
+ *  - System for dynamically registering types
+ *  - Support for single-inheritance of types
+ *  - Multiple inheritance of stateless interfaces
+ *
+ * <example>
+ *   <title>Creating a minimal type</title>
+ *   <programlisting>
+ * #include "qdev.h"
+ *
+ * #define TYPE_MY_DEVICE "my-device"
+ *
+ * // No new virtual functions: we can reuse the typedef for the
+ * // superclass.
+ * typedef DeviceClass MyDeviceClass;
+ * typedef struct MyDevice
+ * {
+ *     DeviceState parent;
+ *
+ *     int reg0, reg1, reg2;
+ * } MyDevice;
+ *
+ * static const TypeInfo my_device_info = {
+ *     .name = TYPE_MY_DEVICE,
+ *     .parent = TYPE_DEVICE,
+ *     .instance_size = sizeof(MyDevice),
+ * };
+ *
+ * static void my_device_register_types(void)
+ * {
+ *     type_register_static(&my_device_info);
+ * }
+ *
+ * type_init(my_device_register_types)
+ *   </programlisting>
+ * </example>
+ *
+ * In the above example, we create a simple type that is described by #TypeInfo.
+ * #TypeInfo describes information about the type including what it inherits
+ * from, the instance and class size, and constructor/destructor hooks.
+ *
+ * Every type has an #ObjectClass associated with it.  #ObjectClass derivatives
+ * are instantiated dynamically but there is only ever one instance for any
+ * given type.  The #ObjectClass typically holds a table of function pointers
+ * for the virtual methods implemented by this type.
+ *
+ * Using object_new(), a new #Object derivative will be instantiated.  You can
+ * cast an #Object to a subclass (or base-class) type using
+ * object_dynamic_cast().  You typically want to define macro wrappers around
+ * OBJECT_CHECK() and OBJECT_CLASS_CHECK() to make it easier to convert to a
+ * specific type:
+ *
+ * <example>
+ *   <title>Typecasting macros</title>
+ *   <programlisting>
+ *    #define MY_DEVICE_GET_CLASS(obj) \
+ *       OBJECT_GET_CLASS(MyDeviceClass, obj, TYPE_MY_DEVICE)
+ *    #define MY_DEVICE_CLASS(klass) \
+ *       OBJECT_CLASS_CHECK(MyDeviceClass, klass, TYPE_MY_DEVICE)
+ *    #define MY_DEVICE(obj) \
+ *       OBJECT_CHECK(MyDevice, obj, TYPE_MY_DEVICE)
+ *   </programlisting>
+ * </example>
+ *
+ * # Class Initialization #
+ *
+ * Before an object is initialized, the class for the object must be
+ * initialized.  There is only one class object for all instance objects
+ * that is created lazily.
+ *
+ * Classes are initialized by first initializing any parent classes (if
+ * necessary).  After the parent class object has initialized, it will be
+ * copied into the current class object and any additional storage in the
+ * class object is zero filled.
+ *
+ * The effect of this is that classes automatically inherit any virtual
+ * function pointers that the parent class has already initialized.  All
+ * other fields will be zero filled.
+ *
+ * Once all of the parent classes have been initialized, #TypeInfo::class_init
+ * is called to let the class being instantiated provide default initialize for
+ * its virtual functions.  Here is how the above example might be modified
+ * to introduce an overridden virtual function:
+ *
+ * <example>
+ *   <title>Overriding a virtual function</title>
+ *   <programlisting>
+ * #include "qdev.h"
+ *
+ * void my_device_class_init(ObjectClass *klass, void *class_data)
+ * {
+ *     DeviceClass *dc = DEVICE_CLASS(klass);
+ *     dc->reset = my_device_reset;
+ * }
+ *
+ * static const TypeInfo my_device_info = {
+ *     .name = TYPE_MY_DEVICE,
+ *     .parent = TYPE_DEVICE,
+ *     .instance_size = sizeof(MyDevice),
+ *     .class_init = my_device_class_init,
+ * };
+ *   </programlisting>
+ * </example>
+ *
+ * Introducing new virtual methods requires a class to define its own
+ * struct and to add a .class_size member to the #TypeInfo.  Each method
+ * will also have a wrapper function to call it easily:
+ *
+ * <example>
+ *   <title>Defining an abstract class</title>
+ *   <programlisting>
+ * #include "qdev.h"
+ *
+ * typedef struct MyDeviceClass
+ * {
+ *     DeviceClass parent;
+ *
+ *     void (*frobnicate) (MyDevice *obj);
+ * } MyDeviceClass;
+ *
+ * static const TypeInfo my_device_info = {
+ *     .name = TYPE_MY_DEVICE,
+ *     .parent = TYPE_DEVICE,
+ *     .instance_size = sizeof(MyDevice),
+ *     .abstract = true, // or set a default in my_device_class_init
+ *     .class_size = sizeof(MyDeviceClass),
+ * };
+ *
+ * void my_device_frobnicate(MyDevice *obj)
+ * {
+ *     MyDeviceClass *klass = MY_DEVICE_GET_CLASS(obj);
+ *
+ *     klass->frobnicate(obj);
+ * }
+ *   </programlisting>
+ * </example>
+ *
+ * # Interfaces #
+ *
+ * Interfaces allow a limited form of multiple inheritance.  Instances are
+ * similar to normal types except for the fact that are only defined by
+ * their classes and never carry any state.  You can dynamically cast an object
+ * to one of its #Interface types and vice versa.
+ *
+ * # Methods #
+ *
+ * A <emphasis>method</emphasis> is a function within the namespace scope of
+ * a class. It usually operates on the object instance by passing it as a
+ * strongly-typed first argument.
+ * If it does not operate on an object instance, it is dubbed
+ * <emphasis>class method</emphasis>.
+ *
+ * Methods cannot be overloaded. That is, the #ObjectClass and method name
+ * uniquely identity the function to be called; the signature does not vary
+ * except for trailing varargs.
+ *
+ * Methods are always <emphasis>virtual</emphasis>. Overriding a method in
+ * #TypeInfo.class_init of a subclass leads to any user of the class obtained
+ * via OBJECT_GET_CLASS() accessing the overridden function.
+ * The original function is not automatically invoked. It is the responsibility
+ * of the overriding class to determine whether and when to invoke the method
+ * being overridden.
+ *
+ * To invoke the method being overridden, the preferred solution is to store
+ * the original value in the overriding class before overriding the method.
+ * This corresponds to |[ {super,base}.method(...) ]| in Java and C#
+ * respectively; this frees the overriding class from hardcoding its parent
+ * class, which someone might choose to change at some point.
+ *
+ * <example>
+ *   <title>Overriding a virtual method</title>
+ *   <programlisting>
+ * typedef struct MyState MyState;
+ *
+ * typedef void (*MyDoSomething)(MyState *obj);
+ *
+ * typedef struct MyClass {
+ *     ObjectClass parent_class;
+ *
+ *     MyDoSomething do_something;
+ * } MyClass;
+ *
+ * static void my_do_something(MyState *obj)
+ * {
+ *     // do something
+ * }
+ *
+ * static void my_class_init(ObjectClass *oc, void *data)
+ * {
+ *     MyClass *mc = MY_CLASS(oc);
+ *
+ *     mc->do_something = my_do_something;
+ * }
+ *
+ * static const TypeInfo my_type_info = {
+ *     .name = TYPE_MY,
+ *     .parent = TYPE_OBJECT,
+ *     .instance_size = sizeof(MyState),
+ *     .class_size = sizeof(MyClass),
+ *     .class_init = my_class_init,
+ * };
+ *
+ * typedef struct DerivedClass {
+ *     MyClass parent_class;
+ *
+ *     MyDoSomething parent_do_something;
+ * } DerivedClass;
+ *
+ * static void derived_do_something(MyState *obj)
+ * {
+ *     DerivedClass *dc = DERIVED_GET_CLASS(obj);
+ *
+ *     // do something here
+ *     dc->parent_do_something(obj);
+ *     // do something else here
+ * }
+ *
+ * static void derived_class_init(ObjectClass *oc, void *data)
+ * {
+ *     MyClass *mc = MY_CLASS(oc);
+ *     DerivedClass *dc = DERIVED_CLASS(oc);
+ *
+ *     dc->parent_do_something = mc->do_something;
+ *     mc->do_something = derived_do_something;
+ * }
+ *
+ * static const TypeInfo derived_type_info = {
+ *     .name = TYPE_DERIVED,
+ *     .parent = TYPE_MY,
+ *     .class_size = sizeof(DerivedClass),
+ *     .class_init = my_class_init,
+ * };
+ *   </programlisting>
+ * </example>
+ *
+ * Alternatively, object_class_by_name() can be used to obtain the class and
+ * its non-overridden methods for a specific type. This would correspond to
+ * |[ MyClass::method(...) ]| in C++.
+ *
+ * The first example of such a QOM method was #CPUClass.reset,
+ * another example is #DeviceClass.realize.
+ */
+
+
+/**
+ * ObjectPropertyAccessor:
+ * @obj: the object that owns the property
+ * @v: the visitor that contains the property data
+ * @opaque: the object property opaque
+ * @name: the name of the property
+ * @errp: a pointer to an Error that is filled if getting/setting fails.
+ *
+ * Called when trying to get/set a property.
+ */
+typedef void (ObjectPropertyAccessor)(Object *obj,
+                                      struct Visitor *v,
+                                      void *opaque,
+                                      const char *name,
+                                      Error **errp);
+
+/**
+ * ObjectPropertyRelease:
+ * @obj: the object that owns the property
+ * @name: the name of the property
+ * @opaque: the opaque registered with the property
+ *
+ * Called when a property is removed from a object.
+ */
+typedef void (ObjectPropertyRelease)(Object *obj,
+                                     const char *name,
+                                     void *opaque);
+
+typedef struct ObjectProperty
+{
+    gchar *name;
+    gchar *type;
+    ObjectPropertyAccessor *get;
+    ObjectPropertyAccessor *set;
+    ObjectPropertyRelease *release;
+    void *opaque;
+
+    QTAILQ_ENTRY(ObjectProperty) node;
+} ObjectProperty;
+
+/**
+ * ObjectUnparent:
+ * @obj: the object that is being removed from the composition tree
+ *
+ * Called when an object is being removed from the QOM composition tree.
+ * The function should remove any backlinks from children objects to @obj.
+ */
+typedef void (ObjectUnparent)(Object *obj);
+
+/**
+ * ObjectFree:
+ * @obj: the object being freed
+ *
+ * Called when an object's last reference is removed.
+ */
+typedef void (ObjectFree)(void *obj);
+
+#define OBJECT_CLASS_CAST_CACHE 4
+
+/**
+ * ObjectClass:
+ *
+ * The base for all classes.  The only thing that #ObjectClass contains is an
+ * integer type handle.
+ */
+struct ObjectClass
+{
+    /*< private >*/
+    Type type;
+    GSList *interfaces;
+
+    const char *cast_cache[OBJECT_CLASS_CAST_CACHE];
+
+    ObjectUnparent *unparent;
+};
+
+/**
+ * Object:
+ *
+ * The base for all objects.  The first member of this object is a pointer to
+ * a #ObjectClass.  Since C guarantees that the first member of a structure
+ * always begins at byte 0 of that structure, as long as any sub-object places
+ * its parent as the first member, we can cast directly to a #Object.
+ *
+ * As a result, #Object contains a reference to the objects type as its
+ * first member.  This allows identification of the real type of the object at
+ * run time.
+ *
+ * #Object also contains a list of #Interfaces that this object
+ * implements.
+ */
+struct Object
+{
+    /*< private >*/
+    ObjectClass *class;
+    ObjectFree *free;
+    QTAILQ_HEAD(, ObjectProperty) properties;
+    uint32_t ref;
+    Object *parent;
+};
+
+/**
+ * TypeInfo:
+ * @name: The name of the type.
+ * @parent: The name of the parent type.
+ * @instance_size: The size of the object (derivative of #Object).  If
+ *   @instance_size is 0, then the size of the object will be the size of the
+ *   parent object.
+ * @instance_init: This function is called to initialize an object.  The parent
+ *   class will have already been initialized so the type is only responsible
+ *   for initializing its own members.
+ * @instance_post_init: This function is called to finish initialization of
+ *   an object, after all @instance_init functions were called.
+ * @instance_finalize: This function is called during object destruction.  This
+ *   is called before the parent @instance_finalize function has been called.
+ *   An object should only free the members that are unique to its type in this
+ *   function.
+ * @abstract: If this field is true, then the class is considered abstract and
+ *   cannot be directly instantiated.
+ * @class_size: The size of the class object (derivative of #ObjectClass)
+ *   for this object.  If @class_size is 0, then the size of the class will be
+ *   assumed to be the size of the parent class.  This allows a type to avoid
+ *   implementing an explicit class type if they are not adding additional
+ *   virtual functions.
+ * @class_init: This function is called after all parent class initialization
+ *   has occurred to allow a class to set its default virtual method pointers.
+ *   This is also the function to use to override virtual methods from a parent
+ *   class.
+ * @class_base_init: This function is called for all base classes after all
+ *   parent class initialization has occurred, but before the class itself
+ *   is initialized.  This is the function to use to undo the effects of
+ *   memcpy from the parent class to the descendents.
+ * @class_finalize: This function is called during class destruction and is
+ *   meant to release and dynamic parameters allocated by @class_init.
+ * @class_data: Data to pass to the @class_init, @class_base_init and
+ *   @class_finalize functions.  This can be useful when building dynamic
+ *   classes.
+ * @interfaces: The list of interfaces associated with this type.  This
+ *   should point to a static array that's terminated with a zero filled
+ *   element.
+ */
+struct TypeInfo
+{
+    const char *name;
+    const char *parent;
+
+    size_t instance_size;
+    void (*instance_init)(Object *obj);
+    void (*instance_post_init)(Object *obj);
+    void (*instance_finalize)(Object *obj);
+
+    bool abstract;
+    size_t class_size;
+
+    void (*class_init)(ObjectClass *klass, void *data);
+    void (*class_base_init)(ObjectClass *klass, void *data);
+    void (*class_finalize)(ObjectClass *klass, void *data);
+    void *class_data;
+
+    InterfaceInfo *interfaces;
+};
+
+/**
+ * OBJECT:
+ * @obj: A derivative of #Object
+ *
+ * Converts an object to a #Object.  Since all objects are #Objects,
+ * this function will always succeed.
+ */
+#define OBJECT(obj) \
+    ((Object *)(obj))
+
+/**
+ * OBJECT_CLASS:
+ * @class: A derivative of #ObjectClass.
+ *
+ * Converts a class to an #ObjectClass.  Since all objects are #Objects,
+ * this function will always succeed.
+ */
+#define OBJECT_CLASS(class) \
+    ((ObjectClass *)(class))
+
+/**
+ * OBJECT_CHECK:
+ * @type: The C type to use for the return value.
+ * @obj: A derivative of @type to cast.
+ * @name: The QOM typename of @type
+ *
+ * A type safe version of @object_dynamic_cast_assert.  Typically each class
+ * will define a macro based on this type to perform type safe dynamic_casts to
+ * this object type.
+ *
+ * If an invalid object is passed to this function, a run time assert will be
+ * generated.
+ */
+#define OBJECT_CHECK(type, obj, name) \
+    ((type *)object_dynamic_cast_assert(OBJECT(obj), (name), \
+                                        __FILE__, __LINE__, __func__))
+
+/**
+ * OBJECT_CLASS_CHECK:
+ * @class: The C type to use for the return value.
+ * @obj: A derivative of @type to cast.
+ * @name: the QOM typename of @class.
+ *
+ * A type safe version of @object_class_dynamic_cast_assert.  This macro is
+ * typically wrapped by each type to perform type safe casts of a class to a
+ * specific class type.
+ */
+#define OBJECT_CLASS_CHECK(class, obj, name) \
+    ((class *)object_class_dynamic_cast_assert(OBJECT_CLASS(obj), (name), \
+                                               __FILE__, __LINE__, __func__))
+
+/**
+ * OBJECT_GET_CLASS:
+ * @class: The C type to use for the return value.
+ * @obj: The object to obtain the class for.
+ * @name: The QOM typename of @obj.
+ *
+ * This function will return a specific class for a given object.  Its generally
+ * used by each type to provide a type safe macro to get a specific class type
+ * from an object.
+ */
+#define OBJECT_GET_CLASS(class, obj, name) \
+    OBJECT_CLASS_CHECK(class, object_get_class(OBJECT(obj)), name)
+
+/**
+ * InterfaceInfo:
+ * @type: The name of the interface.
+ *
+ * The information associated with an interface.
+ */
+struct InterfaceInfo {
+    const char *type;
+};
+
+/**
+ * InterfaceClass:
+ * @parent_class: the base class
+ *
+ * The class for all interfaces.  Subclasses of this class should only add
+ * virtual methods.
+ */
+struct InterfaceClass
+{
+    ObjectClass parent_class;
+    /*< private >*/
+    ObjectClass *concrete_class;
+};
+
+#define TYPE_INTERFACE "interface"
+
+/**
+ * INTERFACE_CLASS:
+ * @klass: class to cast from
+ * Returns: An #InterfaceClass or raise an error if cast is invalid
+ */
+#define INTERFACE_CLASS(klass) \
+    OBJECT_CLASS_CHECK(InterfaceClass, klass, TYPE_INTERFACE)
+
+/**
+ * INTERFACE_CHECK:
+ * @interface: the type to return
+ * @obj: the object to convert to an interface
+ * @name: the interface type name
+ *
+ * Returns: @obj casted to @interface if cast is valid, otherwise raise error.
+ */
+#define INTERFACE_CHECK(interface, obj, name) \
+    ((interface *)object_dynamic_cast_assert(OBJECT((obj)), (name), \
+                                             __FILE__, __LINE__, __func__))
+
+/**
+ * object_new:
+ * @typename: The name of the type of the object to instantiate.
+ *
+ * This function will initialize a new object using heap allocated memory.
+ * The returned object has a reference count of 1, and will be freed when
+ * the last reference is dropped.
+ *
+ * Returns: The newly allocated and instantiated object.
+ */
+Object *object_new(const char *typename);
+
+/**
+ * object_new_with_type:
+ * @type: The type of the object to instantiate.
+ *
+ * This function will initialize a new object using heap allocated memory.
+ * The returned object has a reference count of 1, and will be freed when
+ * the last reference is dropped.
+ *
+ * Returns: The newly allocated and instantiated object.
+ */
+Object *object_new_with_type(Type type);
+
+/**
+ * object_initialize_with_type:
+ * @data: A pointer to the memory to be used for the object.
+ * @size: The maximum size available at @data for the object.
+ * @type: The type of the object to instantiate.
+ *
+ * This function will initialize an object.  The memory for the object should
+ * have already been allocated.  The returned object has a reference count of 1,
+ * and will be finalized when the last reference is dropped.
+ */
+void object_initialize_with_type(void *data, size_t size, Type type);
+
+/**
+ * object_initialize:
+ * @obj: A pointer to the memory to be used for the object.
+ * @size: The maximum size available at @obj for the object.
+ * @typename: The name of the type of the object to instantiate.
+ *
+ * This function will initialize an object.  The memory for the object should
+ * have already been allocated.  The returned object has a reference count of 1,
+ * and will be finalized when the last reference is dropped.
+ */
+void object_initialize(void *obj, size_t size, const char *typename);
+
+/**
+ * object_dynamic_cast:
+ * @obj: The object to cast.
+ * @typename: The @typename to cast to.
+ *
+ * This function will determine if @obj is-a @typename.  @obj can refer to an
+ * object or an interface associated with an object.
+ *
+ * Returns: This function returns @obj on success or #NULL on failure.
+ */
+Object *object_dynamic_cast(Object *obj, const char *typename);
+
+/**
+ * object_dynamic_cast_assert:
+ *
+ * See object_dynamic_cast() for a description of the parameters of this
+ * function.  The only difference in behavior is that this function asserts
+ * instead of returning #NULL on failure if QOM cast debugging is enabled.
+ * This function is not meant to be called directly, but only through
+ * the wrapper macro OBJECT_CHECK.
+ */
+Object *object_dynamic_cast_assert(Object *obj, const char *typename,
+                                   const char *file, int line, const char *func);
+
+/**
+ * object_get_class:
+ * @obj: A derivative of #Object
+ *
+ * Returns: The #ObjectClass of the type associated with @obj.
+ */
+ObjectClass *object_get_class(Object *obj);
+
+/**
+ * object_get_typename:
+ * @obj: A derivative of #Object.
+ *
+ * Returns: The QOM typename of @obj.
+ */
+const char *object_get_typename(Object *obj);
+
+/**
+ * type_register_static:
+ * @info: The #TypeInfo of the new type.
+ *
+ * @info and all of the strings it points to should exist for the life time
+ * that the type is registered.
+ *
+ * Returns: 0 on failure, the new #Type on success.
+ */
+Type type_register_static(const TypeInfo *info);
+
+/**
+ * type_register:
+ * @info: The #TypeInfo of the new type
+ *
+ * Unlike type_register_static(), this call does not require @info or its
+ * string members to continue to exist after the call returns.
+ *
+ * Returns: 0 on failure, the new #Type on success.
+ */
+Type type_register(const TypeInfo *info);
+
+/**
+ * object_class_dynamic_cast_assert:
+ * @klass: The #ObjectClass to attempt to cast.
+ * @typename: The QOM typename of the class to cast to.
+ *
+ * See object_class_dynamic_cast() for a description of the parameters
+ * of this function.  The only difference in behavior is that this function
+ * asserts instead of returning #NULL on failure if QOM cast debugging is
+ * enabled.  This function is not meant to be called directly, but only through
+ * the wrapper macros OBJECT_CLASS_CHECK and INTERFACE_CHECK.
+ */
+ObjectClass *object_class_dynamic_cast_assert(ObjectClass *klass,
+                                              const char *typename,
+                                              const char *file, int line,
+                                              const char *func);
+
+/**
+ * object_class_dynamic_cast:
+ * @klass: The #ObjectClass to attempt to cast.
+ * @typename: The QOM typename of the class to cast to.
+ *
+ * Returns: If @typename is a class, this function returns @klass if
+ * @typename is a subtype of @klass, else returns #NULL.
+ *
+ * If @typename is an interface, this function returns the interface
+ * definition for @klass if @klass implements it unambiguously; #NULL
+ * is returned if @klass does not implement the interface or if multiple
+ * classes or interfaces on the hierarchy leading to @klass implement
+ * it.  (FIXME: perhaps this can be detected at type definition time?)
+ */
+ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
+                                       const char *typename);
+
+/**
+ * object_class_get_parent:
+ * @klass: The class to obtain the parent for.
+ *
+ * Returns: The parent for @klass or %NULL if none.
+ */
+ObjectClass *object_class_get_parent(ObjectClass *klass);
+
+/**
+ * object_class_get_name:
+ * @klass: The class to obtain the QOM typename for.
+ *
+ * Returns: The QOM typename for @klass.
+ */
+const char *object_class_get_name(ObjectClass *klass);
+
+/**
+ * object_class_is_abstract:
+ * @klass: The class to obtain the abstractness for.
+ *
+ * Returns: %true if @klass is abstract, %false otherwise.
+ */
+bool object_class_is_abstract(ObjectClass *klass);
+
+/**
+ * object_class_by_name:
+ * @typename: The QOM typename to obtain the class for.
+ *
+ * Returns: The class for @typename or %NULL if not found.
+ */
+ObjectClass *object_class_by_name(const char *typename);
+
+void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
+                          const char *implements_type, bool include_abstract,
+                          void *opaque);
+
+/**
+ * object_class_get_list:
+ * @implements_type: The type to filter for, including its derivatives.
+ * @include_abstract: Whether to include abstract classes.
+ *
+ * Returns: A singly-linked list of the classes in reverse hashtable order.
+ */
+GSList *object_class_get_list(const char *implements_type,
+                              bool include_abstract);
+
+/**
+ * object_ref:
+ * @obj: the object
+ *
+ * Increase the reference count of a object.  A object cannot be freed as long
+ * as its reference count is greater than zero.
+ */
+void object_ref(Object *obj);
+
+/**
+ * qdef_unref:
+ * @obj: the object
+ *
+ * Decrease the reference count of a object.  A object cannot be freed as long
+ * as its reference count is greater than zero.
+ */
+void object_unref(Object *obj);
+
+/**
+ * object_property_add:
+ * @obj: the object to add a property to
+ * @name: the name of the property.  This can contain any character except for
+ *  a forward slash.  In general, you should use hyphens '-' instead of
+ *  underscores '_' when naming properties.
+ * @type: the type name of the property.  This namespace is pretty loosely
+ *   defined.  Sub namespaces are constructed by using a prefix and then
+ *   to angle brackets.  For instance, the type 'virtio-net-pci' in the
+ *   'link' namespace would be 'link<virtio-net-pci>'.
+ * @get: The getter to be called to read a property.  If this is NULL, then
+ *   the property cannot be read.
+ * @set: the setter to be called to write a property.  If this is NULL,
+ *   then the property cannot be written.
+ * @release: called when the property is removed from the object.  This is
+ *   meant to allow a property to free its opaque upon object
+ *   destruction.  This may be NULL.
+ * @opaque: an opaque pointer to pass to the callbacks for the property
+ * @errp: returns an error if this function fails
+ */
+void object_property_add(Object *obj, const char *name, const char *type,
+                         ObjectPropertyAccessor *get,
+                         ObjectPropertyAccessor *set,
+                         ObjectPropertyRelease *release,
+                         void *opaque, Error **errp);
+
+void object_property_del(Object *obj, const char *name, Error **errp);
+
+/**
+ * object_property_find:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Look up a property for an object and return its #ObjectProperty if found.
+ */
+ObjectProperty *object_property_find(Object *obj, const char *name,
+                                     Error **errp);
+
+void object_unparent(Object *obj);
+
+/**
+ * object_property_get:
+ * @obj: the object
+ * @v: the visitor that will receive the property value.  This should be an
+ *   Output visitor and the data will be written with @name as the name.
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Reads a property from a object.
+ */
+void object_property_get(Object *obj, struct Visitor *v, const char *name,
+                         Error **errp);
+
+/**
+ * object_property_set_str:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes a string value to a property.
+ */
+void object_property_set_str(Object *obj, const char *value,
+                             const char *name, Error **errp);
+
+/**
+ * object_property_get_str:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to a C string, or NULL if
+ * an error occurs (including when the property value is not a string).
+ * The caller should free the string.
+ */
+char *object_property_get_str(Object *obj, const char *name,
+                              Error **errp);
+
+/**
+ * object_property_set_link:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes an object's canonical path to a property.
+ */
+void object_property_set_link(Object *obj, Object *value,
+                              const char *name, Error **errp);
+
+/**
+ * object_property_get_link:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, resolved from a path to an Object,
+ * or NULL if an error occurs (including when the property value is not a
+ * string or not a valid object path).
+ */
+Object *object_property_get_link(Object *obj, const char *name,
+                                 Error **errp);
+
+/**
+ * object_property_set_bool:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes a bool value to a property.
+ */
+void object_property_set_bool(Object *obj, bool value,
+                              const char *name, Error **errp);
+
+/**
+ * object_property_get_bool:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to a boolean, or NULL if
+ * an error occurs (including when the property value is not a bool).
+ */
+bool object_property_get_bool(Object *obj, const char *name,
+                              Error **errp);
+
+/**
+ * object_property_set_int:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes an integer value to a property.
+ */
+void object_property_set_int(Object *obj, int64_t value,
+                             const char *name, Error **errp);
+
+/**
+ * object_property_get_int:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to an integer, or NULL if
+ * an error occurs (including when the property value is not an integer).
+ */
+int64_t object_property_get_int(Object *obj, const char *name,
+                                Error **errp);
+
+/**
+ * object_property_set:
+ * @obj: the object
+ * @v: the visitor that will be used to write the property value.  This should
+ *   be an Input visitor and the data will be first read with @name as the
+ *   name and then written as the property value.
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes a property to a object.
+ */
+void object_property_set(Object *obj, struct Visitor *v, const char *name,
+                         Error **errp);
+
+/**
+ * object_property_parse:
+ * @obj: the object
+ * @string: the string that will be used to parse the property value.
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Parses a string and writes the result into a property of an object.
+ */
+void object_property_parse(Object *obj, const char *string,
+                           const char *name, Error **errp);
+
+/**
+ * object_property_print:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns a string representation of the value of the property.  The
+ * caller shall free the string.
+ */
+char *object_property_print(Object *obj, const char *name,
+                            Error **errp);
+
+/**
+ * object_property_get_type:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns:  The type name of the property.
+ */
+const char *object_property_get_type(Object *obj, const char *name,
+                                     Error **errp);
+
+/**
+ * object_get_root:
+ *
+ * Returns: the root object of the composition tree
+ */
+Object *object_get_root(void);
+
+/**
+ * object_get_canonical_path:
+ *
+ * Returns: The canonical path for a object.  This is the path within the
+ * composition tree starting from the root.
+ */
+gchar *object_get_canonical_path(Object *obj);
+
+/**
+ * object_resolve_path:
+ * @path: the path to resolve
+ * @ambiguous: returns true if the path resolution failed because of an
+ *   ambiguous match
+ *
+ * There are two types of supported paths--absolute paths and partial paths.
+ * 
+ * Absolute paths are derived from the root object and can follow child<> or
+ * link<> properties.  Since they can follow link<> properties, they can be
+ * arbitrarily long.  Absolute paths look like absolute filenames and are
+ * prefixed with a leading slash.
+ * 
+ * Partial paths look like relative filenames.  They do not begin with a
+ * prefix.  The matching rules for partial paths are subtle but designed to make
+ * specifying objects easy.  At each level of the composition tree, the partial
+ * path is matched as an absolute path.  The first match is not returned.  At
+ * least two matches are searched for.  A successful result is only returned if
+ * only one match is found.  If more than one match is found, a flag is
+ * returned to indicate that the match was ambiguous.
+ *
+ * Returns: The matched object or NULL on path lookup failure.
+ */
+Object *object_resolve_path(const char *path, bool *ambiguous);
+
+/**
+ * object_resolve_path_type:
+ * @path: the path to resolve
+ * @typename: the type to look for.
+ * @ambiguous: returns true if the path resolution failed because of an
+ *   ambiguous match
+ *
+ * This is similar to object_resolve_path.  However, when looking for a
+ * partial path only matches that implement the given type are considered.
+ * This restricts the search and avoids spuriously flagging matches as
+ * ambiguous.
+ *
+ * For both partial and absolute paths, the return value goes through
+ * a dynamic cast to @typename.  This is important if either the link,
+ * or the typename itself are of interface types.
+ *
+ * Returns: The matched object or NULL on path lookup failure.
+ */
+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, const gchar *part);
+
+/**
+ * object_property_add_child:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @child: the child object
+ * @errp: if an error occurs, a pointer to an area to store the area
+ *
+ * Child properties form the composition tree.  All objects need to be a child
+ * of another object.  Objects can only be a child of one object.
+ *
+ * There is no way for a child to determine what its parent is.  It is not
+ * a bidirectional relationship.  This is by design.
+ *
+ * The value of a child property as a C string will be the child object's
+ * canonical path. It can be retrieved using object_property_get_str().
+ * The child object itself can be retrieved using object_property_get_link().
+ */
+void object_property_add_child(Object *obj, const char *name,
+                               Object *child, Error **errp);
+
+/**
+ * object_property_add_link:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @type: the qobj type of the link
+ * @child: a pointer to where the link object reference is stored
+ * @errp: if an error occurs, a pointer to an area to store the area
+ *
+ * Links establish relationships between objects.  Links are unidirectional
+ * although two links can be combined to form a bidirectional relationship
+ * between objects.
+ *
+ * Links form the graph in the object model.
+ *
+ * Ownership of the pointer that @child points to is transferred to the
+ * link property.  The reference count for <code>*@child</code> is
+ * managed by the property from after the function returns till the
+ * property is deleted with object_property_del().
+ */
+void object_property_add_link(Object *obj, const char *name,
+                              const char *type, Object **child,
+                              Error **errp);
+
+/**
+ * object_property_add_str:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @get: the getter or NULL if the property is write-only.  This function must
+ *   return a string to be freed by g_free().
+ * @set: the setter or NULL if the property is read-only
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add a string property using getters/setters.  This function will add a
+ * property of type 'string'.
+ */
+void object_property_add_str(Object *obj, const char *name,
+                             char *(*get)(Object *, Error **),
+                             void (*set)(Object *, const char *, Error **),
+                             Error **errp);
+
+/**
+ * object_property_add_bool:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @get: the getter or NULL if the property is write-only.
+ * @set: the setter or NULL if the property is read-only
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add a bool property using getters/setters.  This function will add a
+ * property of type 'bool'.
+ */
+void object_property_add_bool(Object *obj, const char *name,
+                              bool (*get)(Object *, Error **),
+                              void (*set)(Object *, bool, Error **),
+                              Error **errp);
+
+/**
+ * object_property_add_uint8_ptr:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @v: pointer to value
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add an integer property in memory.  This function will add a
+ * property of type 'uint8'.
+ */
+void object_property_add_uint8_ptr(Object *obj, const char *name,
+                                   const uint8_t *v, Error **errp);
+
+/**
+ * object_property_add_uint16_ptr:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @v: pointer to value
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add an integer property in memory.  This function will add a
+ * property of type 'uint16'.
+ */
+void object_property_add_uint16_ptr(Object *obj, const char *name,
+                                    const uint16_t *v, Error **errp);
+
+/**
+ * object_property_add_uint32_ptr:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @v: pointer to value
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add an integer property in memory.  This function will add a
+ * property of type 'uint32'.
+ */
+void object_property_add_uint32_ptr(Object *obj, const char *name,
+                                    const uint32_t *v, Error **errp);
+
+/**
+ * object_property_add_uint64_ptr:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @v: pointer to value
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add an integer property in memory.  This function will add a
+ * property of type 'uint64'.
+ */
+void object_property_add_uint64_ptr(Object *obj, const char *name,
+                                    const uint64_t *v, Error **Errp);
+
+/**
+ * object_child_foreach:
+ * @obj: the object whose children will be navigated
+ * @fn: the iterator function to be called
+ * @opaque: an opaque value that will be passed to the iterator
+ *
+ * Call @fn passing each child of @obj and @opaque to it, until @fn returns
+ * non-zero.
+ *
+ * Returns: The last value returned by @fn, or 0 if there is no child.
+ */
+int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
+                         void *opaque);
+
+/**
+ * container_get:
+ * @root: root of the #path, e.g., object_get_root()
+ * @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(Object *root, const char *path);
+
+
+#endif
diff --git a/include/qom/qom-qobject.h b/include/qom/qom-qobject.h
new file mode 100644
index 0000000..77cd717
--- /dev/null
+++ b/include/qom/qom-qobject.h
@@ -0,0 +1,42 @@
+/*
+ * QEMU Object Model - QObject wrappers
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Author: 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 QEMU_QOM_QOBJECT_H
+#define QEMU_QOM_QOBJECT_H
+
+#include "qom/object.h"
+
+/*
+ * object_property_get_qobject:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to QObject, or NULL if
+ * an error occurs.
+ */
+struct QObject *object_property_get_qobject(Object *obj, const char *name,
+                                            struct Error **errp);
+
+/**
+ * object_property_set_qobject:
+ * @obj: the object
+ * @ret: The value that will be written to the property.
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes a property to a object.
+ */
+void object_property_set_qobject(Object *obj, struct QObject *qobj,
+                                 const char *name, struct Error **errp);
+
+#endif
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index c25f35e..9c646ec 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -32,5 +32,6 @@
 void resume_all_vcpus(void);
 void pause_all_vcpus(void);
 int qemu_init_main_loop(void);
+void main_loop(void);
 
 #endif /* QEMU_CPUS_H */
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
deleted file mode 100644
index cecd98f..0000000
--- a/include/sysemu/device_tree.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Header with function prototypes to help device tree manipulation using
- * libfdt. It also provides functions to read entries from device tree proc
- * interface.
- *
- * Copyright 2008 IBM Corporation.
- * Authors: Jerone Young <jyoung5@us.ibm.com>
- *          Hollis Blanchard <hollisb@us.ibm.com>
- *
- * This work is licensed under the GNU GPL license version 2 or later.
- *
- */
-
-#ifndef __DEVICE_TREE_H__
-#define __DEVICE_TREE_H__
-
-void *load_device_tree(const char *filename_path, int *sizep);
-
-int qemu_devtree_setprop(void *fdt, const char *node_path,
-                         const char *property, void *val_array, int size);
-int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
-                              const char *property, uint32_t val);
-int qemu_devtree_setprop_string(void *fdt, const char *node_path,
-                                const char *property, const char *string);
-
-#endif /* __DEVICE_TREE_H__ */
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 7880383..7035c31 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -20,12 +20,12 @@
     hwaddr len;
 } ScatterGatherEntry;
 
-typedef struct {
+struct QEMUSGList {
     ScatterGatherEntry *sg;
     int nsg;
     int nalloc;
     hwaddr size;
-} QEMUSGList;
+};
 
 void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint);
 void qemu_sglist_add(QEMUSGList *qsg, hwaddr base,
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index e59ae20..7f86d89 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -15,6 +15,7 @@
 #define QEMU_KVM_H
 
 #include "config.h"
+#include "cpu.h"
 #include "qemu/queue.h"
 
 #ifdef CONFIG_KVM
@@ -37,10 +38,10 @@
 
 int kvm_init(int smp_cpus);
 
-int kvm_init_vcpu(CPUState *env);
+int kvm_init_vcpu(CPUOldState *env);
 int kvm_sync_vcpus(void);
 
-int kvm_cpu_exec(CPUState *env);
+int kvm_cpu_exec(CPUOldState *env);
 
 void kvm_set_phys_mem(hwaddr start_addr,
                       ram_addr_t size,
@@ -60,12 +61,12 @@
 int kvm_coalesce_mmio_region(hwaddr start, ram_addr_t size);
 int kvm_uncoalesce_mmio_region(hwaddr start, ram_addr_t size);
 
-int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUOldState *current_env, target_ulong addr,
                           target_ulong len, int type);
-int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUOldState *current_env, target_ulong addr,
                           target_ulong len, int type);
-void kvm_remove_all_breakpoints(CPUState *current_env);
-int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap);
+void kvm_remove_all_breakpoints(CPUOldState *current_env);
+int kvm_update_guest_debug(CPUOldState *env, unsigned long reinject_trap);
 
 /* internal API */
 
@@ -76,28 +77,28 @@
 
 int kvm_vm_ioctl(KVMState *s, int type, ...);
 
-int kvm_vcpu_ioctl(CPUState *env, int type, ...);
+int kvm_vcpu_ioctl(CPUOldState *env, int type, ...);
 
-int kvm_get_mp_state(CPUState *env);
-int kvm_put_mp_state(CPUState *env);
+int kvm_get_mp_state(CPUOldState *env);
+int kvm_put_mp_state(CPUOldState *env);
 
 /* Arch specific hooks */
 
-int kvm_arch_post_run(CPUState *env, struct kvm_run *run);
+int kvm_arch_post_run(CPUOldState *env, struct kvm_run *run);
 
-int kvm_arch_vcpu_run(CPUState *env);
+int kvm_arch_vcpu_run(CPUOldState *env);
 
-int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run);
+int kvm_arch_handle_exit(CPUOldState *env, struct kvm_run *run);
 
-int kvm_arch_pre_run(CPUState *env, struct kvm_run *run);
+int kvm_arch_pre_run(CPUOldState *env, struct kvm_run *run);
 
-int kvm_arch_get_registers(CPUState *env);
+int kvm_arch_get_registers(CPUOldState *env);
 
-int kvm_arch_put_registers(CPUState *env);
+int kvm_arch_put_registers(CPUOldState *env);
 
 int kvm_arch_init(KVMState *s, int smp_cpus);
 
-int kvm_arch_init_vcpu(CPUState *env);
+int kvm_arch_init_vcpu(CPUOldState *env);
 
 struct kvm_guest_debug;
 struct kvm_debug_exit_arch;
@@ -113,14 +114,14 @@
 
 int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info);
 
-struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
+struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUOldState *env,
                                                  target_ulong pc);
 
-int kvm_sw_breakpoints_active(CPUState *env);
+int kvm_sw_breakpoints_active(CPUOldState *env);
 
-int kvm_arch_insert_sw_breakpoint(CPUState *current_env,
+int kvm_arch_insert_sw_breakpoint(CPUOldState *current_env,
                                   struct kvm_sw_breakpoint *bp);
-int kvm_arch_remove_sw_breakpoint(CPUState *current_env,
+int kvm_arch_remove_sw_breakpoint(CPUOldState *current_env,
                                   struct kvm_sw_breakpoint *bp);
 int kvm_arch_insert_hw_breakpoint(target_ulong addr,
                                   target_ulong len, int type);
@@ -128,18 +129,18 @@
                                   target_ulong len, int type);
 void kvm_arch_remove_all_hw_breakpoints(void);
 
-void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg);
+void kvm_arch_update_guest_debug(CPUOldState *env, struct kvm_guest_debug *dbg);
 
 int kvm_check_extension(KVMState *s, unsigned int extension);
 
-uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
+uint32_t kvm_arch_get_supported_cpuid(CPUOldState *env, uint32_t function,
                                       int reg);
 
 /* generic hooks - to be moved/refactored once there are more users */
 #ifdef CONFIG_HAX
-void hax_vcpu_sync_state(CPUState *env, int modified);
+void hax_vcpu_sync_state(CPUOldState *env, int modified);
 #endif
-static inline void cpu_synchronize_state(CPUState *env, int modified)
+static inline void cpu_synchronize_state(CPUOldState *env, int modified)
 {
     if (kvm_enabled()) {
         if (modified)
@@ -152,7 +153,7 @@
 #endif
 }
 
-int kvm_get_sregs(CPUState *env);
+int kvm_get_sregs(CPUOldState *env);
 
 
 #endif
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
index 81fd9ab..920499d 100644
--- a/include/sysemu/os-posix.h
+++ b/include/sysemu/os-posix.h
@@ -26,10 +26,6 @@
 #ifndef QEMU_OS_POSIX_H
 #define QEMU_OS_POSIX_H
 
-static inline void os_host_main_loop_wait(int *timeout)
-{
-}
-
 void os_set_line_buffering(void);
 void os_set_proc_name(const char *s);
 void os_setup_signal_handling(void);
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
index 5f032ea..05b1aba 100644
--- a/include/sysemu/os-win32.h
+++ b/include/sysemu/os-win32.h
@@ -24,11 +24,14 @@
  */
 
 #ifndef QEMU_OS_WIN32_H
-#define QEMU_OS_WIN32_H
+
+#define socket_close  winsock2_socket_close3
 
 #include <winsock2.h>
 #include <windows.h>
 
+#undef socket_close
+
 /* Polling handling */
 
 /* return TRUE if no sleep should be done afterwards */
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 821492b..fc8b83b 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -9,6 +9,8 @@
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qerror.h"
 
+#include "exec/hwaddr.h"
+
 #ifdef _WIN32
 #include <windows.h>
 #endif
@@ -16,11 +18,11 @@
 /* vl.c */
 extern const char *bios_name;
 
-#define QEMU_FILE_TYPE_BIOS   0
-#define QEMU_FILE_TYPE_KEYMAP 1
-char *qemu_find_file(int type, const char *name);
-
+extern const char* savevm_on_exit;
+extern int no_shutdown;
 extern int vm_running;
+extern int vm_can_run(void);
+extern int qemu_debug_requested(void);
 extern const char *qemu_name;
 extern uint8_t qemu_uuid[];
 int qemu_uuid_parse(const char *str, uint8_t *uuid);
@@ -36,6 +38,8 @@
 void vm_start(void);
 void vm_stop(int reason);
 
+void qemu_adjust_clock(QEMUClock* clock);
+
 uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_transferred(void);
 uint64_t ram_bytes_total(void);
@@ -44,11 +48,14 @@
 void cpu_enable_ticks(void);
 void cpu_disable_ticks(void);
 
+int tcg_has_work(void);
+
 void qemu_system_reset_request(void);
 void qemu_system_shutdown_request(void);
 void qemu_system_powerdown_request(void);
 int qemu_shutdown_requested(void);
 int qemu_reset_requested(void);
+int qemu_vmstop_requested(void);
 int qemu_powerdown_requested(void);
 void qemu_system_killed(int signal, pid_t pid);
 #ifdef NEED_CPU_H
@@ -94,6 +101,17 @@
 /* SLIRP */
 void do_info_slirp(Monitor *mon);
 
+typedef enum DisplayType
+{
+    DT_DEFAULT,
+    DT_CURSES,
+    DT_SDL,
+    DT_GTK,
+    DT_VNC,
+    DT_NOGRAPHIC,
+    DT_NONE,
+} DisplayType;
+
 extern int autostart;
 extern int bios_size;
 extern int cirrus_vga_enabled;
@@ -118,6 +136,9 @@
 extern int old_param;
 extern QEMUClock *rtc_clock;
 
+const char* dns_log_filename;
+const char* drop_log_filename;
+
 #define MAX_NODES 64
 extern int nb_numa_nodes;
 extern uint64_t node_mem[MAX_NODES];
@@ -221,6 +242,7 @@
 
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
+#if 0 //DIGIT
 #ifdef NEED_CPU_H
 /* loader.c */
 int get_image_size(const char *filename);
@@ -238,6 +260,7 @@
 void pstrcpy_targphys(hwaddr dest, int buf_size,
                       const char *source);
 #endif
+#endif //DIGIT
 
 void do_usb_add(Monitor *mon, const char *devname);
 void do_usb_del(Monitor *mon, const char *devname);
diff --git a/kvm-all.c b/kvm-all.c
index bb89229..3ee3296 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -20,6 +20,7 @@
 
 #include <linux/kvm.h>
 
+#include "cpu.h"
 #include "qemu-common.h"
 #include "sysemu/sysemu.h"
 #include "hw/hw.h"
@@ -144,7 +145,7 @@
 }
 
 
-int kvm_init_vcpu(CPUState *env)
+int kvm_init_vcpu(CPUOldState *env)
 {
     KVMState *s = kvm_state;
     long mmap_size;
@@ -181,14 +182,14 @@
     return ret;
 }
 
-int kvm_put_mp_state(CPUState *env)
+int kvm_put_mp_state(CPUOldState *env)
 {
     struct kvm_mp_state mp_state = { .mp_state = env->mp_state };
 
     return kvm_vcpu_ioctl(env, KVM_SET_MP_STATE, &mp_state);
 }
 
-int kvm_get_mp_state(CPUState *env)
+int kvm_get_mp_state(CPUOldState *env)
 {
     struct kvm_mp_state mp_state;
     int ret;
@@ -203,7 +204,7 @@
 
 int kvm_sync_vcpus(void)
 {
-    CPUState *env;
+    CPUOldState *env;
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
         int ret;
@@ -516,7 +517,7 @@
     return ret;
 }
 
-static int kvm_handle_io(CPUState *env, uint16_t port, void *data,
+static int kvm_handle_io(CPUOldState *env, uint16_t port, void *data,
                          int direction, int size, uint32_t count)
 {
     int i;
@@ -555,7 +556,7 @@
     return 1;
 }
 
-static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run)
+static void kvm_run_coalesced_mmio(CPUOldState *env, struct kvm_run *run)
 {
 #ifdef KVM_CAP_COALESCED_MMIO
     KVMState *s = kvm_state;
@@ -576,7 +577,7 @@
 #endif
 }
 
-int kvm_cpu_exec(CPUState *env)
+int kvm_cpu_exec(CPUOldState *env)
 {
     struct kvm_run *run = env->kvm_run;
     int ret;
@@ -842,7 +843,7 @@
     return ret;
 }
 
-int kvm_vcpu_ioctl(CPUState *env, int type, ...)
+int kvm_vcpu_ioctl(CPUOldState *env, int type, ...)
 {
     int ret;
     void *arg;
@@ -889,7 +890,7 @@
 }
 
 #ifdef KVM_CAP_SET_GUEST_DEBUG
-struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
+struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUOldState *env,
                                                  target_ulong pc)
 {
     struct kvm_sw_breakpoint *bp;
@@ -901,12 +902,12 @@
     return NULL;
 }
 
-int kvm_sw_breakpoints_active(CPUState *env)
+int kvm_sw_breakpoints_active(CPUOldState *env)
 {
     return !QTAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints);
 }
 
-int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
+int kvm_update_guest_debug(CPUOldState *env, unsigned long reinject_trap)
 {
     struct kvm_guest_debug dbg;
 
@@ -920,11 +921,11 @@
     return kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg);
 }
 
-int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUOldState *current_env, target_ulong addr,
                           target_ulong len, int type)
 {
     struct kvm_sw_breakpoint *bp;
-    CPUState *env;
+    CPUOldState *env;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
@@ -962,11 +963,11 @@
     return 0;
 }
 
-int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUOldState *current_env, target_ulong addr,
                           target_ulong len, int type)
 {
     struct kvm_sw_breakpoint *bp;
-    CPUState *env;
+    CPUOldState *env;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
@@ -999,11 +1000,11 @@
     return 0;
 }
 
-void kvm_remove_all_breakpoints(CPUState *current_env)
+void kvm_remove_all_breakpoints(CPUOldState *current_env)
 {
     struct kvm_sw_breakpoint *bp, *next;
     KVMState *s = current_env->kvm_state;
-    CPUState *env;
+    CPUOldState *env;
 
     QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
         if (kvm_arch_remove_sw_breakpoint(current_env, bp) != 0) {
@@ -1022,24 +1023,24 @@
 
 #else /* !KVM_CAP_SET_GUEST_DEBUG */
 
-int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
+int kvm_update_guest_debug(CPUOldState *env, unsigned long reinject_trap)
 {
     return -EINVAL;
 }
 
-int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUOldState *current_env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUOldState *current_env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUState *current_env)
+void kvm_remove_all_breakpoints(CPUOldState *current_env)
 {
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
diff --git a/log-rotate-android.c b/log-rotate-android.c
new file mode 100644
index 0000000..747a0a7
--- /dev/null
+++ b/log-rotate-android.c
@@ -0,0 +1,93 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// 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.
+
+#include "android/log-rotate.h"
+#include "net/net.h"
+#include "slirp-android/libslirp.h"
+#include "sysemu/sysemu.h"
+
+#include <stdio.h>
+
+#ifdef _WIN32
+
+void qemu_log_rotation_init(void) {
+    // Nothing to do on Win32 for now.
+}
+
+void qemu_log_rotation_poll(void) {
+    // Nothing to do on Win32 for now.
+}
+
+#else // !_WIN32
+
+#include <sys/signal.h>
+
+static int rotate_logs_requested = 0;
+
+static void rotate_qemu_logs_handler(int signum) {
+  rotate_logs_requested = 1;
+}
+
+void qemu_log_rotation_init(void) {
+  // Install SIGUSR1 signal handler.
+  struct sigaction act;
+  sigfillset(&act.sa_mask);
+  act.sa_flags = 0;
+  act.sa_handler = rotate_qemu_logs_handler;
+  if (sigaction(SIGUSR1, &act, NULL) == -1) {
+    fprintf(stderr, "Failed to setup SIGUSR1 handler to clear Qemu logs\n");
+    exit(-1);
+  }
+}
+
+
+// Clears the passed qemu log when the rotate_logs_requested
+// is set. We need to clear the logs between the tasks that do not
+// require restarting Qemu.
+static FILE* rotate_log(FILE* old_log_fd, const char* filename) {
+  FILE* new_log_fd = NULL;
+  if (old_log_fd) {
+    if (fclose(old_log_fd) == -1) {
+      fprintf(stderr, "Cannot close old_log fd\n");
+      exit(errno);
+    }
+  }
+
+  if (!filename) {
+    fprintf(stderr, "The log filename to be rotated is not provided");
+    exit(-1);
+  }
+
+  new_log_fd = fopen(filename , "wb+");
+  if (new_log_fd == NULL) {
+    fprintf(stderr, "Cannot open the log file: %s for write.\n",
+            filename);
+    exit(1);
+  }
+
+  return new_log_fd;
+}
+
+
+void qemu_log_rotation_poll(void) {
+    if (!rotate_logs_requested)
+        return;
+    
+    FILE* new_dns_log_fd = rotate_log(get_slirp_dns_log_fd(),
+                                      dns_log_filename);
+    FILE* new_drop_log_fd = rotate_log(get_slirp_drop_log_fd(),
+                                       drop_log_filename);
+    slirp_dns_log_fd(new_dns_log_fd);
+    slirp_drop_log_fd(new_drop_log_fd);
+    rotate_logs_requested = 0;
+}
+
+#endif  // !_WIN32
diff --git a/main-loop.c b/main-loop.c
new file mode 100644
index 0000000..446fe32
--- /dev/null
+++ b/main-loop.c
@@ -0,0 +1,1306 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "android/charpipe.h"
+#include "android/log-rotate.h"
+#include "android/snaphost-android.h"
+#include "block/aio.h"
+#include "exec/hax.h"
+#include "hw/hw.h"
+#include "monitor/monitor.h"
+#include "net/net.h"
+#include "qemu-common.h"
+#include "qemu/sockets.h"
+#include "qemu/timer.h"
+#include "slirp-android/libslirp.h"
+#include "sysemu/cpus.h"
+#include "sysemu/sysemu.h"
+
+#ifdef __linux__
+#include <sys/ioctl.h>
+#include <linux/rtc.h>
+/* For the benefit of older linux systems which don't supply it,
+   we use a local copy of hpet.h. */
+/* #include <linux/hpet.h> */
+#include "hw/timer/hpet.h"
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#include <mmsystem.h>
+#endif
+
+
+/* Conversion factor from emulated instructions to virtual clock ticks.  */
+int icount_time_shift;
+/* Arbitrarily pick 1MIPS as the minimum allowable speed.  */
+#define MAX_ICOUNT_SHIFT 10
+/* Compensate for varying guest execution speed.  */
+int64_t qemu_icount_bias;
+static QEMUTimer *icount_rt_timer;
+static QEMUTimer *icount_vm_timer;
+
+#ifndef _WIN32
+static int io_thread_fd = -1;
+
+static void qemu_event_read(void *opaque)
+{
+    int fd = (unsigned long)opaque;
+    ssize_t len;
+
+    /* Drain the notify pipe */
+    do {
+        char buffer[512];
+        len = read(fd, buffer, sizeof(buffer));
+    } while ((len == -1 && errno == EINTR) || len > 0);
+}
+
+static int qemu_event_init(void)
+{
+    int err;
+    int fds[2];
+
+    err = pipe(fds);
+    if (err == -1)
+        return -errno;
+
+    err = fcntl_setfl(fds[0], O_NONBLOCK);
+    if (err < 0)
+        goto fail;
+
+    err = fcntl_setfl(fds[1], O_NONBLOCK);
+    if (err < 0)
+        goto fail;
+
+    qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
+                         (void *)(unsigned long)fds[0]);
+
+    io_thread_fd = fds[1];
+    return 0;
+
+fail:
+    close(fds[0]);
+    close(fds[1]);
+    return err;
+}
+#else
+HANDLE qemu_event_handle;
+
+static void dummy_event_handler(void *opaque)
+{
+}
+
+static int qemu_event_init(void)
+{
+    qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (!qemu_event_handle) {
+        perror("Failed CreateEvent");
+        return -1;
+    }
+    qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
+    return 0;
+}
+#endif
+
+int qemu_init_main_loop(void)
+{
+    return qemu_event_init();
+}
+
+#ifndef _WIN32
+
+static inline void os_host_main_loop_wait(int *timeout)
+{
+}
+
+#else  // _WIN32
+
+/***********************************************************/
+/* Polling handling */
+
+typedef struct PollingEntry {
+    PollingFunc *func;
+    void *opaque;
+    struct PollingEntry *next;
+} PollingEntry;
+
+static PollingEntry *first_polling_entry;
+
+int qemu_add_polling_cb(PollingFunc *func, void *opaque)
+{
+    PollingEntry **ppe, *pe;
+    pe = g_malloc0(sizeof(PollingEntry));
+    pe->func = func;
+    pe->opaque = opaque;
+    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
+    *ppe = pe;
+    return 0;
+}
+
+void qemu_del_polling_cb(PollingFunc *func, void *opaque)
+{
+    PollingEntry **ppe, *pe;
+    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
+        pe = *ppe;
+        if (pe->func == func && pe->opaque == opaque) {
+            *ppe = pe->next;
+            g_free(pe);
+            break;
+        }
+    }
+}
+
+/***********************************************************/
+/* Wait objects support */
+typedef struct WaitObjects {
+    int num;
+    HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
+    WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
+    void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
+} WaitObjects;
+
+static WaitObjects wait_objects = {0};
+
+int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
+{
+    WaitObjects *w = &wait_objects;
+
+    if (w->num >= MAXIMUM_WAIT_OBJECTS)
+        return -1;
+    w->events[w->num] = handle;
+    w->func[w->num] = func;
+    w->opaque[w->num] = opaque;
+    w->num++;
+    return 0;
+}
+
+void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
+{
+    int i, found;
+    WaitObjects *w = &wait_objects;
+
+    found = 0;
+    for (i = 0; i < w->num; i++) {
+        if (w->events[i] == handle)
+            found = 1;
+        if (found) {
+            w->events[i] = w->events[i + 1];
+            w->func[i] = w->func[i + 1];
+            w->opaque[i] = w->opaque[i + 1];
+        }
+    }
+    if (found)
+        w->num--;
+}
+
+void os_host_main_loop_wait(int *timeout)
+{
+    int ret, ret2, i;
+    PollingEntry *pe;
+
+    /* XXX: need to suppress polling by better using win32 events */
+    ret = 0;
+    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
+        ret |= pe->func(pe->opaque);
+    }
+    if (ret == 0) {
+        int err;
+        WaitObjects *w = &wait_objects;
+
+        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]);
+
+            /* 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) {
+                } else {
+                    err = GetLastError();
+                    fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
+                }
+            }
+        } else if (ret == WAIT_TIMEOUT) {
+        } else {
+            err = GetLastError();
+            fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
+        }
+    }
+
+    *timeout = 0;
+}
+
+#endif  // _WIN32
+
+void main_loop_wait(int timeout)
+{
+    fd_set rfds, wfds, xfds;
+    int ret, nfds;
+    struct timeval tv;
+
+    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;
+    FD_ZERO(&rfds);
+    FD_ZERO(&wfds);
+    FD_ZERO(&xfds);
+    qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
+    if (slirp_is_inited()) {
+        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
+    }
+
+    qemu_mutex_unlock_iothread();
+    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
+    qemu_mutex_lock_iothread();
+    qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
+    if (slirp_is_inited()) {
+        if (ret < 0) {
+            FD_ZERO(&rfds);
+            FD_ZERO(&wfds);
+            FD_ZERO(&xfds);
+        }
+        slirp_select_poll(&rfds, &wfds, &xfds);
+    }
+    charpipe_poll();
+
+    qemu_run_all_timers();
+
+    /* Check bottom-halves last in case any of the earlier events triggered
+       them.  */
+    qemu_bh_poll();
+
+}
+
+void main_loop(void)
+{
+    int r;
+
+#ifdef CONFIG_HAX
+    if (hax_enabled())
+        hax_sync_vcpus();
+#endif
+
+    for (;;) {
+        do {
+#ifdef CONFIG_PROFILER
+            int64_t ti;
+#endif
+            tcg_cpu_exec();
+#ifdef CONFIG_PROFILER
+            ti = profile_getclock();
+#endif
+            main_loop_wait(qemu_calculate_timeout());
+#ifdef CONFIG_PROFILER
+            dev_time += profile_getclock() - ti;
+#endif
+
+            qemu_log_rotation_poll();
+
+        } while (vm_can_run());
+
+        if (qemu_debug_requested())
+            vm_stop(EXCP_DEBUG);
+        if (qemu_shutdown_requested()) {
+            if (no_shutdown) {
+                vm_stop(0);
+                no_shutdown = 0;
+            } else {
+                if (savevm_on_exit != NULL) {
+                  /* Prior to saving VM to the snapshot file, save HW config
+                   * settings for that VM, so we can match them when VM gets
+                   * loaded from the snapshot. */
+                  snaphost_save_config(savevm_on_exit);
+                  do_savevm(cur_mon, savevm_on_exit);
+                }
+                break;
+            }
+        }
+        if (qemu_reset_requested()) {
+            pause_all_vcpus();
+            qemu_system_reset();
+            resume_all_vcpus();
+        }
+        if (qemu_powerdown_requested())
+            qemu_system_powerdown();
+        if ((r = qemu_vmstop_requested()))
+            vm_stop(r);
+    }
+    pause_all_vcpus();
+}
+
+/* Correlation between real and virtual time is always going to be
+   fairly approximate, so ignore small variation.
+   When the guest is idle real and virtual time will be aligned in
+   the IO wait loop.  */
+#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10)
+
+static void icount_adjust(void)
+{
+    int64_t cur_time;
+    int64_t cur_icount;
+    int64_t delta;
+    static int64_t last_delta;
+    /* If the VM is not running, then do nothing.  */
+    if (!vm_running)
+        return;
+
+    cur_time = cpu_get_clock();
+    cur_icount = qemu_get_clock_ns(vm_clock);
+    delta = cur_icount - cur_time;
+    /* FIXME: This is a very crude algorithm, somewhat prone to oscillation.  */
+    if (delta > 0
+        && last_delta + ICOUNT_WOBBLE < delta * 2
+        && icount_time_shift > 0) {
+        /* The guest is getting too far ahead.  Slow time down.  */
+        icount_time_shift--;
+    }
+    if (delta < 0
+        && last_delta - ICOUNT_WOBBLE > delta * 2
+        && icount_time_shift < MAX_ICOUNT_SHIFT) {
+        /* The guest is getting too far behind.  Speed time up.  */
+        icount_time_shift++;
+    }
+    last_delta = delta;
+    qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
+}
+
+static void icount_adjust_rt(void * opaque)
+{
+    qemu_mod_timer(icount_rt_timer,
+                   qemu_get_clock_ms(rt_clock) + 1000);
+    icount_adjust();
+}
+
+static void icount_adjust_vm(void * opaque)
+{
+    qemu_mod_timer(icount_vm_timer,
+                   qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10);
+    icount_adjust();
+}
+
+void configure_icount(const char *option)
+{
+    qemu_timer_register_savevm();
+
+    if (!option)
+        return;
+
+    if (strcmp(option, "auto") != 0) {
+        icount_time_shift = strtol(option, NULL, 0);
+        use_icount = 1;
+        return;
+    }
+
+    use_icount = 2;
+
+    /* 125MIPS seems a reasonable initial guess at the guest speed.
+       It will be corrected fairly quickly anyway.  */
+    icount_time_shift = 3;
+
+    /* Have both realtime and virtual time triggers for speed adjustment.
+       The realtime trigger catches emulated time passing too slowly,
+       the virtual time trigger catches emulated time passing too fast.
+       Realtime triggers occur even when idle, so use them less frequently
+       than VM triggers.  */
+    icount_rt_timer = qemu_new_timer_ms(rt_clock, icount_adjust_rt, NULL);
+    qemu_mod_timer(icount_rt_timer,
+                   qemu_get_clock_ms(rt_clock) + 1000);
+    icount_vm_timer = qemu_new_timer_ns(vm_clock, icount_adjust_vm, NULL);
+    qemu_mod_timer(icount_vm_timer,
+                   qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10);
+}
+
+struct qemu_alarm_timer {
+    char const *name;
+    int (*start)(struct qemu_alarm_timer *t);
+    void (*stop)(struct qemu_alarm_timer *t);
+    void (*rearm)(struct qemu_alarm_timer *t);
+#if defined(__linux__)
+    int fd;
+    timer_t timer;
+#elif defined(_WIN32)
+    HANDLE timer;
+#endif
+    char expired;
+    char pending;
+};
+
+static struct qemu_alarm_timer *alarm_timer;
+
+int qemu_alarm_pending(void)
+{
+    return alarm_timer->pending;
+}
+
+static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
+{
+    return !!t->rearm;
+}
+
+static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
+{
+    if (!alarm_has_dynticks(t))
+        return;
+
+    t->rearm(t);
+}
+
+/* TODO: MIN_TIMER_REARM_NS should be optimized */
+#define MIN_TIMER_REARM_NS 250000
+
+#ifdef _WIN32
+
+static int mm_start_timer(struct qemu_alarm_timer *t);
+static void mm_stop_timer(struct qemu_alarm_timer *t);
+static void mm_rearm_timer(struct qemu_alarm_timer *t);
+
+static int win32_start_timer(struct qemu_alarm_timer *t);
+static void win32_stop_timer(struct qemu_alarm_timer *t);
+static void win32_rearm_timer(struct qemu_alarm_timer *t);
+
+#else
+
+static int unix_start_timer(struct qemu_alarm_timer *t);
+static void unix_stop_timer(struct qemu_alarm_timer *t);
+
+#ifdef __linux__
+
+static int dynticks_start_timer(struct qemu_alarm_timer *t);
+static void dynticks_stop_timer(struct qemu_alarm_timer *t);
+static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
+
+static int hpet_start_timer(struct qemu_alarm_timer *t);
+static void hpet_stop_timer(struct qemu_alarm_timer *t);
+
+static int rtc_start_timer(struct qemu_alarm_timer *t);
+static void rtc_stop_timer(struct qemu_alarm_timer *t);
+
+#endif /* __linux__ */
+
+#endif /* _WIN32 */
+
+int64_t qemu_icount_round(int64_t count)
+{
+    return (count + (1 << icount_time_shift) - 1) >> icount_time_shift;
+}
+
+static struct qemu_alarm_timer alarm_timers[] = {
+#ifndef _WIN32
+#ifdef __linux__
+    /* HPET - if available - is preferred */
+    {"hpet", hpet_start_timer, hpet_stop_timer, NULL},
+    /* ...otherwise try RTC */
+    {"rtc", rtc_start_timer, rtc_stop_timer, NULL},
+#endif
+    {"unix", unix_start_timer, unix_stop_timer, NULL},
+#ifdef __linux__
+    /* on Linux, the 'dynticks' clock sometimes doesn't work
+     * properly. this results in the UI freezing while emulation
+     * continues, for several seconds... So move it to the end
+     * of the list. */
+    {"dynticks", dynticks_start_timer,
+     dynticks_stop_timer, dynticks_rearm_timer},
+#endif
+#else
+    {"mmtimer", mm_start_timer, mm_stop_timer, NULL},
+    {"mmtimer2", mm_start_timer, mm_stop_timer, mm_rearm_timer},
+    {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
+    {"win32", win32_start_timer, win32_stop_timer, NULL},
+#endif
+    {NULL, }
+};
+
+static void show_available_alarms(void)
+{
+    int i;
+
+    printf("Available alarm timers, in order of precedence:\n");
+    for (i = 0; alarm_timers[i].name; i++)
+        printf("%s\n", alarm_timers[i].name);
+}
+
+void configure_alarms(char const *opt)
+{
+    int i;
+    int cur = 0;
+    int count = ARRAY_SIZE(alarm_timers) - 1;
+    char *arg;
+    char *name;
+    struct qemu_alarm_timer tmp;
+
+    if (!strcmp(opt, "?")) {
+        show_available_alarms();
+        exit(0);
+    }
+
+    arg = g_strdup(opt);
+
+    /* Reorder the array */
+    name = strtok(arg, ",");
+    while (name) {
+        for (i = 0; i < count && alarm_timers[i].name; i++) {
+            if (!strcmp(alarm_timers[i].name, name))
+                break;
+        }
+
+        if (i == count) {
+            fprintf(stderr, "Unknown clock %s\n", name);
+            goto next;
+        }
+
+        if (i < cur)
+            /* Ignore */
+            goto next;
+
+        /* Swap */
+        tmp = alarm_timers[i];
+        alarm_timers[i] = alarm_timers[cur];
+        alarm_timers[cur] = tmp;
+
+        cur++;
+next:
+        name = strtok(NULL, ",");
+    }
+
+    g_free(arg);
+
+    if (cur) {
+        /* Disable remaining timers */
+        for (i = cur; i < count; i++)
+            alarm_timers[i].name = NULL;
+    } else {
+        show_available_alarms();
+        exit(1);
+    }
+}
+
+static int64_t vm_clock_warp_start;
+
+static void icount_warp_rt(void *opaque)
+{
+    if (vm_clock_warp_start == -1) {
+        return;
+    }
+
+    if (vm_running) {
+        int64_t clock = qemu_get_clock_ns(rt_clock);
+        int64_t warp_delta = clock - vm_clock_warp_start;
+        if (use_icount == 1) {
+            qemu_icount_bias += warp_delta;
+        } else {
+            /*
+             * In adaptive mode, do not let the vm_clock run too
+             * far ahead of real time.
+             */
+            int64_t cur_time = cpu_get_clock();
+            int64_t cur_icount = qemu_get_clock_ns(vm_clock);
+            int64_t delta = cur_time - cur_icount;
+            qemu_icount_bias += MIN(warp_delta, delta);
+        }
+        if (qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],
+                               qemu_get_clock_ns(vm_clock))) {
+            qemu_notify_event();
+        }
+    }
+    vm_clock_warp_start = -1;
+}
+
+static void qemu_clock_warp(QEMUClock *clock)
+{
+    int64_t deadline;
+
+    QEMUTimer* warp_timer = qemu_clock_get_warp_timer(clock);
+    if (!warp_timer)
+        return;
+
+    /*
+     * There are too many global variables to make the "warp" behavior
+     * applicable to other clocks.  But a clock argument removes the
+     * need for if statements all over the place.
+     */
+    assert(clock == vm_clock);
+
+    /*
+     * If the CPUs have been sleeping, advance the vm_clock timer now.  This
+     * ensures that the deadline for the timer is computed correctly below.
+     * This also makes sure that the insn counter is synchronized before the
+     * CPU starts running, in case the CPU is woken by an event other than
+     * the earliest vm_clock timer.
+     */
+    icount_warp_rt(NULL);
+    if (qemu_cpu_has_work(cpu_single_env) || 
+            !qemu_clock_has_active_timer(clock)) {
+        qemu_del_timer(qemu_clock_get_warp_timer(clock));
+        return;
+    }
+
+    vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
+    deadline = qemu_next_icount_deadline();
+    if (deadline > 0) {
+        /*
+         * Ensure the vm_clock proceeds even when the virtual CPU goes to
+         * sleep.  Otherwise, the CPU might be waiting for a future timer
+         * interrupt to wake it up, but the interrupt never comes because
+         * the vCPU isn't running any insns and thus doesn't advance the
+         * vm_clock.
+         *
+         * An extreme solution for this problem would be to never let VCPUs
+         * sleep in icount mode if there is a pending vm_clock timer; rather
+         * time could just advance to the next vm_clock event.  Instead, we
+         * do stop VCPUs and only advance vm_clock after some "real" time,
+         * (related to the time left until the next event) has passed.  This
+         * rt_clock timer will do this.  This avoids that the warps are too
+         * visible externally---for example, you will not be sending network
+         * packets continously instead of every 100ms.
+         */
+        qemu_mod_timer(qemu_clock_get_warp_timer(clock),
+                       vm_clock_warp_start + deadline);
+    } else {
+        qemu_notify_event();
+    }
+}
+
+void qemu_adjust_clock(QEMUClock* clock) {
+    if (!alarm_timer->pending) {
+        qemu_rearm_alarm_timer(alarm_timer);
+    }
+    /* Interrupt execution to force deadline recalculation.  */
+    qemu_clock_warp(clock);
+    if (use_icount) {
+        qemu_notify_event();
+    }
+}
+
+void qemu_run_all_timers(void)
+{
+    alarm_timer->pending = 0;
+
+    /* rearm timer, if not periodic */
+    if (alarm_timer->expired) {
+        alarm_timer->expired = 0;
+        qemu_rearm_alarm_timer(alarm_timer);
+    }
+
+    /* vm time timers */
+    if (vm_running) {
+        qemu_run_timers(vm_clock);
+    }
+
+    qemu_run_timers(rt_clock);
+    qemu_run_timers(host_clock);
+}
+
+static int timer_alarm_pending = 1;
+
+int qemu_timer_alarm_pending(void)
+{
+    int ret = timer_alarm_pending;
+    timer_alarm_pending = 0;
+    return ret;
+}
+
+
+static int64_t qemu_next_alarm_deadline(void);
+
+#ifdef _WIN32
+static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
+#else
+static void host_alarm_handler(int host_signum)
+#endif
+{
+    struct qemu_alarm_timer *t = alarm_timer;
+    if (!t)
+        return;
+
+#if 0
+#define DISP_FREQ 1000
+    {
+        static int64_t delta_min = INT64_MAX;
+        static int64_t delta_max, delta_cum, last_clock, delta, ti;
+        static int count;
+        ti = qemu_get_clock_ns(vm_clock);
+        if (last_clock != 0) {
+            delta = ti - last_clock;
+            if (delta < delta_min)
+                delta_min = delta;
+            if (delta > delta_max)
+                delta_max = delta;
+            delta_cum += delta;
+            if (++count == DISP_FREQ) {
+                printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
+                       muldiv64(delta_min, 1000000, get_ticks_per_sec()),
+                       muldiv64(delta_max, 1000000, get_ticks_per_sec()),
+                       muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()),
+                       (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ));
+                count = 0;
+                delta_min = INT64_MAX;
+                delta_max = 0;
+                delta_cum = 0;
+            }
+        }
+        last_clock = ti;
+    }
+#endif
+    if (alarm_has_dynticks(t) ||
+        qemu_next_alarm_deadline () <= 0) {
+        t->expired = alarm_has_dynticks(t);
+        t->pending = 1;
+        timer_alarm_pending = 1;
+        qemu_notify_event();
+    }
+}
+
+int64_t qemu_next_icount_deadline(void)
+{
+    assert(use_icount);
+    return qemu_clock_next_deadline(vm_clock);
+}
+
+static int64_t qemu_next_alarm_deadline(void)
+{
+    int64_t delta = INT32_MAX;
+    if (!use_icount) {
+        delta = qemu_clock_next_deadline(vm_clock);
+    }
+    int64_t hdelta = qemu_clock_next_deadline(host_clock);
+    if (hdelta < delta) {
+        delta = hdelta;
+    }
+    int64_t rtdelta = qemu_clock_next_deadline(rt_clock);
+    if (rtdelta < delta) {
+        delta = rtdelta;
+    }
+    return delta;
+}
+
+#if defined(__linux__)
+
+#define RTC_FREQ 1024
+
+static void enable_sigio_timer(int fd)
+{
+    struct sigaction act;
+
+    /* timer signal */
+    sigfillset(&act.sa_mask);
+    act.sa_flags = 0;
+    act.sa_handler = host_alarm_handler;
+
+    sigaction(SIGIO, &act, NULL);
+    fcntl_setfl(fd, O_ASYNC);
+    fcntl(fd, F_SETOWN, getpid());
+}
+
+static int hpet_start_timer(struct qemu_alarm_timer *t)
+{
+    struct hpet_info info;
+    int r, fd;
+
+    fd = open("/dev/hpet", O_RDONLY);
+    if (fd < 0)
+        return -1;
+
+    /* Set frequency */
+    r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
+    if (r < 0) {
+        fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
+                "error, but for better emulation accuracy type:\n"
+                "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
+        goto fail;
+    }
+
+    /* Check capabilities */
+    r = ioctl(fd, HPET_INFO, &info);
+    if (r < 0)
+        goto fail;
+
+    /* Enable periodic mode */
+    r = ioctl(fd, HPET_EPI, 0);
+    if (info.hi_flags && (r < 0))
+        goto fail;
+
+    /* Enable interrupt */
+    r = ioctl(fd, HPET_IE_ON, 0);
+    if (r < 0)
+        goto fail;
+
+    enable_sigio_timer(fd);
+    t->fd = fd;
+
+    return 0;
+fail:
+    close(fd);
+    return -1;
+}
+
+static void hpet_stop_timer(struct qemu_alarm_timer *t)
+{
+    int fd = t->fd;
+
+    close(fd);
+}
+
+static int rtc_start_timer(struct qemu_alarm_timer *t)
+{
+    int rtc_fd;
+    unsigned long current_rtc_freq = 0;
+
+    TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
+    if (rtc_fd < 0)
+        return -1;
+    ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
+    if (current_rtc_freq != RTC_FREQ &&
+        ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
+        fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
+                "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
+                "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
+        goto fail;
+    }
+    if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
+    fail:
+        close(rtc_fd);
+        return -1;
+    }
+
+    enable_sigio_timer(rtc_fd);
+
+    t->fd = rtc_fd;
+
+    return 0;
+}
+
+static void rtc_stop_timer(struct qemu_alarm_timer *t)
+{
+    int rtc_fd = t->fd;
+
+    close(rtc_fd);
+}
+
+static int dynticks_start_timer(struct qemu_alarm_timer *t)
+{
+    struct sigevent ev;
+    timer_t host_timer;
+    struct sigaction act;
+
+    sigfillset(&act.sa_mask);
+    act.sa_flags = 0;
+    act.sa_handler = host_alarm_handler;
+
+    sigaction(SIGALRM, &act, NULL);
+
+    /*
+     * Initialize ev struct to 0 to avoid valgrind complaining
+     * about uninitialized data in timer_create call
+     */
+    memset(&ev, 0, sizeof(ev));
+    ev.sigev_value.sival_int = 0;
+    ev.sigev_notify = SIGEV_SIGNAL;
+    ev.sigev_signo = SIGALRM;
+
+    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
+        perror("timer_create");
+
+        /* disable dynticks */
+        fprintf(stderr, "Dynamic Ticks disabled\n");
+
+        return -1;
+    }
+
+    t->timer = host_timer;
+
+    return 0;
+}
+
+static void dynticks_stop_timer(struct qemu_alarm_timer *t)
+{
+    timer_t host_timer = t->timer;
+
+    timer_delete(host_timer);
+}
+
+static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
+{
+    timer_t host_timer = t->timer;
+    struct itimerspec timeout;
+    int64_t nearest_delta_ns = INT64_MAX;
+    int64_t current_ns;
+
+    assert(alarm_has_dynticks(t));
+    if (!active_timers[QEMU_CLOCK_REALTIME] &&
+        !active_timers[QEMU_CLOCK_VIRTUAL] &&
+        !active_timers[QEMU_CLOCK_HOST])
+        return;
+
+    nearest_delta_ns = qemu_next_alarm_deadline();
+    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
+        nearest_delta_ns = MIN_TIMER_REARM_NS;
+
+    /* check whether a timer is already running */
+    if (timer_gettime(host_timer, &timeout)) {
+        perror("gettime");
+        fprintf(stderr, "Internal timer error: aborting\n");
+        exit(1);
+    }
+    current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
+    if (current_ns && current_ns <= nearest_delta_ns)
+        return;
+
+    timeout.it_interval.tv_sec = 0;
+    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
+    timeout.it_value.tv_sec =  nearest_delta_ns / 1000000000;
+    timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
+    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
+        perror("settime");
+        fprintf(stderr, "Internal timer error: aborting\n");
+        exit(1);
+    }
+}
+
+#endif /* defined(__linux__) */
+
+#if !defined(_WIN32)
+
+static int unix_start_timer(struct qemu_alarm_timer *t)
+{
+    struct sigaction act;
+    struct itimerval itv;
+    int err;
+
+    /* timer signal */
+    sigfillset(&act.sa_mask);
+    act.sa_flags = 0;
+    act.sa_handler = host_alarm_handler;
+
+    sigaction(SIGALRM, &act, NULL);
+
+    itv.it_interval.tv_sec = 0;
+    /* for i386 kernel 2.6 to get 1 ms */
+    itv.it_interval.tv_usec = 999;
+    itv.it_value.tv_sec = 0;
+    itv.it_value.tv_usec = 10 * 1000;
+
+    err = setitimer(ITIMER_REAL, &itv, NULL);
+    if (err)
+        return -1;
+
+    return 0;
+}
+
+static void unix_stop_timer(struct qemu_alarm_timer *t)
+{
+    struct itimerval itv;
+
+    memset(&itv, 0, sizeof(itv));
+    setitimer(ITIMER_REAL, &itv, NULL);
+}
+
+#endif /* !defined(_WIN32) */
+
+
+#ifdef _WIN32
+
+static MMRESULT mm_timer;
+static unsigned mm_period;
+
+static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
+                                      DWORD_PTR dwUser, DWORD_PTR dw1,
+                                      DWORD_PTR dw2)
+{
+    struct qemu_alarm_timer *t = alarm_timer;
+    if (!t) {
+        return;
+    }
+    if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) {
+        t->expired = alarm_has_dynticks(t);
+        t->pending = 1;
+        qemu_notify_event();
+    }
+}
+
+static int mm_start_timer(struct qemu_alarm_timer *t)
+{
+    TIMECAPS tc;
+    UINT flags;
+
+    memset(&tc, 0, sizeof(tc));
+    timeGetDevCaps(&tc, sizeof(tc));
+
+    mm_period = tc.wPeriodMin;
+    timeBeginPeriod(mm_period);
+
+    flags = TIME_CALLBACK_FUNCTION;
+    if (alarm_has_dynticks(t)) {
+        flags |= TIME_ONESHOT;
+    } else {
+        flags |= TIME_PERIODIC;
+    }
+
+    mm_timer = timeSetEvent(1,                  /* interval (ms) */
+                            mm_period,          /* resolution */
+                            mm_alarm_handler,   /* function */
+                            (DWORD_PTR)t,       /* parameter */
+                        flags);
+
+    if (!mm_timer) {
+        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
+                GetLastError());
+        timeEndPeriod(mm_period);
+        return -1;
+    }
+
+    return 0;
+}
+
+static void mm_stop_timer(struct qemu_alarm_timer *t)
+{
+    timeKillEvent(mm_timer);
+    timeEndPeriod(mm_period);
+}
+
+static void mm_rearm_timer(struct qemu_alarm_timer *t)
+{
+    int nearest_delta_ms;
+
+    assert(alarm_has_dynticks(t));
+    if (!active_timers[QEMU_CLOCK_REALTIME] &&
+        !active_timers[QEMU_CLOCK_VIRTUAL] &&
+        !active_timers[QEMU_CLOCK_HOST]) {
+        return;
+    }
+
+    timeKillEvent(mm_timer);
+
+    nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
+    if (nearest_delta_ms < 1) {
+        nearest_delta_ms = 1;
+    }
+    mm_timer = timeSetEvent(nearest_delta_ms,
+                            mm_period,
+                            mm_alarm_handler,
+                            (DWORD_PTR)t,
+                            TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
+
+    if (!mm_timer) {
+        fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
+                GetLastError());
+
+        timeEndPeriod(mm_period);
+        exit(1);
+    }
+}
+
+static int win32_start_timer(struct qemu_alarm_timer *t)
+{
+    HANDLE hTimer;
+    BOOLEAN success;
+
+    /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
+       is zero) that has already expired, the timer is not updated.  Since
+       creating a new timer is relatively expensive, set a bogus one-hour
+       interval in the dynticks case.  */
+    success = CreateTimerQueueTimer(&hTimer,
+                          NULL,
+                          host_alarm_handler,
+                          t,
+                          1,
+                          alarm_has_dynticks(t) ? 3600000 : 1,
+                          WT_EXECUTEINTIMERTHREAD);
+
+    if (!success) {
+        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
+                GetLastError());
+        return -1;
+    }
+
+    t->timer = hTimer;
+    return 0;
+}
+
+static void win32_stop_timer(struct qemu_alarm_timer *t)
+{
+    HANDLE hTimer = t->timer;
+
+    if (hTimer) {
+        DeleteTimerQueueTimer(NULL, hTimer, NULL);
+    }
+}
+
+static void win32_rearm_timer(struct qemu_alarm_timer *t)
+{
+    HANDLE hTimer = t->timer;
+    int nearest_delta_ms;
+    BOOLEAN success;
+
+    assert(alarm_has_dynticks(t));
+    if (!active_timers[QEMU_CLOCK_REALTIME] &&
+        !active_timers[QEMU_CLOCK_VIRTUAL] &&
+        !active_timers[QEMU_CLOCK_HOST])
+        return;
+
+    nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
+    if (nearest_delta_ms < 1) {
+        nearest_delta_ms = 1;
+    }
+    success = ChangeTimerQueueTimer(NULL,
+                                    hTimer,
+                                    nearest_delta_ms,
+                                    3600000);
+
+    if (!success) {
+        fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
+                GetLastError());
+        exit(-1);
+    }
+
+}
+
+#endif /* _WIN32 */
+
+static void alarm_timer_on_change_state_rearm(void *opaque, 
+                                              int running, 
+                                              int reason)
+{
+    if (running)
+        qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque);
+}
+
+int init_timer_alarm(void)
+{
+    struct qemu_alarm_timer *t = NULL;
+    int i, err = -1;
+
+    for (i = 0; alarm_timers[i].name; i++) {
+        t = &alarm_timers[i];
+
+        err = t->start(t);
+        if (!err)
+            break;
+    }
+
+    if (err) {
+        err = -ENOENT;
+        goto fail;
+    }
+
+    /* first event is at time 0 */
+    t->pending = 1;
+    alarm_timer = t;
+    qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t);
+
+    return 0;
+
+fail:
+    return err;
+}
+
+void quit_timers(void)
+{
+    struct qemu_alarm_timer *t = alarm_timer;
+    alarm_timer = NULL;
+    t->stop(t);
+}
+
+static int64_t qemu_icount_delta(void)
+{
+    if (!use_icount) {
+        return 5000 * (int64_t) 1000000;
+    } else if (use_icount == 1) {
+        /* When not using an adaptive execution frequency
+           we tend to get badly out of sync with real time,
+           so just delay for a reasonable amount of time.  */
+        return 0;
+    } else {
+        return cpu_get_icount() - cpu_get_clock();
+    }
+}
+
+int qemu_calculate_timeout(void)
+{
+    int timeout;
+
+    if (!vm_running)
+        timeout = 5000;
+    else if (tcg_has_work())
+        timeout = 0;
+    else if (!use_icount) {
+#ifdef WIN32
+        /* This corresponds to the case where the emulated system is
+         * totally idle and waiting for i/o. The problem is that on
+         * Windows, the default value will prevent Windows user events
+         * to be delivered in less than 5 seconds.
+         *
+         * Upstream contains a different way to handle this, for now
+         * this hack should be sufficient until we integrate it into
+         * our tree.
+         */
+        timeout = 1000/15;  /* deliver user events every 15/th of second */
+#else
+        timeout = 5000;
+#endif
+    } else {
+     /* XXX: use timeout computed from timers */
+        int64_t add;
+        int64_t delta;
+        /* Advance virtual time to the next event.  */
+        delta = qemu_icount_delta();
+        if (delta > 0) {
+            /* If virtual time is ahead of real time then just
+               wait for IO.  */
+            timeout = (delta + 999999) / 1000000;
+        } else {
+            /* Wait for either IO to occur or the next
+               timer event.  */
+            add = qemu_next_icount_deadline();
+            /* We advance the timer before checking for IO.
+               Limit the amount we advance so that early IO
+               activity won't get the guest too far ahead.  */
+            if (add > 10000000)
+                add = 10000000;
+            delta += add;
+            qemu_icount += qemu_icount_round (add);
+            timeout = delta / 1000000;
+            if (timeout < 0)
+                timeout = 0;
+        }
+    }
+
+    return timeout;
+}
diff --git a/migration-dummy-android.c b/migration-dummy-android.c
index c207733..0157819 100644
--- a/migration-dummy-android.c
+++ b/migration-dummy-android.c
@@ -14,7 +14,6 @@
 #include "qemu-common.h"
 #include "migration/migration.h"
 #include "monitor/monitor.h"
-#include "buffered_file.h"
 #include "sysemu/sysemu.h"
 #include "block/block.h"
 #include "qemu/sockets.h"
diff --git a/migration-exec.c b/migration-exec.c
deleted file mode 100644
index 2c4e7bc..0000000
--- a/migration-exec.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * QEMU live migration
- *
- * Copyright IBM, Corp. 2008
- * Copyright Dell MessageOne 2008
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *  Charles Duffy     <charles_duffy@messageone.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu-common.h"
-#include "qemu/sockets.h"
-#include "migration/migration.h"
-#include "sysemu/char.h"
-#include "sysemu/sysemu.h"
-#include "buffered_file.h"
-#include "block/block.h"
-#include <sys/types.h>
-#include <sys/wait.h>
-
-//#define DEBUG_MIGRATION_EXEC
-
-#ifdef DEBUG_MIGRATION_EXEC
-#define DPRINTF(fmt, ...) \
-    do { printf("migration-exec: " fmt, ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...) \
-    do { } while (0)
-#endif
-
-static int file_errno(FdMigrationState *s)
-{
-    return errno;
-}
-
-static int file_write(FdMigrationState *s, const void * buf, size_t size)
-{
-    return write(s->fd, buf, size);
-}
-
-static int exec_close(FdMigrationState *s)
-{
-    int ret = 0;
-    DPRINTF("exec_close\n");
-    if (s->opaque) {
-        ret = qemu_fclose(s->opaque);
-        s->opaque = NULL;
-        s->fd = -1;
-        if (ret != -1 &&
-            WIFEXITED(ret)
-            && WEXITSTATUS(ret) == 0) {
-            ret = 0;
-        } else {
-            ret = -1;
-    }
-    }
-    return ret;
-}
-
-MigrationState *exec_start_outgoing_migration(const char *command,
-                                             int64_t bandwidth_limit,
-                                             int detach)
-{
-    FdMigrationState *s;
-    FILE *f;
-
-    s = g_malloc0(sizeof(*s));
-
-    f = popen(command, "w");
-    if (f == NULL) {
-        DPRINTF("Unable to popen exec target\n");
-        goto err_after_alloc;
-    }
-
-    s->fd = fileno(f);
-    if (s->fd == -1) {
-        DPRINTF("Unable to retrieve file descriptor for popen'd handle\n");
-        goto err_after_open;
-    }
-
-    if (fcntl(s->fd, F_SETFD, O_NONBLOCK) == -1) {
-        DPRINTF("Unable to set nonblocking mode on file descriptor\n");
-        goto err_after_open;
-    }
-
-    s->opaque = qemu_popen(f, "w");
-
-    s->close = exec_close;
-    s->get_error = file_errno;
-    s->write = file_write;
-    s->mig_state.cancel = migrate_fd_cancel;
-    s->mig_state.get_status = migrate_fd_get_status;
-    s->mig_state.release = migrate_fd_release;
-
-    s->state = MIG_STATE_ACTIVE;
-    s->mon_resume = NULL;
-    s->bandwidth_limit = bandwidth_limit;
-
-    if (!detach)
-        migrate_fd_monitor_suspend(s);
-
-    migrate_fd_connect(s);
-    return &s->mig_state;
-
-err_after_open:
-    pclose(f);
-err_after_alloc:
-    g_free(s);
-    return NULL;
-}
-
-static void exec_accept_incoming_migration(void *opaque)
-{
-    QEMUFile *f = opaque;
-    int ret;
-
-    vm_stop(0); /* just in case */
-    ret = qemu_loadvm_state(f);
-    if (ret < 0) {
-        fprintf(stderr, "load of migration failed\n");
-        goto err;
-    }
-    qemu_announce_self();
-    DPRINTF("successfully loaded vm state\n");
-    /* we've successfully migrated, close the fd */
-    qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
-    vm_start();
-
-err:
-    qemu_fclose(f);
-}
-
-int exec_start_incoming_migration(const char *command)
-{
-    QEMUFile *f;
-
-    DPRINTF("Attempting to start an incoming migration\n");
-    f = qemu_popen_cmd(command, "r");
-    if(f == NULL) {
-        DPRINTF("Unable to apply qemu wrapper to popen file\n");
-        return -errno;
-    }
-
-    qemu_set_fd_handler2(qemu_stdio_fd(f), NULL,
-			 exec_accept_incoming_migration, NULL,
-			 (void *)(unsigned long)f);
-
-    return 0;
-}
diff --git a/migration-tcp-android.c b/migration-tcp-android.c
deleted file mode 100644
index ed3dd67..0000000
--- a/migration-tcp-android.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * QEMU live migration
- *
- * Copyright IBM, Corp. 2008
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu-common.h"
-#include "qemu/sockets.h"
-#include "migration/migration.h"
-#include "sysemu/char.h"
-#include "sysemu/sysemu.h"
-#include "buffered_file.h"
-#include "block/block.h"
-
-//#define DEBUG_MIGRATION_TCP
-
-#ifdef DEBUG_MIGRATION_TCP
-#define dprintf(fmt, ...) \
-    do { printf("migration-tcp: " fmt, ## __VA_ARGS__); } while (0)
-#else
-#define dprintf(fmt, ...) \
-    do { } while (0)
-#endif
-
-static int socket_errno(FdMigrationState *s)
-{
-    return errno;
-}
-
-static int socket_write(FdMigrationState *s, const void * buf, size_t size)
-{
-    return socket_send(s->fd, buf, size);
-}
-
-static int tcp_close(FdMigrationState *s)
-{
-    dprintf("tcp_close\n");
-    if (s->fd != -1) {
-        socket_close(s->fd);
-        s->fd = -1;
-    }
-    return 0;
-}
-
-
-static void tcp_wait_for_connect(void *opaque)
-{
-    FdMigrationState *s = opaque;
-    int ret;
-
-    dprintf("connect completed\n");
-    ret = socket_get_error(s->fd);
-    if (ret < 0) {
-        dprintf("error connecting %d\n", val);
-        migrate_fd_error(s);
-        return;
-    }
-
-    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
-
-    migrate_fd_connect(s);
-}
-
-MigrationState *tcp_start_outgoing_migration(const char *host_port,
-                                             int64_t bandwidth_limit,
-                                             int detach)
-{
-    SockAddress  addr;
-    FdMigrationState *s;
-    int ret;
-
-    if (parse_host_port(&addr, host_port) < 0)
-        return NULL;
-
-    s = g_malloc0(sizeof(*s));
-
-    s->get_error = socket_errno;
-    s->write = socket_write;
-    s->close = tcp_close;
-    s->mig_state.cancel = migrate_fd_cancel;
-    s->mig_state.get_status = migrate_fd_get_status;
-    s->mig_state.release = migrate_fd_release;
-
-    s->state = MIG_STATE_ACTIVE;
-    s->mon_resume = NULL;
-    s->bandwidth_limit = bandwidth_limit;
-    s->fd = socket_create_inet(SOCKET_STREAM);
-    if (s->fd == -1) {
-        g_free(s);
-        return NULL;
-    }
-
-    socket_set_nonblock(s->fd);
-
-    if (!detach)
-        migrate_fd_monitor_suspend(s);
-
-    do {
-        ret = socket_connect(s->fd, &addr);
-        if (ret == -1)
-            ret = -(s->get_error(s));
-
-        if (ret == -EINPROGRESS || ret == -EWOULDBLOCK || ret == -EAGAIN)
-            qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s);
-    } while (ret == -EINTR);
-
-    if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK && ret != -EAGAIN) {
-        dprintf("connect failed\n");
-        socket_close(s->fd);
-        g_free(s);
-        return NULL;
-    } else if (ret >= 0)
-        migrate_fd_connect(s);
-
-    return &s->mig_state;
-}
-
-static void tcp_accept_incoming_migration(void *opaque)
-{
-    SockAddress  addr;
-    int s = (unsigned long)opaque;
-    QEMUFile *f;
-    int c, ret;
-
-    c = socket_accept(s, &addr);
-    dprintf("accepted migration\n");
-
-    if (c == -1) {
-        fprintf(stderr, "could not accept migration connection\n");
-        return;
-    }
-
-    f = qemu_fopen_socket(c);
-    if (f == NULL) {
-        fprintf(stderr, "could not qemu_fopen socket\n");
-        goto out;
-    }
-
-    vm_stop(0); /* just in case */
-    ret = qemu_loadvm_state(f);
-    if (ret < 0) {
-        fprintf(stderr, "load of migration failed\n");
-        goto out_fopen;
-    }
-    qemu_announce_self();
-    dprintf("successfully loaded vm state\n");
-
-    /* we've successfully migrated, close the server socket */
-    qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL);
-    socket_close(s);
-
-    vm_start();
-
-out_fopen:
-    qemu_fclose(f);
-out:
-    socket_close(c);
-}
-
-int tcp_start_incoming_migration(const char *host_port)
-{
-    SockAddress addr;
-    int s;
-
-    if (parse_host_port(&addr, host_port) < 0) {
-        fprintf(stderr, "invalid host/port combination: %s\n", host_port);
-        return -EINVAL;
-    }
-
-    s = socket_create_inet(SOCKET_STREAM);
-    if (s == -1)
-        return -socket_error();
-
-    socket_set_xreuseaddr(s);
-
-    if (socket_bind(s, &addr) == -1)
-        goto err;
-
-    if (socket_listen(s, 1) == -1)
-        goto err;
-
-    qemu_set_fd_handler2(s, NULL, tcp_accept_incoming_migration, NULL,
-                         (void *)(unsigned long)s);
-
-    return 0;
-
-err:
-    socket_close(s);
-    return -socket_error();
-}
diff --git a/migration-tcp.c b/migration-tcp.c
deleted file mode 100644
index 46354c3..0000000
--- a/migration-tcp.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * QEMU live migration
- *
- * Copyright IBM, Corp. 2008
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu-common.h"
-#include "qemu/sockets.h"
-#include "migration/migration.h"
-#include "sysemu/char.h"
-#include "sysemu/sysemu.h"
-#include "buffered_file.h"
-#include "block/block.h"
-
-//#define DEBUG_MIGRATION_TCP
-
-#ifdef DEBUG_MIGRATION_TCP
-#define dprintf(fmt, ...) \
-    do { printf("migration-tcp: " fmt, ## __VA_ARGS__); } while (0)
-#else
-#define dprintf(fmt, ...) \
-    do { } while (0)
-#endif
-
-static int socket_errno(FdMigrationState *s)
-{
-    return socket_error();
-}
-
-static int socket_write(FdMigrationState *s, const void * buf, size_t size)
-{
-    return send(s->fd, buf, size, 0);
-}
-
-static int tcp_close(FdMigrationState *s)
-{
-    dprintf("tcp_close\n");
-    if (s->fd != -1) {
-        close(s->fd);
-        s->fd = -1;
-    }
-    return 0;
-}
-
-
-static void tcp_wait_for_connect(void *opaque)
-{
-    FdMigrationState *s = opaque;
-    int val, ret;
-    socklen_t valsize = sizeof(val);
-
-    dprintf("connect completed\n");
-    do {
-        ret = getsockopt(s->fd, SOL_SOCKET, SO_ERROR, (void *) &val, &valsize);
-    } while (ret == -1 && (s->get_error(s)) == EINTR);
-
-    if (ret < 0) {
-        migrate_fd_error(s);
-        return;
-    }
-
-    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
-
-    if (val == 0)
-        migrate_fd_connect(s);
-    else {
-        dprintf("error connecting %d\n", val);
-        migrate_fd_error(s);
-    }
-}
-
-MigrationState *tcp_start_outgoing_migration(const char *host_port,
-                                             int64_t bandwidth_limit,
-                                             int detach)
-{
-    struct sockaddr_in addr;
-    FdMigrationState *s;
-    int ret;
-
-    if (parse_host_port(&addr, host_port) < 0)
-        return NULL;
-
-    s = g_malloc0(sizeof(*s));
-
-    s->get_error = socket_errno;
-    s->write = socket_write;
-    s->close = tcp_close;
-    s->mig_state.cancel = migrate_fd_cancel;
-    s->mig_state.get_status = migrate_fd_get_status;
-    s->mig_state.release = migrate_fd_release;
-
-    s->state = MIG_STATE_ACTIVE;
-    s->mon_resume = NULL;
-    s->bandwidth_limit = bandwidth_limit;
-    s->fd = socket(PF_INET, SOCK_STREAM, 0);
-    if (s->fd == -1) {
-        g_free(s);
-        return NULL;
-    }
-
-    socket_set_nonblock(s->fd);
-
-    if (!detach)
-        migrate_fd_monitor_suspend(s);
-
-    do {
-        ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr));
-        if (ret == -1)
-            ret = -(s->get_error(s));
-
-        if (ret == -EINPROGRESS || ret == -EWOULDBLOCK)
-            qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s);
-    } while (ret == -EINTR);
-
-    if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) {
-        dprintf("connect failed\n");
-        close(s->fd);
-        g_free(s);
-        return NULL;
-    } else if (ret >= 0)
-        migrate_fd_connect(s);
-
-    return &s->mig_state;
-}
-
-static void tcp_accept_incoming_migration(void *opaque)
-{
-    struct sockaddr_in addr;
-    socklen_t addrlen = sizeof(addr);
-    int s = (unsigned long)opaque;
-    QEMUFile *f;
-    int c, ret;
-
-    do {
-        c = accept(s, (struct sockaddr *)&addr, &addrlen);
-    } while (c == -1 && socket_error() == EINTR);
-
-    dprintf("accepted migration\n");
-
-    if (c == -1) {
-        fprintf(stderr, "could not accept migration connection\n");
-        return;
-    }
-
-    f = qemu_fopen_socket(c);
-    if (f == NULL) {
-        fprintf(stderr, "could not qemu_fopen socket\n");
-        goto out;
-    }
-
-    vm_stop(0); /* just in case */
-    ret = qemu_loadvm_state(f);
-    if (ret < 0) {
-        fprintf(stderr, "load of migration failed\n");
-        goto out_fopen;
-    }
-    qemu_announce_self();
-    dprintf("successfully loaded vm state\n");
-
-    /* we've successfully migrated, close the server socket */
-    qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL);
-    close(s);
-
-    vm_start();
-
-out_fopen:
-    qemu_fclose(f);
-out:
-    close(c);
-}
-
-int tcp_start_incoming_migration(const char *host_port)
-{
-    struct sockaddr_in addr;
-    int val;
-    int s;
-
-    if (parse_host_port(&addr, host_port) < 0) {
-        fprintf(stderr, "invalid host/port combination: %s\n", host_port);
-        return -EINVAL;
-    }
-
-    s = socket(PF_INET, SOCK_STREAM, 0);
-    if (s == -1)
-        return -socket_error();
-
-    val = 1;
-    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
-
-    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1)
-        goto err;
-
-    if (listen(s, 1) == -1)
-        goto err;
-
-    qemu_set_fd_handler2(s, NULL, tcp_accept_incoming_migration, NULL,
-                         (void *)(unsigned long)s);
-
-    return 0;
-
-err:
-    close(s);
-    return -socket_error();
-}
diff --git a/migration.c b/migration.c
deleted file mode 100644
index cdcdd12..0000000
--- a/migration.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * QEMU live migration
- *
- * Copyright IBM, Corp. 2008
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu-common.h"
-#include "migration/migration.h"
-#include "monitor/monitor.h"
-#include "buffered_file.h"
-#include "sysemu/sysemu.h"
-#include "block/block.h"
-#include "qemu/sockets.h"
-
-//#define DEBUG_MIGRATION
-
-#ifdef DEBUG_MIGRATION
-#define dprintf(fmt, ...) \
-    do { printf("migration: " fmt, ## __VA_ARGS__); } while (0)
-#else
-#define dprintf(fmt, ...) \
-    do { } while (0)
-#endif
-
-/* Migration speed throttling */
-static uint32_t max_throttle = (32 << 20);
-
-static MigrationState *current_migration;
-
-void qemu_start_incoming_migration(const char *uri)
-{
-    const char *p;
-
-    if (strstart(uri, "tcp:", &p))
-        tcp_start_incoming_migration(p);
-#if !defined(WIN32)
-    else if (strstart(uri, "exec:", &p))
-        exec_start_incoming_migration(p);
-#endif
-    else
-        fprintf(stderr, "unknown migration protocol: %s\n", uri);
-}
-
-void do_migrate(Monitor *mon, int detach, const char *uri)
-{
-    MigrationState *s = NULL;
-    const char *p;
-
-    if (strstart(uri, "tcp:", &p))
-        s = tcp_start_outgoing_migration(p, max_throttle, detach);
-#if !defined(WIN32)
-    else if (strstart(uri, "exec:", &p))
-        s = exec_start_outgoing_migration(p, max_throttle, detach);
-#endif
-    else
-        monitor_printf(mon, "unknown migration protocol: %s\n", uri);
-
-    if (s == NULL)
-        monitor_printf(mon, "migration failed\n");
-    else {
-        if (current_migration)
-            current_migration->release(current_migration);
-
-        current_migration = s;
-    }
-}
-
-void do_migrate_cancel(Monitor *mon)
-{
-    MigrationState *s = current_migration;
-
-    if (s)
-        s->cancel(s);
-}
-
-void do_migrate_set_speed(Monitor *mon, const char *value)
-{
-    double d;
-    char *ptr;
-    FdMigrationState *s;
-
-    d = strtod(value, &ptr);
-    switch (*ptr) {
-    case 'G': case 'g':
-        d *= 1024;
-    case 'M': case 'm':
-        d *= 1024;
-    case 'K': case 'k':
-        d *= 1024;
-    default:
-        break;
-    }
-
-    max_throttle = (uint32_t)d;
-    s = migrate_to_fms(current_migration);
-
-    if (s) {
-        qemu_file_set_rate_limit(s->file, max_throttle);
-    }
-    
-}
-
-/* amount of nanoseconds we are willing to wait for migration to be down.
- * the choice of nanoseconds is because it is the maximum resolution that
- * get_clock() can achieve. It is an internal measure. All user-visible
- * units must be in seconds */
-static uint64_t max_downtime = 30000000;
-
-uint64_t migrate_max_downtime(void)
-{
-    return max_downtime;
-}
-
-void do_migrate_set_downtime(Monitor *mon, const char *value)
-{
-    char *ptr;
-    double d;
-
-    d = strtod(value, &ptr);
-    if (!strcmp(ptr,"ms")) {
-        d *= 1000000;
-    } else if (!strcmp(ptr,"us")) {
-        d *= 1000;
-    } else if (!strcmp(ptr,"ns")) {
-    } else {
-        /* all else considered to be seconds */
-        d *= 1000000000;
-    }
-
-    max_downtime = (uint64_t)d;
-}
-
-void do_info_migrate(Monitor *mon)
-{
-    MigrationState *s = current_migration;
-
-    if (s) {
-        monitor_printf(mon, "Migration status: ");
-        switch (s->get_status(s)) {
-        case MIG_STATE_ACTIVE:
-            monitor_printf(mon, "active\n");
-            monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n", ram_bytes_transferred() >> 10);
-            monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n", ram_bytes_remaining() >> 10);
-            monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n", ram_bytes_total() >> 10);
-            break;
-        case MIG_STATE_COMPLETED:
-            monitor_printf(mon, "completed\n");
-            break;
-        case MIG_STATE_ERROR:
-            monitor_printf(mon, "failed\n");
-            break;
-        case MIG_STATE_CANCELLED:
-            monitor_printf(mon, "cancelled\n");
-            break;
-        }
-    }
-}
-
-/* shared migration helpers */
-
-void migrate_fd_monitor_suspend(FdMigrationState *s)
-{
-    s->mon_resume = cur_mon;
-    if (monitor_suspend(cur_mon) == 0)
-        dprintf("suspending monitor\n");
-    else
-        monitor_printf(cur_mon, "terminal does not allow synchronous "
-                       "migration, continuing detached\n");
-}
-
-void migrate_fd_error(FdMigrationState *s)
-{
-    dprintf("setting error state\n");
-    s->state = MIG_STATE_ERROR;
-    migrate_fd_cleanup(s);
-}
-
-void migrate_fd_cleanup(FdMigrationState *s)
-{
-    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
-
-    if (s->file) {
-        dprintf("closing file\n");
-        qemu_fclose(s->file);
-    }
-
-    if (s->fd != -1)
-        close(s->fd);
-
-    /* Don't resume monitor until we've flushed all of the buffers */
-    if (s->mon_resume)
-        monitor_resume(s->mon_resume);
-
-    s->fd = -1;
-}
-
-void migrate_fd_put_notify(void *opaque)
-{
-    FdMigrationState *s = opaque;
-
-    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
-    qemu_file_put_notify(s->file);
-}
-
-ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)
-{
-    FdMigrationState *s = opaque;
-    ssize_t ret;
-
-    do {
-        ret = s->write(s, data, size);
-    } while (ret == -1 && ((s->get_error(s)) == EINTR));
-
-    if (ret == -1)
-        ret = -(s->get_error(s));
-
-    if (ret == -EAGAIN)
-        qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
-
-    return ret;
-}
-
-void migrate_fd_connect(FdMigrationState *s)
-{
-    int ret;
-
-    s->file = qemu_fopen_ops_buffered(s,
-                                      s->bandwidth_limit,
-                                      migrate_fd_put_buffer,
-                                      migrate_fd_put_ready,
-                                      migrate_fd_wait_for_unfreeze,
-                                      migrate_fd_close);
-
-    dprintf("beginning savevm\n");
-    ret = qemu_savevm_state_begin(s->file);
-    if (ret < 0) {
-        dprintf("failed, %d\n", ret);
-        migrate_fd_error(s);
-        return;
-    }
-
-    migrate_fd_put_ready(s);
-}
-
-void migrate_fd_put_ready(void *opaque)
-{
-    FdMigrationState *s = opaque;
-
-    if (s->state != MIG_STATE_ACTIVE) {
-        dprintf("put_ready returning because of non-active state\n");
-        return;
-    }
-
-    dprintf("iterate\n");
-    if (qemu_savevm_state_iterate(s->file) == 1) {
-        int state;
-        dprintf("done iterating\n");
-        vm_stop(0);
-
-        bdrv_flush_all();
-        if ((qemu_savevm_state_complete(s->file)) < 0) {
-            vm_start();
-            state = MIG_STATE_ERROR;
-        } else {
-            state = MIG_STATE_COMPLETED;
-        }
-        migrate_fd_cleanup(s);
-        s->state = state;
-    }
-}
-
-int migrate_fd_get_status(MigrationState *mig_state)
-{
-    FdMigrationState *s = migrate_to_fms(mig_state);
-    return s->state;
-}
-
-void migrate_fd_cancel(MigrationState *mig_state)
-{
-    FdMigrationState *s = migrate_to_fms(mig_state);
-
-    if (s->state != MIG_STATE_ACTIVE)
-        return;
-
-    dprintf("cancelling migration\n");
-
-    s->state = MIG_STATE_CANCELLED;
-
-    migrate_fd_cleanup(s);
-}
-
-void migrate_fd_release(MigrationState *mig_state)
-{
-    FdMigrationState *s = migrate_to_fms(mig_state);
-
-    dprintf("releasing state\n");
-   
-    if (s->state == MIG_STATE_ACTIVE) {
-        s->state = MIG_STATE_CANCELLED;
-        migrate_fd_cleanup(s);
-    }
-    free(s);
-}
-
-void migrate_fd_wait_for_unfreeze(void *opaque)
-{
-    FdMigrationState *s = opaque;
-    int ret;
-
-    dprintf("wait for unfreeze\n");
-    if (s->state != MIG_STATE_ACTIVE)
-        return;
-
-    do {
-        fd_set wfds;
-
-        FD_ZERO(&wfds);
-        FD_SET(s->fd, &wfds);
-
-        ret = select(s->fd + 1, NULL, &wfds, NULL, NULL);
-    } while (ret == -1 && (s->get_error(s)) == EINTR);
-}
-
-int migrate_fd_close(void *opaque)
-{
-    FdMigrationState *s = opaque;
-
-    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
-    return s->close(s);
-}
diff --git a/monitor-android.c b/monitor-android.c
new file mode 100644
index 0000000..5c2eb10
--- /dev/null
+++ b/monitor-android.c
@@ -0,0 +1,168 @@
+#include "monitor/monitor.h"
+
+#include <stdarg.h>
+#include "hw/hw.h"
+
+struct Monitor {
+    CharDriverState *chr;
+    int mux_out;
+    // int reset_seen;
+    int flags;
+    // int suspend_cnt;
+    uint8_t outbuf[1024];
+    int outbuf_index;
+    // ReadLineState *rs;
+    // CPUOldState *mon_cpu;
+    // BlockDriverCompletionFunc *password_completion_cb;
+    // void *password_opaque;
+    QLIST_ENTRY(Monitor) entry;
+    //int has_quit;
+#ifdef CONFIG_ANDROID
+    void*            fake_opaque;
+    MonitorFakeFunc  fake_func;
+    int64_t          fake_count;
+
+#endif
+};
+
+// Minimalistic / fake implementation of the QEMU Monitor.
+
+Monitor* cur_mon;
+
+/* Return non-zero iff we have a current monitor, and it is in QMP mode.  */
+int monitor_cur_is_qmp(void)
+{
+    return 0;
+}
+
+Monitor*
+monitor_fake_new(void* opaque, MonitorFakeFunc cb)
+{
+    Monitor* mon;
+
+    assert(cb != NULL);
+    mon = g_malloc0(sizeof(*mon));
+    mon->fake_opaque = opaque;
+    mon->fake_func   = cb;
+    mon->fake_count  = 0;
+
+    return mon;
+}
+
+int
+monitor_fake_get_bytes(Monitor* mon)
+{
+    assert(mon->fake_func != NULL);
+    return mon->fake_count;
+}
+
+void
+monitor_fake_free(Monitor* mon)
+{
+    assert(mon->fake_func != NULL);
+    free(mon);
+}
+
+/* This replaces the definition in monitor.c which is in a
+ * #ifndef CONFIG_ANDROID .. #endif block.
+ */
+void monitor_flush(Monitor *mon)
+{
+    if (!mon)
+        return;
+
+    if (mon->fake_func != NULL) {
+        mon->fake_func(mon->fake_opaque, (void*)mon->outbuf, mon->outbuf_index);
+        mon->outbuf_index = 0;
+        mon->fake_count += mon->outbuf_index;
+    } else if (!mon->mux_out) {
+        qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
+        mon->outbuf_index = 0;
+    }
+}
+
+/* flush at every end of line or if the buffer is full */
+static void monitor_puts(Monitor *mon, const char *str)
+{
+    char c;
+
+    if (!mon)
+        return;
+
+    for(;;) {
+        c = *str++;
+        if (c == '\0')
+            break;
+        if (c == '\n')
+            mon->outbuf[mon->outbuf_index++] = '\r';
+        mon->outbuf[mon->outbuf_index++] = c;
+        if (mon->outbuf_index >= (sizeof(mon->outbuf) - 1)
+            || c == '\n')
+            monitor_flush(mon);
+    }
+}
+
+void monitor_vprintf(Monitor* mon, const char* fmt, va_list args) {
+    char buf[4096];
+    vsnprintf(buf, sizeof(buf), fmt, args);
+    monitor_puts(mon, buf);
+}
+
+void monitor_printf(Monitor *mon, const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    monitor_vprintf(mon, fmt, ap);
+    va_end(ap);
+}
+
+void monitor_print_filename(Monitor *mon, const char *filename)
+{
+    int i;
+
+    for (i = 0; filename[i]; i++) {
+        switch (filename[i]) {
+        case ' ':
+        case '"':
+        case '\\':
+            monitor_printf(mon, "\\%c", filename[i]);
+            break;
+        case '\t':
+            monitor_printf(mon, "\\t");
+            break;
+        case '\r':
+            monitor_printf(mon, "\\r");
+            break;
+        case '\n':
+            monitor_printf(mon, "\\n");
+            break;
+        default:
+            monitor_printf(mon, "%c", filename[i]);
+            break;
+        }
+    }
+}
+
+void monitor_protocol_event(MonitorEvent event, QObject *data)
+{
+    /* XXX: TODO */
+}
+
+void monitor_set_error(Monitor *mon, QError *qerror)
+{
+    QDECREF(qerror);
+}
+
+void monitor_init(CharDriverState* cs, int flags) {
+    // Nothing.
+}
+
+/* boot_set handler */
+static QEMUBootSetHandler *qemu_boot_set_handler = NULL;
+static void *boot_opaque;
+
+void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
+{
+    qemu_boot_set_handler = func;
+    boot_opaque = opaque;
+}
diff --git a/monitor.c b/monitor.c
deleted file mode 100644
index e48a559..0000000
--- a/monitor.c
+++ /dev/null
@@ -1,3163 +0,0 @@
-/*
- * QEMU monitor
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <dirent.h>
-#include "hw/hw.h"
-#include "hw/qdev.h"
-#include "hw/usb.h"
-#include "hw/pcmcia.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
-#include "sysemu/watchdog.h"
-#include "exec/gdbstub.h"
-#include "net/net.h"
-#include "sysemu/char.h"
-#include "sysemu/sysemu.h"
-#include "monitor/monitor.h"
-#include "monitor/readline.h"
-#include "ui/console.h"
-#include "sysemu/blockdev.h"
-#include "audio/audio.h"
-#include "disas/disas.h"
-#include "sysemu/balloon.h"
-#include "qemu/timer.h"
-#include "migration/migration.h"
-#include "sysemu/kvm.h"
-#include "qemu/acl.h"
-#include "exec/exec-all.h"
-
-//#define DEBUG
-//#define DEBUG_COMPLETION
-
-/*
- * Supported types:
- *
- * 'F'          filename
- * 'B'          block device name
- * 's'          string (accept optional quote)
- * 'i'          32 bit integer
- * 'l'          target long (32 or 64 bit)
- * '/'          optional gdb-like print format (like "/10x")
- *
- * '?'          optional type (for 'F', 's' and 'i')
- *
- */
-
-typedef struct mon_cmd_t {
-    const char *name;
-    const char *args_type;
-    void *handler;
-    const char *params;
-    const char *help;
-} mon_cmd_t;
-
-#define MON_CMD_T_INITIALIZER { NULL, NULL, NULL, NULL, NULL }
-
-struct Monitor {
-    CharDriverState *chr;
-    int mux_out;
-    int reset_seen;
-    int flags;
-    int suspend_cnt;
-    uint8_t outbuf[1024];
-    int outbuf_index;
-    ReadLineState *rs;
-    CPUState *mon_cpu;
-    BlockDriverCompletionFunc *password_completion_cb;
-    void *password_opaque;
-    QLIST_ENTRY(Monitor) entry;
-    int has_quit;
-#ifdef CONFIG_ANDROID
-    void*            fake_opaque;
-    MonitorFakeFunc  fake_func;
-    int64_t          fake_count;
-
-#endif
-};
-
-#ifdef CONFIG_ANDROID
-#include "android/monitor.h"
-#endif
-
-static QLIST_HEAD(mon_list, Monitor) mon_list;
-
-#if defined(TARGET_I386)
-static void do_inject_mce(Monitor *mon,
-                          int cpu_index, int bank,
-                          unsigned status_hi, unsigned status_lo,
-                          unsigned mcg_status_hi, unsigned mcg_status_lo,
-                          unsigned addr_hi, unsigned addr_lo,
-                          unsigned misc_hi, unsigned misc_lo)
-{
-    CPUState *cenv;
-    uint64_t status = ((uint64_t)status_hi << 32) | status_lo;
-    uint64_t mcg_status = ((uint64_t)mcg_status_hi << 32) | mcg_status_lo;
-    uint64_t addr = ((uint64_t)addr_hi << 32) | addr_lo;
-    uint64_t misc = ((uint64_t)misc_hi << 32) | misc_lo;
-
-    for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu)
-        if (cenv->cpu_index == cpu_index && cenv->mcg_cap) {
-            cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
-            break;
-        }
-}
-#endif
-
-static const mon_cmd_t mon_cmds[];
-static const mon_cmd_t info_cmds[];
-
-Monitor *cur_mon = NULL;
-
-static void monitor_command_cb(Monitor *mon, const char *cmdline,
-                               void *opaque);
-
-static inline int qmp_cmd_mode(const Monitor *mon)
-{
-    //return (mon->mc ? mon->mc->command_mode : 0);
-    return 0;
-}
-
-/* Return true if in control mode, false otherwise */
-static inline int monitor_ctrl_mode(const Monitor *mon)
-{
-    return (mon->flags & MONITOR_USE_CONTROL);
-}
-
-/* Return non-zero iff we have a current monitor, and it is in QMP mode.  */
-int monitor_cur_is_qmp(void)
-{
-    return cur_mon && monitor_ctrl_mode(cur_mon);
-}
-
-static void monitor_read_command(Monitor *mon, int show_prompt)
-{
-    readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL);
-    if (show_prompt)
-        readline_show_prompt(mon->rs);
-}
-
-static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
-                                 void *opaque)
-{
-    if (mon->rs) {
-        readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
-        /* prompt is printed on return from the command handler */
-        return 0;
-    } else {
-        monitor_printf(mon, "terminal does not support password prompting\n");
-        return -ENOTTY;
-    }
-}
-
-#ifndef CONFIG_ANDROID /* See monitor-android.h */
-void monitor_flush(Monitor *mon)
-{
-    if (mon && mon->outbuf_index != 0 && !mon->mux_out) {
-        qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
-        mon->outbuf_index = 0;
-    }
-}
-#endif
-
-/* flush at every end of line or if the buffer is full */
-static void monitor_puts(Monitor *mon, const char *str)
-{
-    char c;
-
-    if (!mon)
-        return;
-
-    for(;;) {
-        c = *str++;
-        if (c == '\0')
-            break;
-        if (c == '\n')
-            mon->outbuf[mon->outbuf_index++] = '\r';
-        mon->outbuf[mon->outbuf_index++] = c;
-        if (mon->outbuf_index >= (sizeof(mon->outbuf) - 1)
-            || c == '\n')
-            monitor_flush(mon);
-    }
-}
-
-void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
-{
-    char buf[4096];
-    vsnprintf(buf, sizeof(buf), fmt, ap);
-    monitor_puts(mon, buf);
-}
-
-void monitor_printf(Monitor *mon, const char *fmt, ...)
-{
-    va_list ap;
-    va_start(ap, fmt);
-    monitor_vprintf(mon, fmt, ap);
-    va_end(ap);
-}
-
-void monitor_print_filename(Monitor *mon, const char *filename)
-{
-    int i;
-
-    for (i = 0; filename[i]; i++) {
-        switch (filename[i]) {
-        case ' ':
-        case '"':
-        case '\\':
-            monitor_printf(mon, "\\%c", filename[i]);
-            break;
-        case '\t':
-            monitor_printf(mon, "\\t");
-            break;
-        case '\r':
-            monitor_printf(mon, "\\r");
-            break;
-        case '\n':
-            monitor_printf(mon, "\\n");
-            break;
-        default:
-            monitor_printf(mon, "%c", filename[i]);
-            break;
-        }
-    }
-}
-
-static int GCC_FMT_ATTR(2, 3) monitor_fprintf(FILE *stream,
-                                              const char *fmt, ...)
-{
-    va_list ap;
-    va_start(ap, fmt);
-    monitor_vprintf((Monitor *)stream, fmt, ap);
-    va_end(ap);
-    return 0;
-}
-
-void monitor_protocol_event(MonitorEvent event, QObject *data)
-{
-    /* XXX: TODO */
-}
-
-static int compare_cmd(const char *name, const char *list)
-{
-    const char *p, *pstart;
-    int len;
-    len = strlen(name);
-    p = list;
-    for(;;) {
-        pstart = p;
-        p = strchr(p, '|');
-        if (!p)
-            p = pstart + strlen(pstart);
-        if ((p - pstart) == len && !memcmp(pstart, name, len))
-            return 1;
-        if (*p == '\0')
-            break;
-        p++;
-    }
-    return 0;
-}
-
-static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
-                          const char *prefix, const char *name)
-{
-    const mon_cmd_t *cmd;
-
-    for(cmd = cmds; cmd->name != NULL; cmd++) {
-        if (!name || !strcmp(name, cmd->name))
-            monitor_printf(mon, "%s%s %s -- %s\n", prefix, cmd->name,
-                           cmd->params, cmd->help);
-    }
-}
-
-static void help_cmd(Monitor *mon, const char *name)
-{
-    if (name && !strcmp(name, "info")) {
-        help_cmd_dump(mon, info_cmds, "info ", NULL);
-    } else {
-        help_cmd_dump(mon, mon_cmds, "", name);
-        if (name && !strcmp(name, "log")) {
-            const CPULogItem *item;
-            monitor_printf(mon, "Log items (comma separated):\n");
-            monitor_printf(mon, "%-10s %s\n", "none", "remove all logs");
-            for(item = cpu_log_items; item->mask != 0; item++) {
-                monitor_printf(mon, "%-10s %s\n", item->name, item->help);
-            }
-        }
-    }
-}
-
-static void do_info(Monitor *mon, const char *item)
-{
-    const mon_cmd_t *cmd;
-    void (*handler)(Monitor *);
-
-    if (!item)
-        goto help;
-    for(cmd = info_cmds; cmd->name != NULL; cmd++) {
-        if (compare_cmd(item, cmd->name))
-            goto found;
-    }
- help:
-    help_cmd(mon, "info");
-    return;
- found:
-    handler = cmd->handler;
-    handler(mon);
-}
-
-static void do_info_version(Monitor *mon)
-{
-    monitor_printf(mon, "%s\n", QEMU_VERSION QEMU_PKGVERSION);
-}
-
-static void do_info_name(Monitor *mon)
-{
-    if (qemu_name)
-        monitor_printf(mon, "%s\n", qemu_name);
-}
-
-#if defined(TARGET_I386)
-static void do_info_hpet(Monitor *mon)
-{
-    monitor_printf(mon, "HPET is %s by QEMU\n",
-                   (no_hpet) ? "disabled" : "enabled");
-}
-#endif
-
-static void do_info_uuid(Monitor *mon)
-{
-    monitor_printf(mon, UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1],
-                   qemu_uuid[2], qemu_uuid[3], qemu_uuid[4], qemu_uuid[5],
-                   qemu_uuid[6], qemu_uuid[7], qemu_uuid[8], qemu_uuid[9],
-                   qemu_uuid[10], qemu_uuid[11], qemu_uuid[12], qemu_uuid[13],
-                   qemu_uuid[14], qemu_uuid[15]);
-}
-
-/* get the current CPU defined by the user */
-static int mon_set_cpu(int cpu_index)
-{
-    CPUState *env;
-
-    for(env = first_cpu; env != NULL; env = env->next_cpu) {
-        if (env->cpu_index == cpu_index) {
-            cur_mon->mon_cpu = env;
-            return 0;
-        }
-    }
-    return -1;
-}
-
-static CPUState *mon_get_cpu(void)
-{
-    if (!cur_mon->mon_cpu) {
-        mon_set_cpu(0);
-    }
-    cpu_synchronize_state(cur_mon->mon_cpu, 0);
-    return cur_mon->mon_cpu;
-}
-
-static void do_info_registers(Monitor *mon)
-{
-    CPUState *env;
-    env = mon_get_cpu();
-    if (!env)
-        return;
-#ifdef TARGET_I386
-    cpu_dump_state(env, (FILE *)mon, monitor_fprintf,
-                   X86_DUMP_FPU);
-#else
-    cpu_dump_state(env, (FILE *)mon, monitor_fprintf,
-                   0);
-#endif
-}
-
-static void do_info_cpus(Monitor *mon)
-{
-    CPUState *env;
-
-    /* just to set the default cpu if not already done */
-    mon_get_cpu();
-
-    for(env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu_synchronize_state(env, 0);
-        monitor_printf(mon, "%c CPU #%d:",
-                       (env == mon->mon_cpu) ? '*' : ' ',
-                       env->cpu_index);
-#if defined(TARGET_I386)
-        monitor_printf(mon, " pc=0x" TARGET_FMT_lx,
-                       env->eip + env->segs[R_CS].base);
-#elif defined(TARGET_PPC)
-        monitor_printf(mon, " nip=0x" TARGET_FMT_lx, env->nip);
-#elif defined(TARGET_SPARC)
-        monitor_printf(mon, " pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx,
-                       env->pc, env->npc);
-#elif defined(TARGET_MIPS)
-        monitor_printf(mon, " PC=0x" TARGET_FMT_lx, env->active_tc.PC);
-#endif
-        if (env->halted)
-            monitor_printf(mon, " (halted)");
-        monitor_printf(mon, "\n");
-    }
-}
-
-static void do_cpu_set(Monitor *mon, int index)
-{
-    if (mon_set_cpu(index) < 0)
-        monitor_printf(mon, "Invalid CPU index\n");
-}
-
-static void do_info_jit(Monitor *mon)
-{
-    dump_exec_info((FILE *)mon, monitor_fprintf);
-}
-
-static void do_info_history(Monitor *mon)
-{
-    int i;
-    const char *str;
-
-    if (!mon->rs)
-        return;
-    i = 0;
-    for(;;) {
-        str = readline_get_history(mon->rs, i);
-        if (!str)
-            break;
-        monitor_printf(mon, "%d: '%s'\n", i, str);
-        i++;
-    }
-}
-
-#if defined(TARGET_PPC)
-/* XXX: not implemented in other targets */
-static void do_info_cpu_stats(Monitor *mon)
-{
-    CPUState *env;
-
-    env = mon_get_cpu();
-    cpu_dump_statistics(env, (FILE *)mon, &monitor_fprintf, 0);
-}
-#endif
-
-static void do_quit(Monitor *mon)
-{
-    if ((mon->flags & MONITOR_QUIT_DOESNT_EXIT) == 0) {
-        exit(0);
-    }
-    /* we cannot destroy the monitor just yet, so flag it instead */
-    mon->has_quit = 1;
-}
-
-static void change_vnc_password_cb(Monitor *mon, const char *password,
-                                   void *opaque)
-{
-    if (vnc_display_password(NULL, password) < 0)
-        monitor_printf(mon, "could not set VNC server password\n");
-
-    monitor_read_command(mon, 1);
-}
-
-static void do_change_vnc(Monitor *mon, const char *target, const char *arg)
-{
-    if (strcmp(target, "passwd") == 0 ||
-        strcmp(target, "password") == 0) {
-        if (arg) {
-            char password[9];
-            strncpy(password, arg, sizeof(password));
-            password[sizeof(password) - 1] = '\0';
-            change_vnc_password_cb(mon, password, NULL);
-        } else {
-            monitor_read_password(mon, change_vnc_password_cb, NULL);
-        }
-    } else {
-        if (vnc_display_open(NULL, target) < 0)
-            monitor_printf(mon, "could not start VNC server on %s\n", target);
-    }
-}
-
-static void do_change(Monitor *mon, const char *device, const char *target,
-                      const char *arg)
-{
-    if (strcmp(device, "vnc") == 0) {
-        do_change_vnc(mon, target, arg);
-    } else {
-        do_change_block(mon, device, target, arg);
-    }
-}
-
-static void do_screen_dump(Monitor *mon, const char *filename)
-{
-    vga_hw_screen_dump(filename);
-}
-
-static void do_logfile(Monitor *mon, const char *filename)
-{
-    cpu_set_log_filename(filename);
-}
-
-static void do_log(Monitor *mon, const char *items)
-{
-    int mask;
-
-    if (!strcmp(items, "none")) {
-        mask = 0;
-    } else {
-        mask = cpu_str_to_log_mask(items);
-        if (!mask) {
-            help_cmd(mon, "log");
-            return;
-        }
-    }
-    cpu_set_log(mask);
-}
-
-static void do_singlestep(Monitor *mon, const char *option)
-{
-    if (!option || !strcmp(option, "on")) {
-        singlestep = 1;
-    } else if (!strcmp(option, "off")) {
-        singlestep = 0;
-    } else {
-        monitor_printf(mon, "unexpected option %s\n", option);
-    }
-}
-
-static void do_stop(Monitor *mon)
-{
-    vm_stop(EXCP_INTERRUPT);
-}
-
-static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs);
-
-struct bdrv_iterate_context {
-    Monitor *mon;
-    int err;
-};
-
-static void do_cont(Monitor *mon)
-{
-    struct bdrv_iterate_context context = { mon, 0 };
-
-    bdrv_iterate(encrypted_bdrv_it, &context);
-    /* only resume the vm if all keys are set and valid */
-    if (!context.err)
-        vm_start();
-}
-
-static void bdrv_key_cb(void *opaque, int err)
-{
-    Monitor *mon = opaque;
-
-    /* another key was set successfully, retry to continue */
-    if (!err)
-        do_cont(mon);
-}
-
-static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs)
-{
-    struct bdrv_iterate_context *context = opaque;
-
-    if (!context->err && bdrv_key_required(bs)) {
-        context->err = -EBUSY;
-        monitor_read_bdrv_key_start(context->mon, bs, bdrv_key_cb,
-                                    context->mon);
-    }
-}
-
-static void do_gdbserver(Monitor *mon, const char *device)
-{
-    if (!device)
-        device = "tcp::" DEFAULT_GDBSTUB_PORT;
-    if (gdbserver_start(device) < 0) {
-        monitor_printf(mon, "Could not open gdbserver on device '%s'\n",
-                       device);
-    } else if (strcmp(device, "none") == 0) {
-        monitor_printf(mon, "Disabled gdbserver\n");
-    } else {
-        monitor_printf(mon, "Waiting for gdb connection on device '%s'\n",
-                       device);
-    }
-}
-
-static void do_watchdog_action(Monitor *mon, const char *action)
-{
-    if (select_watchdog_action(action) == -1) {
-        monitor_printf(mon, "Unknown watchdog action '%s'\n", action);
-    }
-}
-
-static void monitor_printc(Monitor *mon, int c)
-{
-    monitor_printf(mon, "'");
-    switch(c) {
-    case '\'':
-        monitor_printf(mon, "\\'");
-        break;
-    case '\\':
-        monitor_printf(mon, "\\\\");
-        break;
-    case '\n':
-        monitor_printf(mon, "\\n");
-        break;
-    case '\r':
-        monitor_printf(mon, "\\r");
-        break;
-    default:
-        if (c >= 32 && c <= 126) {
-            monitor_printf(mon, "%c", c);
-        } else {
-            monitor_printf(mon, "\\x%02x", c);
-        }
-        break;
-    }
-    monitor_printf(mon, "'");
-}
-
-static void memory_dump(Monitor *mon, int count, int format, int wsize,
-                        hwaddr addr, int is_physical)
-{
-    CPUState *env;
-    int l, line_size, i, max_digits, len;
-    uint8_t buf[16];
-    uint64_t v;
-
-    if (format == 'i') {
-        int flags;
-        flags = 0;
-        env = mon_get_cpu();
-        if (!env && !is_physical)
-            return;
-#ifdef TARGET_I386
-        if (wsize == 2) {
-            flags = 1;
-        } else if (wsize == 4) {
-            flags = 0;
-        } else {
-            /* as default we use the current CS size */
-            flags = 0;
-            if (env) {
-#ifdef TARGET_X86_64
-                if ((env->efer & MSR_EFER_LMA) &&
-                    (env->segs[R_CS].flags & DESC_L_MASK))
-                    flags = 2;
-                else
-#endif
-                if (!(env->segs[R_CS].flags & DESC_B_MASK))
-                    flags = 1;
-            }
-        }
-#endif
-        monitor_disas(mon, env, addr, count, is_physical, flags);
-        return;
-    }
-
-    len = wsize * count;
-    if (wsize == 1)
-        line_size = 8;
-    else
-        line_size = 16;
-    max_digits = 0;
-
-    switch(format) {
-    case 'o':
-        max_digits = (wsize * 8 + 2) / 3;
-        break;
-    default:
-    case 'x':
-        max_digits = (wsize * 8) / 4;
-        break;
-    case 'u':
-    case 'd':
-        max_digits = (wsize * 8 * 10 + 32) / 33;
-        break;
-    case 'c':
-        wsize = 1;
-        break;
-    }
-
-    while (len > 0) {
-        if (is_physical)
-            monitor_printf(mon, TARGET_FMT_plx ":", addr);
-        else
-            monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr);
-        l = len;
-        if (l > line_size)
-            l = line_size;
-        if (is_physical) {
-            cpu_physical_memory_rw(addr, buf, l, 0);
-        } else {
-            env = mon_get_cpu();
-            if (!env)
-                break;
-            if (cpu_memory_rw_debug(env, addr, buf, l, 0) < 0) {
-                monitor_printf(mon, " Cannot access memory\n");
-                break;
-            }
-        }
-        i = 0;
-        while (i < l) {
-            switch(wsize) {
-            default:
-            case 1:
-                v = ldub_raw(buf + i);
-                break;
-            case 2:
-                v = lduw_raw(buf + i);
-                break;
-            case 4:
-                v = (uint32_t)ldl_raw(buf + i);
-                break;
-            case 8:
-                v = ldq_raw(buf + i);
-                break;
-            }
-            monitor_printf(mon, " ");
-            switch(format) {
-            case 'o':
-                monitor_printf(mon, "%#*" PRIo64, max_digits, v);
-                break;
-            case 'x':
-                monitor_printf(mon, "0x%0*" PRIx64, max_digits, v);
-                break;
-            case 'u':
-                monitor_printf(mon, "%*" PRIu64, max_digits, v);
-                break;
-            case 'd':
-                monitor_printf(mon, "%*" PRId64, max_digits, v);
-                break;
-            case 'c':
-                monitor_printc(mon, v);
-                break;
-            }
-            i += wsize;
-        }
-        monitor_printf(mon, "\n");
-        addr += l;
-        len -= l;
-    }
-}
-
-#if TARGET_LONG_BITS == 64
-#define GET_TLONG(h, l) (((uint64_t)(h) << 32) | (l))
-#else
-#define GET_TLONG(h, l) (l)
-#endif
-
-static void do_memory_dump(Monitor *mon, int count, int format, int size,
-                           uint32_t addrh, uint32_t addrl)
-{
-    target_long addr = GET_TLONG(addrh, addrl);
-    memory_dump(mon, count, format, size, addr, 0);
-}
-
-#if TARGET_PHYS_ADDR_BITS > 32
-#define GET_TPHYSADDR(h, l) (((uint64_t)(h) << 32) | (l))
-#else
-#define GET_TPHYSADDR(h, l) (l)
-#endif
-
-static void do_physical_memory_dump(Monitor *mon, int count, int format,
-                                    int size, uint32_t addrh, uint32_t addrl)
-
-{
-    hwaddr addr = GET_TPHYSADDR(addrh, addrl);
-    memory_dump(mon, count, format, size, addr, 1);
-}
-
-static void do_print(Monitor *mon, int count, int format, int size,
-                     unsigned int valh, unsigned int vall)
-{
-    hwaddr val = GET_TPHYSADDR(valh, vall);
-#if TARGET_PHYS_ADDR_BITS == 32
-    switch(format) {
-    case 'o':
-        monitor_printf(mon, "%#o", val);
-        break;
-    case 'x':
-        monitor_printf(mon, "%#x", val);
-        break;
-    case 'u':
-        monitor_printf(mon, "%u", val);
-        break;
-    default:
-    case 'd':
-        monitor_printf(mon, "%d", val);
-        break;
-    case 'c':
-        monitor_printc(mon, val);
-        break;
-    }
-#else
-    switch(format) {
-    case 'o':
-        monitor_printf(mon, "%#" PRIo64, val);
-        break;
-    case 'x':
-        monitor_printf(mon, "%#" PRIx64, val);
-        break;
-    case 'u':
-        monitor_printf(mon, "%" PRIu64, val);
-        break;
-    default:
-    case 'd':
-        monitor_printf(mon, "%" PRId64, val);
-        break;
-    case 'c':
-        monitor_printc(mon, val);
-        break;
-    }
-#endif
-    monitor_printf(mon, "\n");
-}
-
-static void do_memory_save(Monitor *mon, unsigned int valh, unsigned int vall,
-                           uint32_t size, const char *filename)
-{
-    FILE *f;
-    target_long addr = GET_TLONG(valh, vall);
-    uint32_t l;
-    CPUState *env;
-    uint8_t buf[1024];
-
-    env = mon_get_cpu();
-    if (!env)
-        return;
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        monitor_printf(mon, "could not open '%s'\n", filename);
-        return;
-    }
-    while (size != 0) {
-        l = sizeof(buf);
-        if (l > size)
-            l = size;
-        cpu_memory_rw_debug(env, addr, buf, l, 0);
-        fwrite(buf, 1, l, f);
-        addr += l;
-        size -= l;
-    }
-    fclose(f);
-}
-
-static void do_physical_memory_save(Monitor *mon, unsigned int valh,
-                                    unsigned int vall, uint32_t size,
-                                    const char *filename)
-{
-    FILE *f;
-    uint32_t l;
-    uint8_t buf[1024];
-    hwaddr addr = GET_TPHYSADDR(valh, vall);
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        monitor_printf(mon, "could not open '%s'\n", filename);
-        return;
-    }
-    while (size != 0) {
-        l = sizeof(buf);
-        if (l > size)
-            l = size;
-        cpu_physical_memory_rw(addr, buf, l, 0);
-        fwrite(buf, 1, l, f);
-        fflush(f);
-        addr += l;
-        size -= l;
-    }
-    fclose(f);
-}
-
-static void do_sum(Monitor *mon, uint32_t start, uint32_t size)
-{
-    uint32_t addr;
-    uint8_t buf[1];
-    uint16_t sum;
-
-    sum = 0;
-    for(addr = start; addr < (start + size); addr++) {
-        cpu_physical_memory_rw(addr, buf, 1, 0);
-        /* BSD sum algorithm ('sum' Unix command) */
-        sum = (sum >> 1) | (sum << 15);
-        sum += buf[0];
-    }
-    monitor_printf(mon, "%05d\n", sum);
-}
-
-typedef struct {
-    int keycode;
-    const char *name;
-} KeyDef;
-
-static const KeyDef key_defs[] = {
-    { 0x2a, "shift" },
-    { 0x36, "shift_r" },
-
-    { 0x38, "alt" },
-    { 0xb8, "alt_r" },
-    { 0x64, "altgr" },
-    { 0xe4, "altgr_r" },
-    { 0x1d, "ctrl" },
-    { 0x9d, "ctrl_r" },
-
-    { 0xdd, "menu" },
-
-    { 0x01, "esc" },
-
-    { 0x02, "1" },
-    { 0x03, "2" },
-    { 0x04, "3" },
-    { 0x05, "4" },
-    { 0x06, "5" },
-    { 0x07, "6" },
-    { 0x08, "7" },
-    { 0x09, "8" },
-    { 0x0a, "9" },
-    { 0x0b, "0" },
-    { 0x0c, "minus" },
-    { 0x0d, "equal" },
-    { 0x0e, "backspace" },
-
-    { 0x0f, "tab" },
-    { 0x10, "q" },
-    { 0x11, "w" },
-    { 0x12, "e" },
-    { 0x13, "r" },
-    { 0x14, "t" },
-    { 0x15, "y" },
-    { 0x16, "u" },
-    { 0x17, "i" },
-    { 0x18, "o" },
-    { 0x19, "p" },
-
-    { 0x1c, "ret" },
-
-    { 0x1e, "a" },
-    { 0x1f, "s" },
-    { 0x20, "d" },
-    { 0x21, "f" },
-    { 0x22, "g" },
-    { 0x23, "h" },
-    { 0x24, "j" },
-    { 0x25, "k" },
-    { 0x26, "l" },
-
-    { 0x2c, "z" },
-    { 0x2d, "x" },
-    { 0x2e, "c" },
-    { 0x2f, "v" },
-    { 0x30, "b" },
-    { 0x31, "n" },
-    { 0x32, "m" },
-    { 0x33, "comma" },
-    { 0x34, "dot" },
-    { 0x35, "slash" },
-
-    { 0x37, "asterisk" },
-
-    { 0x39, "spc" },
-    { 0x3a, "caps_lock" },
-    { 0x3b, "f1" },
-    { 0x3c, "f2" },
-    { 0x3d, "f3" },
-    { 0x3e, "f4" },
-    { 0x3f, "f5" },
-    { 0x40, "f6" },
-    { 0x41, "f7" },
-    { 0x42, "f8" },
-    { 0x43, "f9" },
-    { 0x44, "f10" },
-    { 0x45, "num_lock" },
-    { 0x46, "scroll_lock" },
-
-    { 0xb5, "kp_divide" },
-    { 0x37, "kp_multiply" },
-    { 0x4a, "kp_subtract" },
-    { 0x4e, "kp_add" },
-    { 0x9c, "kp_enter" },
-    { 0x53, "kp_decimal" },
-    { 0x54, "sysrq" },
-
-    { 0x52, "kp_0" },
-    { 0x4f, "kp_1" },
-    { 0x50, "kp_2" },
-    { 0x51, "kp_3" },
-    { 0x4b, "kp_4" },
-    { 0x4c, "kp_5" },
-    { 0x4d, "kp_6" },
-    { 0x47, "kp_7" },
-    { 0x48, "kp_8" },
-    { 0x49, "kp_9" },
-
-    { 0x56, "<" },
-
-    { 0x57, "f11" },
-    { 0x58, "f12" },
-
-    { 0xb7, "print" },
-
-    { 0xc7, "home" },
-    { 0xc9, "pgup" },
-    { 0xd1, "pgdn" },
-    { 0xcf, "end" },
-
-    { 0xcb, "left" },
-    { 0xc8, "up" },
-    { 0xd0, "down" },
-    { 0xcd, "right" },
-
-    { 0xd2, "insert" },
-    { 0xd3, "delete" },
-#if defined(TARGET_SPARC) && !defined(TARGET_SPARC64)
-    { 0xf0, "stop" },
-    { 0xf1, "again" },
-    { 0xf2, "props" },
-    { 0xf3, "undo" },
-    { 0xf4, "front" },
-    { 0xf5, "copy" },
-    { 0xf6, "open" },
-    { 0xf7, "paste" },
-    { 0xf8, "find" },
-    { 0xf9, "cut" },
-    { 0xfa, "lf" },
-    { 0xfb, "help" },
-    { 0xfc, "meta_l" },
-    { 0xfd, "meta_r" },
-    { 0xfe, "compose" },
-#endif
-    { 0, NULL },
-};
-
-static int get_keycode(const char *key)
-{
-    const KeyDef *p;
-    char *endp;
-    int ret;
-
-    for(p = key_defs; p->name != NULL; p++) {
-        if (!strcmp(key, p->name))
-            return p->keycode;
-    }
-    if (strstart(key, "0x", NULL)) {
-        ret = strtoul(key, &endp, 0);
-        if (*endp == '\0' && ret >= 0x01 && ret <= 0xff)
-            return ret;
-    }
-    return -1;
-}
-
-#define MAX_KEYCODES 16
-static uint8_t keycodes[MAX_KEYCODES];
-static int nb_pending_keycodes;
-static QEMUTimer *key_timer;
-
-static void release_keys(void *opaque)
-{
-    int keycode;
-
-    while (nb_pending_keycodes > 0) {
-        nb_pending_keycodes--;
-        keycode = keycodes[nb_pending_keycodes];
-        if (keycode & 0x80)
-            kbd_put_keycode(0xe0);
-        kbd_put_keycode(keycode | 0x80);
-    }
-}
-
-static void do_sendkey(Monitor *mon, const char *string, int has_hold_time,
-                       int hold_time)
-{
-    char keyname_buf[16];
-    char *separator;
-    int keyname_len, keycode, i;
-
-    if (nb_pending_keycodes > 0) {
-        qemu_del_timer(key_timer);
-        release_keys(NULL);
-    }
-    if (!has_hold_time)
-        hold_time = 100;
-    i = 0;
-    while (1) {
-        separator = strchr(string, '-');
-        keyname_len = separator ? separator - string : strlen(string);
-        if (keyname_len > 0) {
-            pstrcpy(keyname_buf, sizeof(keyname_buf), string);
-            if (keyname_len > sizeof(keyname_buf) - 1) {
-                monitor_printf(mon, "invalid key: '%s...'\n", keyname_buf);
-                return;
-            }
-            if (i == MAX_KEYCODES) {
-                monitor_printf(mon, "too many keys\n");
-                return;
-            }
-            keyname_buf[keyname_len] = 0;
-            keycode = get_keycode(keyname_buf);
-            if (keycode < 0) {
-                monitor_printf(mon, "unknown key: '%s'\n", keyname_buf);
-                return;
-            }
-            keycodes[i++] = keycode;
-        }
-        if (!separator)
-            break;
-        string = separator + 1;
-    }
-    nb_pending_keycodes = i;
-    /* key down events */
-    for (i = 0; i < nb_pending_keycodes; i++) {
-        keycode = keycodes[i];
-        if (keycode & 0x80)
-            kbd_put_keycode(0xe0);
-        kbd_put_keycode(keycode & 0x7f);
-    }
-    /* delayed key up events */
-    qemu_mod_timer(key_timer, qemu_get_clock_ms(vm_clock) + hold_time);
-}
-
-static int mouse_button_state;
-
-static void do_mouse_move(Monitor *mon, const char *dx_str, const char *dy_str,
-                          const char *dz_str)
-{
-    int dx, dy, dz;
-    dx = strtol(dx_str, NULL, 0);
-    dy = strtol(dy_str, NULL, 0);
-    dz = 0;
-    if (dz_str)
-        dz = strtol(dz_str, NULL, 0);
-    kbd_mouse_event(dx, dy, dz, mouse_button_state);
-}
-
-static void do_mouse_button(Monitor *mon, int button_state)
-{
-    mouse_button_state = button_state;
-    kbd_mouse_event(0, 0, 0, mouse_button_state);
-}
-
-static void do_ioport_read(Monitor *mon, int count, int format, int size,
-                           int addr, int has_index, int index)
-{
-    uint32_t val;
-    int suffix;
-
-    if (has_index) {
-        cpu_outb(addr & 0xffff, index & 0xff);
-        addr++;
-    }
-    addr &= 0xffff;
-
-    switch(size) {
-    default:
-    case 1:
-        val = cpu_inb(addr);
-        suffix = 'b';
-        break;
-    case 2:
-        val = cpu_inw(addr);
-        suffix = 'w';
-        break;
-    case 4:
-        val = cpu_inl(addr);
-        suffix = 'l';
-        break;
-    }
-    monitor_printf(mon, "port%c[0x%04x] = %#0*x\n",
-                   suffix, addr, size * 2, val);
-}
-
-/* boot_set handler */
-static QEMUBootSetHandler *qemu_boot_set_handler = NULL;
-static void *boot_opaque;
-
-void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
-{
-    qemu_boot_set_handler = func;
-    boot_opaque = opaque;
-}
-
-static void do_boot_set(Monitor *mon, const char *bootdevice)
-{
-    int res;
-
-    if (qemu_boot_set_handler)  {
-        res = qemu_boot_set_handler(boot_opaque, bootdevice);
-        if (res == 0)
-            monitor_printf(mon, "boot device list now set to %s\n",
-                           bootdevice);
-        else
-            monitor_printf(mon, "setting boot device list failed with "
-                           "error %i\n", res);
-    } else {
-        monitor_printf(mon, "no function defined to set boot device list for "
-                       "this architecture\n");
-    }
-}
-
-static void do_system_reset(Monitor *mon)
-{
-    qemu_system_reset_request();
-}
-
-static void do_system_powerdown(Monitor *mon)
-{
-    qemu_system_powerdown_request();
-}
-
-#if defined(TARGET_I386)
-static void print_pte(Monitor *mon, uint32_t addr, uint32_t pte, uint32_t mask)
-{
-    monitor_printf(mon, "%08x: %08x %c%c%c%c%c%c%c%c\n",
-                   addr,
-                   pte & mask,
-                   pte & PG_GLOBAL_MASK ? 'G' : '-',
-                   pte & PG_PSE_MASK ? 'P' : '-',
-                   pte & PG_DIRTY_MASK ? 'D' : '-',
-                   pte & PG_ACCESSED_MASK ? 'A' : '-',
-                   pte & PG_PCD_MASK ? 'C' : '-',
-                   pte & PG_PWT_MASK ? 'T' : '-',
-                   pte & PG_USER_MASK ? 'U' : '-',
-                   pte & PG_RW_MASK ? 'W' : '-');
-}
-
-static void tlb_info(Monitor *mon)
-{
-    CPUState *env;
-    int l1, l2;
-    uint32_t pgd, pde, pte;
-
-    env = mon_get_cpu();
-    if (!env)
-        return;
-
-    if (!(env->cr[0] & CR0_PG_MASK)) {
-        monitor_printf(mon, "PG disabled\n");
-        return;
-    }
-    pgd = env->cr[3] & ~0xfff;
-    for(l1 = 0; l1 < 1024; l1++) {
-        cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
-        pde = le32_to_cpu(pde);
-        if (pde & PG_PRESENT_MASK) {
-            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
-                print_pte(mon, (l1 << 22), pde, ~((1 << 20) - 1));
-            } else {
-                for(l2 = 0; l2 < 1024; l2++) {
-                    cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
-                                             (uint8_t *)&pte, 4);
-                    pte = le32_to_cpu(pte);
-                    if (pte & PG_PRESENT_MASK) {
-                        print_pte(mon, (l1 << 22) + (l2 << 12),
-                                  pte & ~PG_PSE_MASK,
-                                  ~0xfff);
-                    }
-                }
-            }
-        }
-    }
-}
-
-static void mem_print(Monitor *mon, uint32_t *pstart, int *plast_prot,
-                      uint32_t end, int prot)
-{
-    int prot1;
-    prot1 = *plast_prot;
-    if (prot != prot1) {
-        if (*pstart != -1) {
-            monitor_printf(mon, "%08x-%08x %08x %c%c%c\n",
-                           *pstart, end, end - *pstart,
-                           prot1 & PG_USER_MASK ? 'u' : '-',
-                           'r',
-                           prot1 & PG_RW_MASK ? 'w' : '-');
-        }
-        if (prot != 0)
-            *pstart = end;
-        else
-            *pstart = -1;
-        *plast_prot = prot;
-    }
-}
-
-static void mem_info(Monitor *mon)
-{
-    CPUState *env;
-    int l1, l2, prot, last_prot;
-    uint32_t pgd, pde, pte, start, end;
-
-    env = mon_get_cpu();
-    if (!env)
-        return;
-
-    if (!(env->cr[0] & CR0_PG_MASK)) {
-        monitor_printf(mon, "PG disabled\n");
-        return;
-    }
-    pgd = env->cr[3] & ~0xfff;
-    last_prot = 0;
-    start = -1;
-    for(l1 = 0; l1 < 1024; l1++) {
-        cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
-        pde = le32_to_cpu(pde);
-        end = l1 << 22;
-        if (pde & PG_PRESENT_MASK) {
-            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
-                prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
-                mem_print(mon, &start, &last_prot, end, prot);
-            } else {
-                for(l2 = 0; l2 < 1024; l2++) {
-                    cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
-                                             (uint8_t *)&pte, 4);
-                    pte = le32_to_cpu(pte);
-                    end = (l1 << 22) + (l2 << 12);
-                    if (pte & PG_PRESENT_MASK) {
-                        prot = pte & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
-                    } else {
-                        prot = 0;
-                    }
-                    mem_print(mon, &start, &last_prot, end, prot);
-                }
-            }
-        } else {
-            prot = 0;
-            mem_print(mon, &start, &last_prot, end, prot);
-        }
-    }
-}
-#endif
-
-#if defined(TARGET_SH4)
-
-static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
-{
-    monitor_printf(mon, " tlb%i:\t"
-                   "asid=%hhu vpn=%x\tppn=%x\tsz=%hhu size=%u\t"
-                   "v=%hhu shared=%hhu cached=%hhu prot=%hhu "
-                   "dirty=%hhu writethrough=%hhu\n",
-                   idx,
-                   tlb->asid, tlb->vpn, tlb->ppn, tlb->sz, tlb->size,
-                   tlb->v, tlb->sh, tlb->c, tlb->pr,
-                   tlb->d, tlb->wt);
-}
-
-static void tlb_info(Monitor *mon)
-{
-    CPUState *env = mon_get_cpu();
-    int i;
-
-    monitor_printf (mon, "ITLB:\n");
-    for (i = 0 ; i < ITLB_SIZE ; i++)
-        print_tlb (mon, i, &env->itlb[i]);
-    monitor_printf (mon, "UTLB:\n");
-    for (i = 0 ; i < UTLB_SIZE ; i++)
-        print_tlb (mon, i, &env->utlb[i]);
-}
-
-#endif
-
-static void do_info_kqemu(Monitor *mon)
-{
-#ifdef CONFIG_KQEMU
-    CPUState *env;
-    int val;
-    val = 0;
-    env = mon_get_cpu();
-    if (!env) {
-        monitor_printf(mon, "No cpu initialized yet");
-        return;
-    }
-    val = env->kqemu_enabled;
-    monitor_printf(mon, "kqemu support: ");
-    switch(val) {
-    default:
-    case 0:
-        monitor_printf(mon, "disabled\n");
-        break;
-    case 1:
-        monitor_printf(mon, "enabled for user code\n");
-        break;
-    case 2:
-        monitor_printf(mon, "enabled for user and kernel code\n");
-        break;
-    }
-#else
-    monitor_printf(mon, "kqemu support: not compiled\n");
-#endif
-}
-
-static void do_info_kvm(Monitor *mon)
-{
-#ifdef CONFIG_KVM
-    monitor_printf(mon, "kvm support: ");
-    if (kvm_enabled())
-        monitor_printf(mon, "enabled\n");
-    else
-        monitor_printf(mon, "disabled\n");
-#else
-    monitor_printf(mon, "kvm support: not compiled\n");
-#endif
-}
-
-static void do_info_numa(Monitor *mon)
-{
-    int i;
-    CPUState *env;
-
-    monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
-    for (i = 0; i < nb_numa_nodes; i++) {
-        monitor_printf(mon, "node %d cpus:", i);
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
-            if (env->numa_node == i) {
-                monitor_printf(mon, " %d", env->cpu_index);
-            }
-        }
-        monitor_printf(mon, "\n");
-        monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i,
-            node_mem[i] >> 20);
-    }
-}
-
-#ifdef CONFIG_PROFILER
-
-int64_t kqemu_time;
-int64_t qemu_time;
-int64_t kqemu_exec_count;
-int64_t dev_time;
-int64_t kqemu_ret_int_count;
-int64_t kqemu_ret_excp_count;
-int64_t kqemu_ret_intr_count;
-
-static void do_info_profile(Monitor *mon)
-{
-    int64_t total;
-    total = qemu_time;
-    if (total == 0)
-        total = 1;
-    monitor_printf(mon, "async time  %" PRId64 " (%0.3f)\n",
-                   dev_time, dev_time / (double)ticks_per_sec);
-    monitor_printf(mon, "qemu time   %" PRId64 " (%0.3f)\n",
-                   qemu_time, qemu_time / (double)ticks_per_sec);
-    monitor_printf(mon, "kqemu time  %" PRId64 " (%0.3f %0.1f%%) count=%"
-                        PRId64 " int=%" PRId64 " excp=%" PRId64 " intr=%"
-                        PRId64 "\n",
-                   kqemu_time, kqemu_time / (double)ticks_per_sec,
-                   kqemu_time / (double)total * 100.0,
-                   kqemu_exec_count,
-                   kqemu_ret_int_count,
-                   kqemu_ret_excp_count,
-                   kqemu_ret_intr_count);
-    qemu_time = 0;
-    kqemu_time = 0;
-    kqemu_exec_count = 0;
-    dev_time = 0;
-    kqemu_ret_int_count = 0;
-    kqemu_ret_excp_count = 0;
-    kqemu_ret_intr_count = 0;
-#ifdef CONFIG_KQEMU
-    kqemu_record_dump();
-#endif
-}
-#else
-static void do_info_profile(Monitor *mon)
-{
-    monitor_printf(mon, "Internal profiler not compiled\n");
-}
-#endif
-
-/* Capture support */
-static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
-
-static void do_info_capture(Monitor *mon)
-{
-    int i;
-    CaptureState *s;
-
-    for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
-        monitor_printf(mon, "[%d]: ", i);
-        s->ops.info (s->opaque);
-    }
-}
-
-#ifdef HAS_AUDIO
-static void do_stop_capture(Monitor *mon, int n)
-{
-    int i;
-    CaptureState *s;
-
-    for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
-        if (i == n) {
-            s->ops.destroy (s->opaque);
-            QLIST_REMOVE (s, entries);
-            g_free (s);
-            return;
-        }
-    }
-}
-
-static void do_wav_capture(Monitor *mon, const char *path,
-                           int has_freq, int freq,
-                           int has_bits, int bits,
-                           int has_channels, int nchannels)
-{
-    CaptureState *s;
-
-    s = g_malloc0 (sizeof (*s));
-
-    freq = has_freq ? freq : 44100;
-    bits = has_bits ? bits : 16;
-    nchannels = has_channels ? nchannels : 2;
-
-    if (wav_start_capture (s, path, freq, bits, nchannels)) {
-        monitor_printf(mon, "Faied to add wave capture\n");
-        g_free (s);
-    }
-    QLIST_INSERT_HEAD (&capture_head, s, entries);
-}
-#endif
-
-#if defined(TARGET_I386)
-static void do_inject_nmi(Monitor *mon, int cpu_index)
-{
-    CPUState *env;
-
-    for (env = first_cpu; env != NULL; env = env->next_cpu)
-        if (env->cpu_index == cpu_index) {
-            cpu_interrupt(env, CPU_INTERRUPT_NMI);
-            break;
-        }
-}
-#endif
-
-static void do_info_status(Monitor *mon)
-{
-    if (vm_running) {
-        if (singlestep) {
-            monitor_printf(mon, "VM status: running (single step mode)\n");
-        } else {
-            monitor_printf(mon, "VM status: running\n");
-        }
-    } else
-       monitor_printf(mon, "VM status: paused\n");
-}
-
-
-static void do_balloon(Monitor *mon, int value)
-{
-    ram_addr_t target = value;
-    qemu_balloon(target << 20);
-}
-
-static void do_info_balloon(Monitor *mon)
-{
-    ram_addr_t actual;
-
-    actual = qemu_balloon_status();
-    if (kvm_enabled() && !kvm_has_sync_mmu())
-        monitor_printf(mon, "Using KVM without synchronous MMU, "
-                       "ballooning disabled\n");
-    else if (actual == 0)
-        monitor_printf(mon, "Ballooning not activated in VM\n");
-    else
-        monitor_printf(mon, "balloon: actual=%d\n", (int)(actual >> 20));
-}
-
-static void do_acl(Monitor *mon,
-                   const char *command,
-                   const char *aclname,
-                   const char *match,
-                   int has_index,
-                   int index)
-{
-    qemu_acl *acl;
-
-    acl = qemu_acl_find(aclname);
-    if (!acl) {
-        monitor_printf(mon, "acl: unknown list '%s'\n", aclname);
-        return;
-    }
-
-    if (strcmp(command, "show") == 0) {
-        int i = 0;
-        qemu_acl_entry *entry;
-        monitor_printf(mon, "policy: %s\n",
-                       acl->defaultDeny ? "deny" : "allow");
-        QTAILQ_FOREACH(entry, &acl->entries, next) {
-            i++;
-            monitor_printf(mon, "%d: %s %s\n", i,
-                           entry->deny ? "deny" : "allow",
-                           entry->match);
-        }
-    } else if (strcmp(command, "reset") == 0) {
-        qemu_acl_reset(acl);
-        monitor_printf(mon, "acl: removed all rules\n");
-    } else if (strcmp(command, "policy") == 0) {
-        if (!match) {
-            monitor_printf(mon, "acl: missing policy parameter\n");
-            return;
-        }
-
-        if (strcmp(match, "allow") == 0) {
-            acl->defaultDeny = 0;
-            monitor_printf(mon, "acl: policy set to 'allow'\n");
-        } else if (strcmp(match, "deny") == 0) {
-            acl->defaultDeny = 1;
-            monitor_printf(mon, "acl: policy set to 'deny'\n");
-        } else {
-            monitor_printf(mon, "acl: unknown policy '%s', expected 'deny' or 'allow'\n", match);
-        }
-    } else if ((strcmp(command, "allow") == 0) ||
-               (strcmp(command, "deny") == 0)) {
-        int deny = strcmp(command, "deny") == 0 ? 1 : 0;
-        int ret;
-
-        if (!match) {
-            monitor_printf(mon, "acl: missing match parameter\n");
-            return;
-        }
-
-        if (has_index)
-            ret = qemu_acl_insert(acl, deny, match, index);
-        else
-            ret = qemu_acl_append(acl, deny, match);
-        if (ret < 0)
-            monitor_printf(mon, "acl: unable to add acl entry\n");
-        else
-            monitor_printf(mon, "acl: added rule at position %d\n", ret);
-    } else if (strcmp(command, "remove") == 0) {
-        int ret;
-
-        if (!match) {
-            monitor_printf(mon, "acl: missing match parameter\n");
-            return;
-        }
-
-        ret = qemu_acl_remove(acl, match);
-        if (ret < 0)
-            monitor_printf(mon, "acl: no matching acl entry\n");
-        else
-            monitor_printf(mon, "acl: removed rule at position %d\n", ret);
-    } else {
-        monitor_printf(mon, "acl: unknown command '%s'\n", command);
-    }
-}
-
-static const mon_cmd_t mon_cmds[] = {
-#include "qemu-monitor.h"
-    MON_CMD_T_INITIALIZER
-};
-
-/* Please update qemu-monitor.hx when adding or changing commands */
-static const mon_cmd_t info_cmds[] = {
-    { "version", "", do_info_version,
-      "", "show the version of QEMU" },
-    { "network", "", do_info_network,
-      "", "show the network state" },
-    { "chardev", "", qemu_chr_info,
-      "", "show the character devices" },
-    { "block", "", bdrv_info,
-      "", "show the block devices" },
-    { "blockstats", "", bdrv_info_stats,
-      "", "show block device statistics" },
-    { "registers", "", do_info_registers,
-      "", "show the cpu registers" },
-    { "cpus", "", do_info_cpus,
-      "", "show infos for each CPU" },
-    { "history", "", do_info_history,
-      "", "show the command line history", },
-    { "irq", "", irq_info,
-      "", "show the interrupts statistics (if available)", },
-    { "pic", "", pic_info,
-      "", "show i8259 (PIC) state", },
-    { "pci", "", pci_info,
-      "", "show PCI info", },
-#if defined(TARGET_I386) || defined(TARGET_SH4)
-    { "tlb", "", tlb_info,
-      "", "show virtual to physical memory mappings", },
-#endif
-#if defined(TARGET_I386)
-    { "mem", "", mem_info,
-      "", "show the active virtual memory mappings", },
-    { "hpet", "", do_info_hpet,
-      "", "show state of HPET", },
-#endif
-    { "jit", "", do_info_jit,
-      "", "show dynamic compiler info", },
-    { "kqemu", "", do_info_kqemu,
-      "", "show KQEMU information", },
-    { "kvm", "", do_info_kvm,
-      "", "show KVM information", },
-    { "numa", "", do_info_numa,
-      "", "show NUMA information", },
-    { "usb", "", usb_info,
-      "", "show guest USB devices", },
-    { "usbhost", "", usb_host_info,
-      "", "show host USB devices", },
-    { "profile", "", do_info_profile,
-      "", "show profiling information", },
-    { "capture", "", do_info_capture,
-      "", "show capture information" },
-    { "snapshots", "", do_info_snapshots,
-      "", "show the currently saved VM snapshots" },
-    { "status", "", do_info_status,
-      "", "show the current VM status (running|paused)" },
-    { "pcmcia", "", pcmcia_info,
-      "", "show guest PCMCIA status" },
-    { "mice", "", do_info_mice,
-      "", "show which guest mouse is receiving events" },
-    { "vnc", "", do_info_vnc,
-      "", "show the vnc server status"},
-    { "name", "", do_info_name,
-      "", "show the current VM name" },
-    { "uuid", "", do_info_uuid,
-      "", "show the current VM UUID" },
-#if defined(TARGET_PPC)
-    { "cpustats", "", do_info_cpu_stats,
-      "", "show CPU statistics", },
-#endif
-#if defined(CONFIG_SLIRP)
-    { "slirp", "", do_info_slirp,
-      "", "show SLIRP statistics", },
-#endif
-    { "migrate", "", do_info_migrate, "", "show migration status" },
-    { "balloon", "", do_info_balloon,
-      "", "show balloon information" },
-    { "qtree", "", do_info_qtree,
-      "", "show device tree" },
-    MON_CMD_T_INITIALIZER
-};
-
-/*******************************************************************/
-
-static const char *pch;
-static jmp_buf expr_env;
-
-#define MD_TLONG 0
-#define MD_I32   1
-
-typedef struct MonitorDef {
-    const char *name;
-    int offset;
-    target_long (*get_value)(const struct MonitorDef *md, int val);
-    int type;
-} MonitorDef;
-
-#define MONITOR_DEF_INITIALIZER  { NULL, 0, NULL, 0 }
-
-#if defined(TARGET_I386)
-static target_long monitor_get_pc (const struct MonitorDef *md, int val)
-{
-    CPUState *env = mon_get_cpu();
-    if (!env)
-        return 0;
-    return env->eip + env->segs[R_CS].base;
-}
-#endif
-
-#if defined(TARGET_PPC)
-static target_long monitor_get_ccr (const struct MonitorDef *md, int val)
-{
-    CPUState *env = mon_get_cpu();
-    unsigned int u;
-    int i;
-
-    if (!env)
-        return 0;
-
-    u = 0;
-    for (i = 0; i < 8; i++)
-        u |= env->crf[i] << (32 - (4 * i));
-
-    return u;
-}
-
-static target_long monitor_get_msr (const struct MonitorDef *md, int val)
-{
-    CPUState *env = mon_get_cpu();
-    if (!env)
-        return 0;
-    return env->msr;
-}
-
-static target_long monitor_get_xer (const struct MonitorDef *md, int val)
-{
-    CPUState *env = mon_get_cpu();
-    if (!env)
-        return 0;
-    return env->xer;
-}
-
-static target_long monitor_get_decr (const struct MonitorDef *md, int val)
-{
-    CPUState *env = mon_get_cpu();
-    if (!env)
-        return 0;
-    return cpu_ppc_load_decr(env);
-}
-
-static target_long monitor_get_tbu (const struct MonitorDef *md, int val)
-{
-    CPUState *env = mon_get_cpu();
-    if (!env)
-        return 0;
-    return cpu_ppc_load_tbu(env);
-}
-
-static target_long monitor_get_tbl (const struct MonitorDef *md, int val)
-{
-    CPUState *env = mon_get_cpu();
-    if (!env)
-        return 0;
-    return cpu_ppc_load_tbl(env);
-}
-#endif
-
-#if defined(TARGET_SPARC)
-#ifndef TARGET_SPARC64
-static target_long monitor_get_psr (const struct MonitorDef *md, int val)
-{
-    CPUState *env = mon_get_cpu();
-    if (!env)
-        return 0;
-    return GET_PSR(env);
-}
-#endif
-
-static target_long monitor_get_reg(const struct MonitorDef *md, int val)
-{
-    CPUState *env = mon_get_cpu();
-    if (!env)
-        return 0;
-    return env->regwptr[val];
-}
-#endif
-
-static const MonitorDef monitor_defs[] = {
-#ifdef TARGET_I386
-
-#define SEG(name, seg) \
-    { name, offsetof(CPUState, segs[seg].selector), NULL, MD_I32 },\
-    { name ".base", offsetof(CPUState, segs[seg].base) },\
-    { name ".limit", offsetof(CPUState, segs[seg].limit), NULL, MD_I32 },
-
-    { "eax", offsetof(CPUState, regs[0]) },
-    { "ecx", offsetof(CPUState, regs[1]) },
-    { "edx", offsetof(CPUState, regs[2]) },
-    { "ebx", offsetof(CPUState, regs[3]) },
-    { "esp|sp", offsetof(CPUState, regs[4]) },
-    { "ebp|fp", offsetof(CPUState, regs[5]) },
-    { "esi", offsetof(CPUState, regs[6]) },
-    { "edi", offsetof(CPUState, regs[7]) },
-#ifdef TARGET_X86_64
-    { "r8", offsetof(CPUState, regs[8]) },
-    { "r9", offsetof(CPUState, regs[9]) },
-    { "r10", offsetof(CPUState, regs[10]) },
-    { "r11", offsetof(CPUState, regs[11]) },
-    { "r12", offsetof(CPUState, regs[12]) },
-    { "r13", offsetof(CPUState, regs[13]) },
-    { "r14", offsetof(CPUState, regs[14]) },
-    { "r15", offsetof(CPUState, regs[15]) },
-#endif
-    { "eflags", offsetof(CPUState, eflags) },
-    { "eip", offsetof(CPUState, eip) },
-    SEG("cs", R_CS)
-    SEG("ds", R_DS)
-    SEG("es", R_ES)
-    SEG("ss", R_SS)
-    SEG("fs", R_FS)
-    SEG("gs", R_GS)
-    { "pc", 0, monitor_get_pc, },
-#elif defined(TARGET_PPC)
-    /* General purpose registers */
-    { "r0", offsetof(CPUState, gpr[0]) },
-    { "r1", offsetof(CPUState, gpr[1]) },
-    { "r2", offsetof(CPUState, gpr[2]) },
-    { "r3", offsetof(CPUState, gpr[3]) },
-    { "r4", offsetof(CPUState, gpr[4]) },
-    { "r5", offsetof(CPUState, gpr[5]) },
-    { "r6", offsetof(CPUState, gpr[6]) },
-    { "r7", offsetof(CPUState, gpr[7]) },
-    { "r8", offsetof(CPUState, gpr[8]) },
-    { "r9", offsetof(CPUState, gpr[9]) },
-    { "r10", offsetof(CPUState, gpr[10]) },
-    { "r11", offsetof(CPUState, gpr[11]) },
-    { "r12", offsetof(CPUState, gpr[12]) },
-    { "r13", offsetof(CPUState, gpr[13]) },
-    { "r14", offsetof(CPUState, gpr[14]) },
-    { "r15", offsetof(CPUState, gpr[15]) },
-    { "r16", offsetof(CPUState, gpr[16]) },
-    { "r17", offsetof(CPUState, gpr[17]) },
-    { "r18", offsetof(CPUState, gpr[18]) },
-    { "r19", offsetof(CPUState, gpr[19]) },
-    { "r20", offsetof(CPUState, gpr[20]) },
-    { "r21", offsetof(CPUState, gpr[21]) },
-    { "r22", offsetof(CPUState, gpr[22]) },
-    { "r23", offsetof(CPUState, gpr[23]) },
-    { "r24", offsetof(CPUState, gpr[24]) },
-    { "r25", offsetof(CPUState, gpr[25]) },
-    { "r26", offsetof(CPUState, gpr[26]) },
-    { "r27", offsetof(CPUState, gpr[27]) },
-    { "r28", offsetof(CPUState, gpr[28]) },
-    { "r29", offsetof(CPUState, gpr[29]) },
-    { "r30", offsetof(CPUState, gpr[30]) },
-    { "r31", offsetof(CPUState, gpr[31]) },
-    /* Floating point registers */
-    { "f0", offsetof(CPUState, fpr[0]) },
-    { "f1", offsetof(CPUState, fpr[1]) },
-    { "f2", offsetof(CPUState, fpr[2]) },
-    { "f3", offsetof(CPUState, fpr[3]) },
-    { "f4", offsetof(CPUState, fpr[4]) },
-    { "f5", offsetof(CPUState, fpr[5]) },
-    { "f6", offsetof(CPUState, fpr[6]) },
-    { "f7", offsetof(CPUState, fpr[7]) },
-    { "f8", offsetof(CPUState, fpr[8]) },
-    { "f9", offsetof(CPUState, fpr[9]) },
-    { "f10", offsetof(CPUState, fpr[10]) },
-    { "f11", offsetof(CPUState, fpr[11]) },
-    { "f12", offsetof(CPUState, fpr[12]) },
-    { "f13", offsetof(CPUState, fpr[13]) },
-    { "f14", offsetof(CPUState, fpr[14]) },
-    { "f15", offsetof(CPUState, fpr[15]) },
-    { "f16", offsetof(CPUState, fpr[16]) },
-    { "f17", offsetof(CPUState, fpr[17]) },
-    { "f18", offsetof(CPUState, fpr[18]) },
-    { "f19", offsetof(CPUState, fpr[19]) },
-    { "f20", offsetof(CPUState, fpr[20]) },
-    { "f21", offsetof(CPUState, fpr[21]) },
-    { "f22", offsetof(CPUState, fpr[22]) },
-    { "f23", offsetof(CPUState, fpr[23]) },
-    { "f24", offsetof(CPUState, fpr[24]) },
-    { "f25", offsetof(CPUState, fpr[25]) },
-    { "f26", offsetof(CPUState, fpr[26]) },
-    { "f27", offsetof(CPUState, fpr[27]) },
-    { "f28", offsetof(CPUState, fpr[28]) },
-    { "f29", offsetof(CPUState, fpr[29]) },
-    { "f30", offsetof(CPUState, fpr[30]) },
-    { "f31", offsetof(CPUState, fpr[31]) },
-    { "fpscr", offsetof(CPUState, fpscr) },
-    /* Next instruction pointer */
-    { "nip|pc", offsetof(CPUState, nip) },
-    { "lr", offsetof(CPUState, lr) },
-    { "ctr", offsetof(CPUState, ctr) },
-    { "decr", 0, &monitor_get_decr, },
-    { "ccr", 0, &monitor_get_ccr, },
-    /* Machine state register */
-    { "msr", 0, &monitor_get_msr, },
-    { "xer", 0, &monitor_get_xer, },
-    { "tbu", 0, &monitor_get_tbu, },
-    { "tbl", 0, &monitor_get_tbl, },
-#if defined(TARGET_PPC64)
-    /* Address space register */
-    { "asr", offsetof(CPUState, asr) },
-#endif
-    /* Segment registers */
-    { "sdr1", offsetof(CPUState, sdr1) },
-    { "sr0", offsetof(CPUState, sr[0]) },
-    { "sr1", offsetof(CPUState, sr[1]) },
-    { "sr2", offsetof(CPUState, sr[2]) },
-    { "sr3", offsetof(CPUState, sr[3]) },
-    { "sr4", offsetof(CPUState, sr[4]) },
-    { "sr5", offsetof(CPUState, sr[5]) },
-    { "sr6", offsetof(CPUState, sr[6]) },
-    { "sr7", offsetof(CPUState, sr[7]) },
-    { "sr8", offsetof(CPUState, sr[8]) },
-    { "sr9", offsetof(CPUState, sr[9]) },
-    { "sr10", offsetof(CPUState, sr[10]) },
-    { "sr11", offsetof(CPUState, sr[11]) },
-    { "sr12", offsetof(CPUState, sr[12]) },
-    { "sr13", offsetof(CPUState, sr[13]) },
-    { "sr14", offsetof(CPUState, sr[14]) },
-    { "sr15", offsetof(CPUState, sr[15]) },
-    /* Too lazy to put BATs and SPRs ... */
-#elif defined(TARGET_SPARC)
-    { "g0", offsetof(CPUState, gregs[0]) },
-    { "g1", offsetof(CPUState, gregs[1]) },
-    { "g2", offsetof(CPUState, gregs[2]) },
-    { "g3", offsetof(CPUState, gregs[3]) },
-    { "g4", offsetof(CPUState, gregs[4]) },
-    { "g5", offsetof(CPUState, gregs[5]) },
-    { "g6", offsetof(CPUState, gregs[6]) },
-    { "g7", offsetof(CPUState, gregs[7]) },
-    { "o0", 0, monitor_get_reg },
-    { "o1", 1, monitor_get_reg },
-    { "o2", 2, monitor_get_reg },
-    { "o3", 3, monitor_get_reg },
-    { "o4", 4, monitor_get_reg },
-    { "o5", 5, monitor_get_reg },
-    { "o6", 6, monitor_get_reg },
-    { "o7", 7, monitor_get_reg },
-    { "l0", 8, monitor_get_reg },
-    { "l1", 9, monitor_get_reg },
-    { "l2", 10, monitor_get_reg },
-    { "l3", 11, monitor_get_reg },
-    { "l4", 12, monitor_get_reg },
-    { "l5", 13, monitor_get_reg },
-    { "l6", 14, monitor_get_reg },
-    { "l7", 15, monitor_get_reg },
-    { "i0", 16, monitor_get_reg },
-    { "i1", 17, monitor_get_reg },
-    { "i2", 18, monitor_get_reg },
-    { "i3", 19, monitor_get_reg },
-    { "i4", 20, monitor_get_reg },
-    { "i5", 21, monitor_get_reg },
-    { "i6", 22, monitor_get_reg },
-    { "i7", 23, monitor_get_reg },
-    { "pc", offsetof(CPUState, pc) },
-    { "npc", offsetof(CPUState, npc) },
-    { "y", offsetof(CPUState, y) },
-#ifndef TARGET_SPARC64
-    { "psr", 0, &monitor_get_psr, },
-    { "wim", offsetof(CPUState, wim) },
-#endif
-    { "tbr", offsetof(CPUState, tbr) },
-    { "fsr", offsetof(CPUState, fsr) },
-    { "f0", offsetof(CPUState, fpr[0]) },
-    { "f1", offsetof(CPUState, fpr[1]) },
-    { "f2", offsetof(CPUState, fpr[2]) },
-    { "f3", offsetof(CPUState, fpr[3]) },
-    { "f4", offsetof(CPUState, fpr[4]) },
-    { "f5", offsetof(CPUState, fpr[5]) },
-    { "f6", offsetof(CPUState, fpr[6]) },
-    { "f7", offsetof(CPUState, fpr[7]) },
-    { "f8", offsetof(CPUState, fpr[8]) },
-    { "f9", offsetof(CPUState, fpr[9]) },
-    { "f10", offsetof(CPUState, fpr[10]) },
-    { "f11", offsetof(CPUState, fpr[11]) },
-    { "f12", offsetof(CPUState, fpr[12]) },
-    { "f13", offsetof(CPUState, fpr[13]) },
-    { "f14", offsetof(CPUState, fpr[14]) },
-    { "f15", offsetof(CPUState, fpr[15]) },
-    { "f16", offsetof(CPUState, fpr[16]) },
-    { "f17", offsetof(CPUState, fpr[17]) },
-    { "f18", offsetof(CPUState, fpr[18]) },
-    { "f19", offsetof(CPUState, fpr[19]) },
-    { "f20", offsetof(CPUState, fpr[20]) },
-    { "f21", offsetof(CPUState, fpr[21]) },
-    { "f22", offsetof(CPUState, fpr[22]) },
-    { "f23", offsetof(CPUState, fpr[23]) },
-    { "f24", offsetof(CPUState, fpr[24]) },
-    { "f25", offsetof(CPUState, fpr[25]) },
-    { "f26", offsetof(CPUState, fpr[26]) },
-    { "f27", offsetof(CPUState, fpr[27]) },
-    { "f28", offsetof(CPUState, fpr[28]) },
-    { "f29", offsetof(CPUState, fpr[29]) },
-    { "f30", offsetof(CPUState, fpr[30]) },
-    { "f31", offsetof(CPUState, fpr[31]) },
-#ifdef TARGET_SPARC64
-    { "f32", offsetof(CPUState, fpr[32]) },
-    { "f34", offsetof(CPUState, fpr[34]) },
-    { "f36", offsetof(CPUState, fpr[36]) },
-    { "f38", offsetof(CPUState, fpr[38]) },
-    { "f40", offsetof(CPUState, fpr[40]) },
-    { "f42", offsetof(CPUState, fpr[42]) },
-    { "f44", offsetof(CPUState, fpr[44]) },
-    { "f46", offsetof(CPUState, fpr[46]) },
-    { "f48", offsetof(CPUState, fpr[48]) },
-    { "f50", offsetof(CPUState, fpr[50]) },
-    { "f52", offsetof(CPUState, fpr[52]) },
-    { "f54", offsetof(CPUState, fpr[54]) },
-    { "f56", offsetof(CPUState, fpr[56]) },
-    { "f58", offsetof(CPUState, fpr[58]) },
-    { "f60", offsetof(CPUState, fpr[60]) },
-    { "f62", offsetof(CPUState, fpr[62]) },
-    { "asi", offsetof(CPUState, asi) },
-    { "pstate", offsetof(CPUState, pstate) },
-    { "cansave", offsetof(CPUState, cansave) },
-    { "canrestore", offsetof(CPUState, canrestore) },
-    { "otherwin", offsetof(CPUState, otherwin) },
-    { "wstate", offsetof(CPUState, wstate) },
-    { "cleanwin", offsetof(CPUState, cleanwin) },
-    { "fprs", offsetof(CPUState, fprs) },
-#endif
-#endif
-    MONITOR_DEF_INITIALIZER
-};
-
-static void expr_error(Monitor *mon, const char *msg)
-{
-    monitor_printf(mon, "%s\n", msg);
-    longjmp(expr_env, 1);
-}
-
-/* return 0 if OK, -1 if not found, -2 if no CPU defined */
-static int get_monitor_def(target_long *pval, const char *name)
-{
-    const MonitorDef *md;
-    void *ptr;
-
-    for(md = monitor_defs; md->name != NULL; md++) {
-        if (compare_cmd(name, md->name)) {
-            if (md->get_value) {
-                *pval = md->get_value(md, md->offset);
-            } else {
-                CPUState *env = mon_get_cpu();
-                if (!env)
-                    return -2;
-                ptr = (uint8_t *)env + md->offset;
-                switch(md->type) {
-                case MD_I32:
-                    *pval = *(int32_t *)ptr;
-                    break;
-                case MD_TLONG:
-                    *pval = *(target_long *)ptr;
-                    break;
-                default:
-                    *pval = 0;
-                    break;
-                }
-            }
-            return 0;
-        }
-    }
-    return -1;
-}
-
-static void next(void)
-{
-    if (pch != '\0') {
-        pch++;
-        while (qemu_isspace(*pch))
-            pch++;
-    }
-}
-
-static int64_t expr_sum(Monitor *mon);
-
-static int64_t expr_unary(Monitor *mon)
-{
-    int64_t n;
-    char *p;
-    int ret;
-
-    switch(*pch) {
-    case '+':
-        next();
-        n = expr_unary(mon);
-        break;
-    case '-':
-        next();
-        n = -expr_unary(mon);
-        break;
-    case '~':
-        next();
-        n = ~expr_unary(mon);
-        break;
-    case '(':
-        next();
-        n = expr_sum(mon);
-        if (*pch != ')') {
-            expr_error(mon, "')' expected");
-        }
-        next();
-        break;
-    case '\'':
-        pch++;
-        if (*pch == '\0')
-            expr_error(mon, "character constant expected");
-        n = *pch;
-        pch++;
-        if (*pch != '\'')
-            expr_error(mon, "missing terminating \' character");
-        next();
-        break;
-    case '$':
-        {
-            char buf[128], *q;
-            target_long reg=0;
-
-            pch++;
-            q = buf;
-            while ((*pch >= 'a' && *pch <= 'z') ||
-                   (*pch >= 'A' && *pch <= 'Z') ||
-                   (*pch >= '0' && *pch <= '9') ||
-                   *pch == '_' || *pch == '.') {
-                if ((q - buf) < sizeof(buf) - 1)
-                    *q++ = *pch;
-                pch++;
-            }
-            while (qemu_isspace(*pch))
-                pch++;
-            *q = 0;
-            ret = get_monitor_def(&reg, buf);
-            if (ret == -1)
-                expr_error(mon, "unknown register");
-            else if (ret == -2)
-                expr_error(mon, "no cpu defined");
-            n = reg;
-        }
-        break;
-    case '\0':
-        expr_error(mon, "unexpected end of expression");
-        n = 0;
-        break;
-    default:
-#if TARGET_PHYS_ADDR_BITS > 32
-        n = strtoull(pch, &p, 0);
-#else
-        n = strtoul(pch, &p, 0);
-#endif
-        if (pch == p) {
-            expr_error(mon, "invalid char in expression");
-        }
-        pch = p;
-        while (qemu_isspace(*pch))
-            pch++;
-        break;
-    }
-    return n;
-}
-
-
-static int64_t expr_prod(Monitor *mon)
-{
-    int64_t val, val2;
-    int op;
-
-    val = expr_unary(mon);
-    for(;;) {
-        op = *pch;
-        if (op != '*' && op != '/' && op != '%')
-            break;
-        next();
-        val2 = expr_unary(mon);
-        switch(op) {
-        default:
-        case '*':
-            val *= val2;
-            break;
-        case '/':
-        case '%':
-            if (val2 == 0)
-                expr_error(mon, "division by zero");
-            if (op == '/')
-                val /= val2;
-            else
-                val %= val2;
-            break;
-        }
-    }
-    return val;
-}
-
-static int64_t expr_logic(Monitor *mon)
-{
-    int64_t val, val2;
-    int op;
-
-    val = expr_prod(mon);
-    for(;;) {
-        op = *pch;
-        if (op != '&' && op != '|' && op != '^')
-            break;
-        next();
-        val2 = expr_prod(mon);
-        switch(op) {
-        default:
-        case '&':
-            val &= val2;
-            break;
-        case '|':
-            val |= val2;
-            break;
-        case '^':
-            val ^= val2;
-            break;
-        }
-    }
-    return val;
-}
-
-static int64_t expr_sum(Monitor *mon)
-{
-    int64_t val, val2;
-    int op;
-
-    val = expr_logic(mon);
-    for(;;) {
-        op = *pch;
-        if (op != '+' && op != '-')
-            break;
-        next();
-        val2 = expr_logic(mon);
-        if (op == '+')
-            val += val2;
-        else
-            val -= val2;
-    }
-    return val;
-}
-
-static int get_expr(Monitor *mon, int64_t *pval, const char **pp)
-{
-    pch = *pp;
-    if (setjmp(expr_env)) {
-        *pp = pch;
-        return -1;
-    }
-    while (qemu_isspace(*pch))
-        pch++;
-    *pval = expr_sum(mon);
-    *pp = pch;
-    return 0;
-}
-
-static int get_str(char *buf, int buf_size, const char **pp)
-{
-    const char *p;
-    char *q;
-    int c;
-
-    q = buf;
-    p = *pp;
-    while (qemu_isspace(*p))
-        p++;
-    if (*p == '\0') {
-    fail:
-        *q = '\0';
-        *pp = p;
-        return -1;
-    }
-    if (*p == '\"') {
-        p++;
-        while (*p != '\0' && *p != '\"') {
-            if (*p == '\\') {
-                p++;
-                c = *p++;
-                switch(c) {
-                case 'n':
-                    c = '\n';
-                    break;
-                case 'r':
-                    c = '\r';
-                    break;
-                case '\\':
-                case '\'':
-                case '\"':
-                    break;
-                default:
-                    qemu_printf("unsupported escape code: '\\%c'\n", c);
-                    goto fail;
-                }
-                if ((q - buf) < buf_size - 1) {
-                    *q++ = c;
-                }
-            } else {
-                if ((q - buf) < buf_size - 1) {
-                    *q++ = *p;
-                }
-                p++;
-            }
-        }
-        if (*p != '\"') {
-            qemu_printf("unterminated string\n");
-            goto fail;
-        }
-        p++;
-    } else {
-        while (*p != '\0' && !qemu_isspace(*p)) {
-            if ((q - buf) < buf_size - 1) {
-                *q++ = *p;
-            }
-            p++;
-        }
-    }
-    *q = '\0';
-    *pp = p;
-    return 0;
-}
-
-/*
- * Store the command-name in cmdname, and return a pointer to
- * the remaining of the command string.
- */
-static const char *get_command_name(const char *cmdline,
-                                    char *cmdname, size_t nlen)
-{
-    size_t len;
-    const char *p, *pstart;
-
-    p = cmdline;
-    while (qemu_isspace(*p))
-        p++;
-    if (*p == '\0')
-        return NULL;
-    pstart = p;
-    while (*p != '\0' && *p != '/' && !qemu_isspace(*p))
-        p++;
-    len = p - pstart;
-    if (len > nlen - 1)
-        len = nlen - 1;
-    memcpy(cmdname, pstart, len);
-    cmdname[len] = '\0';
-    return p;
-}
-
-static int default_fmt_format = 'x';
-static int default_fmt_size = 4;
-
-#define MAX_ARGS 16
-
-static void monitor_handle_command(Monitor *mon, const char *cmdline)
-{
-    const char *p, *typestr;
-    int c, nb_args, i, has_arg;
-    const mon_cmd_t *cmd;
-    char cmdname[256];
-    char buf[1024];
-    void *str_allocated[MAX_ARGS];
-    void *args[MAX_ARGS];
-    void (*handler_0)(Monitor *mon);
-    void (*handler_1)(Monitor *mon, void *arg0);
-    void (*handler_2)(Monitor *mon, void *arg0, void *arg1);
-    void (*handler_3)(Monitor *mon, void *arg0, void *arg1, void *arg2);
-    void (*handler_4)(Monitor *mon, void *arg0, void *arg1, void *arg2,
-                      void *arg3);
-    void (*handler_5)(Monitor *mon, void *arg0, void *arg1, void *arg2,
-                      void *arg3, void *arg4);
-    void (*handler_6)(Monitor *mon, void *arg0, void *arg1, void *arg2,
-                      void *arg3, void *arg4, void *arg5);
-    void (*handler_7)(Monitor *mon, void *arg0, void *arg1, void *arg2,
-                      void *arg3, void *arg4, void *arg5, void *arg6);
-    void (*handler_8)(Monitor *mon, void *arg0, void *arg1, void *arg2,
-                      void *arg3, void *arg4, void *arg5, void *arg6,
-                      void *arg7);
-    void (*handler_9)(Monitor *mon, void *arg0, void *arg1, void *arg2,
-                      void *arg3, void *arg4, void *arg5, void *arg6,
-                      void *arg7, void *arg8);
-    void (*handler_10)(Monitor *mon, void *arg0, void *arg1, void *arg2,
-                       void *arg3, void *arg4, void *arg5, void *arg6,
-                       void *arg7, void *arg8, void *arg9);
-#ifdef DEBUG
-    monitor_printf(mon, "command='%s'\n", cmdline);
-#endif
-
-    /* extract the command name */
-    p = get_command_name(cmdline, cmdname, sizeof(cmdname));
-    if (!p)
-        return;
-
-    /* find the command */
-    for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
-        if (compare_cmd(cmdname, cmd->name))
-            break;
-    }
-
-    if (cmd->name == NULL) {
-        monitor_printf(mon, "unknown command: '%s'\n", cmdname);
-        return;
-    }
-
-    for(i = 0; i < MAX_ARGS; i++)
-        str_allocated[i] = NULL;
-
-    /* parse the parameters */
-    typestr = cmd->args_type;
-    nb_args = 0;
-    for(;;) {
-        c = *typestr;
-        if (c == '\0')
-            break;
-        typestr++;
-        switch(c) {
-        case 'F':
-        case 'B':
-        case 's':
-            {
-                int ret;
-                char *str;
-
-                while (qemu_isspace(*p))
-                    p++;
-                if (*typestr == '?') {
-                    typestr++;
-                    if (*p == '\0') {
-                        /* no optional string: NULL argument */
-                        str = NULL;
-                        goto add_str;
-                    }
-                }
-                ret = get_str(buf, sizeof(buf), &p);
-                if (ret < 0) {
-                    switch(c) {
-                    case 'F':
-                        monitor_printf(mon, "%s: filename expected\n",
-                                       cmdname);
-                        break;
-                    case 'B':
-                        monitor_printf(mon, "%s: block device name expected\n",
-                                       cmdname);
-                        break;
-                    default:
-                        monitor_printf(mon, "%s: string expected\n", cmdname);
-                        break;
-                    }
-                    goto fail;
-                }
-                str = g_malloc(strlen(buf) + 1);
-                pstrcpy(str, sizeof(buf), buf);
-                str_allocated[nb_args] = str;
-            add_str:
-                if (nb_args >= MAX_ARGS) {
-                error_args:
-                    monitor_printf(mon, "%s: too many arguments\n", cmdname);
-                    goto fail;
-                }
-                args[nb_args++] = str;
-            }
-            break;
-        case '/':
-            {
-                int count, format, size;
-
-                while (qemu_isspace(*p))
-                    p++;
-                if (*p == '/') {
-                    /* format found */
-                    p++;
-                    count = 1;
-                    if (qemu_isdigit(*p)) {
-                        count = 0;
-                        while (qemu_isdigit(*p)) {
-                            count = count * 10 + (*p - '0');
-                            p++;
-                        }
-                    }
-                    size = -1;
-                    format = -1;
-                    for(;;) {
-                        switch(*p) {
-                        case 'o':
-                        case 'd':
-                        case 'u':
-                        case 'x':
-                        case 'i':
-                        case 'c':
-                            format = *p++;
-                            break;
-                        case 'b':
-                            size = 1;
-                            p++;
-                            break;
-                        case 'h':
-                            size = 2;
-                            p++;
-                            break;
-                        case 'w':
-                            size = 4;
-                            p++;
-                            break;
-                        case 'g':
-                        case 'L':
-                            size = 8;
-                            p++;
-                            break;
-                        default:
-                            goto next;
-                        }
-                    }
-                next:
-                    if (*p != '\0' && !qemu_isspace(*p)) {
-                        monitor_printf(mon, "invalid char in format: '%c'\n",
-                                       *p);
-                        goto fail;
-                    }
-                    if (format < 0)
-                        format = default_fmt_format;
-                    if (format != 'i') {
-                        /* for 'i', not specifying a size gives -1 as size */
-                        if (size < 0)
-                            size = default_fmt_size;
-                        default_fmt_size = size;
-                    }
-                    default_fmt_format = format;
-                } else {
-                    count = 1;
-                    format = default_fmt_format;
-                    if (format != 'i') {
-                        size = default_fmt_size;
-                    } else {
-                        size = -1;
-                    }
-                }
-                if (nb_args + 3 > MAX_ARGS)
-                    goto error_args;
-                args[nb_args++] = (void*)(long)count;
-                args[nb_args++] = (void*)(long)format;
-                args[nb_args++] = (void*)(long)size;
-            }
-            break;
-        case 'i':
-        case 'l':
-            {
-                int64_t val;
-
-                while (qemu_isspace(*p))
-                    p++;
-                if (*typestr == '?' || *typestr == '.') {
-                    if (*typestr == '?') {
-                        if (*p == '\0')
-                            has_arg = 0;
-                        else
-                            has_arg = 1;
-                    } else {
-                        if (*p == '.') {
-                            p++;
-                            while (qemu_isspace(*p))
-                                p++;
-                            has_arg = 1;
-                        } else {
-                            has_arg = 0;
-                        }
-                    }
-                    typestr++;
-                    if (nb_args >= MAX_ARGS)
-                        goto error_args;
-                    args[nb_args++] = (void *)(long)has_arg;
-                    if (!has_arg) {
-                        if (nb_args >= MAX_ARGS)
-                            goto error_args;
-                        val = -1;
-                        goto add_num;
-                    }
-                }
-                if (get_expr(mon, &val, &p))
-                    goto fail;
-            add_num:
-                if (c == 'i') {
-                    if (nb_args >= MAX_ARGS)
-                        goto error_args;
-                    args[nb_args++] = (void *)(long)val;
-                } else {
-                    if ((nb_args + 1) >= MAX_ARGS)
-                        goto error_args;
-#if TARGET_PHYS_ADDR_BITS > 32
-                    args[nb_args++] = (void *)(long)((val >> 32) & 0xffffffff);
-#else
-                    args[nb_args++] = (void *)0;
-#endif
-                    args[nb_args++] = (void *)(long)(val & 0xffffffff);
-                }
-            }
-            break;
-        case '-':
-            {
-                int has_option;
-                /* option */
-
-                c = *typestr++;
-                if (c == '\0')
-                    goto bad_type;
-                while (qemu_isspace(*p))
-                    p++;
-                has_option = 0;
-                if (*p == '-') {
-                    p++;
-                    if (*p != c) {
-                        monitor_printf(mon, "%s: unsupported option -%c\n",
-                                       cmdname, *p);
-                        goto fail;
-                    }
-                    p++;
-                    has_option = 1;
-                }
-                if (nb_args >= MAX_ARGS)
-                    goto error_args;
-                args[nb_args++] = (void *)(long)has_option;
-            }
-            break;
-        default:
-        bad_type:
-            monitor_printf(mon, "%s: unknown type '%c'\n", cmdname, c);
-            goto fail;
-        }
-    }
-    /* check that all arguments were parsed */
-    while (qemu_isspace(*p))
-        p++;
-    if (*p != '\0') {
-        monitor_printf(mon, "%s: extraneous characters at the end of line\n",
-                       cmdname);
-        goto fail;
-    }
-
-    switch(nb_args) {
-    case 0:
-        handler_0 = cmd->handler;
-        handler_0(mon);
-        break;
-    case 1:
-        handler_1 = cmd->handler;
-        handler_1(mon, args[0]);
-        break;
-    case 2:
-        handler_2 = cmd->handler;
-        handler_2(mon, args[0], args[1]);
-        break;
-    case 3:
-        handler_3 = cmd->handler;
-        handler_3(mon, args[0], args[1], args[2]);
-        break;
-    case 4:
-        handler_4 = cmd->handler;
-        handler_4(mon, args[0], args[1], args[2], args[3]);
-        break;
-    case 5:
-        handler_5 = cmd->handler;
-        handler_5(mon, args[0], args[1], args[2], args[3], args[4]);
-        break;
-    case 6:
-        handler_6 = cmd->handler;
-        handler_6(mon, args[0], args[1], args[2], args[3], args[4], args[5]);
-        break;
-    case 7:
-        handler_7 = cmd->handler;
-        handler_7(mon, args[0], args[1], args[2], args[3], args[4], args[5],
-                  args[6]);
-        break;
-    case 8:
-        handler_8 = cmd->handler;
-        handler_8(mon, args[0], args[1], args[2], args[3], args[4], args[5],
-                  args[6], args[7]);
-        break;
-    case 9:
-        handler_9 = cmd->handler;
-        handler_9(mon, args[0], args[1], args[2], args[3], args[4], args[5],
-                  args[6], args[7], args[8]);
-        break;
-    case 10:
-        handler_10 = cmd->handler;
-        handler_10(mon, args[0], args[1], args[2], args[3], args[4], args[5],
-                   args[6], args[7], args[8], args[9]);
-        break;
-    default:
-        monitor_printf(mon, "unsupported number of arguments: %d\n", nb_args);
-        goto fail;
-    }
- fail:
-    for(i = 0; i < MAX_ARGS; i++)
-        g_free(str_allocated[i]);
-}
-
-void monitor_set_error(Monitor *mon, QError *qerror)
-{
-#if 1
-    QDECREF(qerror);
-#else
-    /* report only the first error */
-    if (!mon->error) {
-        mon->error = qerror;
-    } else {
-        MON_DEBUG("Additional error report at %s:%d\n",
-                  qerror->file, qerror->linenr);
-        QDECREF(qerror);
-    }
-#endif
-}
-
-static void cmd_completion(const char *name, const char *list)
-{
-    const char *p, *pstart;
-    char cmd[128];
-    int len;
-
-    p = list;
-    for(;;) {
-        pstart = p;
-        p = strchr(p, '|');
-        if (!p)
-            p = pstart + strlen(pstart);
-        len = p - pstart;
-        if (len > sizeof(cmd) - 2)
-            len = sizeof(cmd) - 2;
-        memcpy(cmd, pstart, len);
-        cmd[len] = '\0';
-        if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
-            readline_add_completion(cur_mon->rs, cmd);
-        }
-        if (*p == '\0')
-            break;
-        p++;
-    }
-}
-
-static void file_completion(const char *input)
-{
-    DIR *ffs;
-    struct dirent *d;
-    char path[1024];
-    char file[1024], file_prefix[1024];
-    int input_path_len;
-    const char *p;
-
-    p = strrchr(input, '/');
-    if (!p) {
-        input_path_len = 0;
-        pstrcpy(file_prefix, sizeof(file_prefix), input);
-        pstrcpy(path, sizeof(path), ".");
-    } else {
-        input_path_len = p - input + 1;
-        memcpy(path, input, input_path_len);
-        if (input_path_len > sizeof(path) - 1)
-            input_path_len = sizeof(path) - 1;
-        path[input_path_len] = '\0';
-        pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
-    }
-#ifdef DEBUG_COMPLETION
-    monitor_printf(cur_mon, "input='%s' path='%s' prefix='%s'\n",
-                   input, path, file_prefix);
-#endif
-    ffs = opendir(path);
-    if (!ffs)
-        return;
-    for(;;) {
-        struct stat sb;
-        d = readdir(ffs);
-        if (!d)
-            break;
-        if (strstart(d->d_name, file_prefix, NULL)) {
-            memcpy(file, input, input_path_len);
-            if (input_path_len < sizeof(file))
-                pstrcpy(file + input_path_len, sizeof(file) - input_path_len,
-                        d->d_name);
-            /* stat the file to find out if it's a directory.
-             * In that case add a slash to speed up typing long paths
-             */
-            stat(file, &sb);
-            if(S_ISDIR(sb.st_mode))
-                pstrcat(file, sizeof(file), "/");
-            readline_add_completion(cur_mon->rs, file);
-        }
-    }
-    closedir(ffs);
-}
-
-static void block_completion_it(void *opaque, BlockDriverState *bs)
-{
-    const char *name = bdrv_get_device_name(bs);
-    const char *input = opaque;
-
-    if (input[0] == '\0' ||
-        !strncmp(name, (char *)input, strlen(input))) {
-        readline_add_completion(cur_mon->rs, name);
-    }
-}
-
-/* NOTE: this parser is an approximate form of the real command parser */
-static void parse_cmdline(const char *cmdline,
-                         int *pnb_args, char **args)
-{
-    const char *p;
-    int nb_args, ret;
-    char buf[1024];
-
-    p = cmdline;
-    nb_args = 0;
-    for(;;) {
-        while (qemu_isspace(*p))
-            p++;
-        if (*p == '\0')
-            break;
-        if (nb_args >= MAX_ARGS)
-            break;
-        ret = get_str(buf, sizeof(buf), &p);
-        args[nb_args] = g_strdup(buf);
-        nb_args++;
-        if (ret < 0)
-            break;
-    }
-    *pnb_args = nb_args;
-}
-
-static void monitor_find_completion(const char *cmdline)
-{
-    const char *cmdname;
-    char *args[MAX_ARGS];
-    int nb_args, i, len;
-    const char *ptype, *str;
-    const mon_cmd_t *cmd;
-    const KeyDef *key;
-
-    parse_cmdline(cmdline, &nb_args, args);
-#ifdef DEBUG_COMPLETION
-    for(i = 0; i < nb_args; i++) {
-        monitor_printf(cur_mon, "arg%d = '%s'\n", i, (char *)args[i]);
-    }
-#endif
-
-    /* if the line ends with a space, it means we want to complete the
-       next arg */
-    len = strlen(cmdline);
-    if (len > 0 && qemu_isspace(cmdline[len - 1])) {
-        if (nb_args >= MAX_ARGS)
-            return;
-        args[nb_args++] = g_strdup("");
-    }
-    if (nb_args <= 1) {
-        /* command completion */
-        if (nb_args == 0)
-            cmdname = "";
-        else
-            cmdname = args[0];
-        readline_set_completion_index(cur_mon->rs, strlen(cmdname));
-        for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
-            cmd_completion(cmdname, cmd->name);
-        }
-    } else {
-        /* find the command */
-        for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
-            if (compare_cmd(args[0], cmd->name))
-                goto found;
-        }
-        return;
-    found:
-        ptype = cmd->args_type;
-        for(i = 0; i < nb_args - 2; i++) {
-            if (*ptype != '\0') {
-                ptype++;
-                while (*ptype == '?')
-                    ptype++;
-            }
-        }
-        str = args[nb_args - 1];
-        switch(*ptype) {
-        case 'F':
-            /* file completion */
-            readline_set_completion_index(cur_mon->rs, strlen(str));
-            file_completion(str);
-            break;
-        case 'B':
-            /* block device name completion */
-            readline_set_completion_index(cur_mon->rs, strlen(str));
-            bdrv_iterate(block_completion_it, (void *)str);
-            break;
-        case 's':
-            /* XXX: more generic ? */
-            if (!strcmp(cmd->name, "info")) {
-                readline_set_completion_index(cur_mon->rs, strlen(str));
-                for(cmd = info_cmds; cmd->name != NULL; cmd++) {
-                    cmd_completion(str, cmd->name);
-                }
-            } else if (!strcmp(cmd->name, "sendkey")) {
-                char *sep = strrchr(str, '-');
-                if (sep)
-                    str = sep + 1;
-                readline_set_completion_index(cur_mon->rs, strlen(str));
-                for(key = key_defs; key->name != NULL; key++) {
-                    cmd_completion(str, key->name);
-                }
-            }
-            break;
-        default:
-            break;
-        }
-    }
-    for(i = 0; i < nb_args; i++)
-        g_free(args[i]);
-}
-
-static int monitor_can_read(void *opaque)
-{
-    Monitor *mon = opaque;
-
-    return (mon->suspend_cnt == 0) ? 128 : 0;
-}
-
-static void monitor_done(Monitor *mon); // forward
-
-static void monitor_read(void *opaque, const uint8_t *buf, int size)
-{
-    Monitor *old_mon = cur_mon;
-    int i;
-
-    cur_mon = opaque;
-
-    if (cur_mon->rs) {
-        for (i = 0; i < size; i++)
-            readline_handle_byte(cur_mon->rs, buf[i]);
-    } else {
-        if (size == 0 || buf[size - 1] != 0)
-            monitor_printf(cur_mon, "corrupted command\n");
-        else
-            monitor_handle_command(cur_mon, (char *)buf);
-    }
-
-    if (cur_mon->has_quit) {
-        monitor_done(cur_mon);
-    }
-    cur_mon = old_mon;
-}
-
-static void monitor_command_cb(Monitor *mon, const char *cmdline, void *opaque)
-{
-    monitor_suspend(mon);
-    monitor_handle_command(mon, cmdline);
-    monitor_resume(mon);
-}
-
-int monitor_suspend(Monitor *mon)
-{
-    if (!mon->rs)
-        return -ENOTTY;
-    mon->suspend_cnt++;
-    return 0;
-}
-
-void monitor_resume(Monitor *mon)
-{
-    if (!mon->rs)
-        return;
-    if (--mon->suspend_cnt == 0)
-        readline_show_prompt(mon->rs);
-}
-
-static void monitor_event(void *opaque, int event)
-{
-    Monitor *mon = opaque;
-
-    switch (event) {
-    case CHR_EVENT_MUX_IN:
-        mon->mux_out = 0;
-        if (mon->reset_seen) {
-            readline_restart(mon->rs);
-            monitor_resume(mon);
-            monitor_flush(mon);
-        } else {
-            mon->suspend_cnt = 0;
-        }
-        break;
-
-    case CHR_EVENT_MUX_OUT:
-        if (mon->reset_seen) {
-            if (mon->suspend_cnt == 0) {
-                monitor_printf(mon, "\n");
-            }
-            monitor_flush(mon);
-            monitor_suspend(mon);
-        } else {
-            mon->suspend_cnt++;
-        }
-        mon->mux_out = 1;
-        break;
-
-    case CHR_EVENT_OPENED:
-        monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
-                       "information\n", QEMU_VERSION);
-        if (!mon->mux_out) {
-            readline_show_prompt(mon->rs);
-        }
-        mon->reset_seen = 1;
-        break;
-    }
-}
-
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
-
-void monitor_init(CharDriverState *chr, int flags)
-{
-    static int is_first_init = 1;
-    Monitor *mon;
-
-    if (is_first_init) {
-        key_timer = qemu_new_timer_ms(vm_clock, release_keys, NULL);
-        is_first_init = 0;
-    }
-
-    mon = g_malloc0(sizeof(*mon));
-
-    mon->chr = chr;
-    mon->flags = flags;
-    if (flags & MONITOR_USE_READLINE) {
-        mon->rs = readline_init(mon, monitor_find_completion);
-        monitor_read_command(mon, 0);
-    }
-
-    qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, monitor_event,
-                          mon);
-
-    QLIST_INSERT_HEAD(&mon_list, mon, entry);
-    if (!cur_mon || (flags & MONITOR_IS_DEFAULT))
-        cur_mon = mon;
-}
-
-static void monitor_done(Monitor *mon)
-{
-    if (cur_mon == mon)
-        cur_mon = NULL;
-
-    QLIST_REMOVE(mon, entry);
-
-    readline_free(mon->rs);
-    qemu_chr_close(mon->chr);
-
-    g_free(mon);
-}
-
-static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque)
-{
-    BlockDriverState *bs = opaque;
-    int ret = 0;
-
-    if (bdrv_set_key(bs, password) != 0) {
-        monitor_printf(mon, "invalid password\n");
-        ret = -EPERM;
-    }
-    if (mon->password_completion_cb)
-        mon->password_completion_cb(mon->password_opaque, ret);
-
-    monitor_read_command(mon, 1);
-}
-
-int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
-                                BlockDriverCompletionFunc *completion_cb,
-                                void *opaque)
-{
-    int err;
-
-    if (!bdrv_key_required(bs)) {
-        if (completion_cb)
-            completion_cb(opaque, 0);
-        return 0;
-    }
-
-    if (monitor_ctrl_mode(mon)) {
-        qerror_report(QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs));
-        return -1;
-    }
-
-    monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
-                   bdrv_get_encrypted_filename(bs));
-
-    mon->password_completion_cb = completion_cb;
-    mon->password_opaque = opaque;
-
-    err = monitor_read_password(mon, bdrv_password_cb, bs);
-
-    if (err && completion_cb)
-        completion_cb(opaque, err);
-
-    return err;
-}
diff --git a/net/net.c b/net/net.c
index b05181d..56bea18 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1611,7 +1611,7 @@
     }
 
     val = 1;
-    ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+    ret=qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
                    (const char *)&val, sizeof(val));
     if (ret < 0) {
 	perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
@@ -1628,7 +1628,7 @@
     imr.imr_multiaddr = mcastaddr->sin_addr;
     imr.imr_interface.s_addr = htonl(INADDR_ANY);
 
-    ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+    ret = qemu_setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                      (const char *)&imr, sizeof(struct ip_mreq));
     if (ret < 0) {
 	perror("setsockopt(IP_ADD_MEMBERSHIP)");
@@ -1637,7 +1637,7 @@
 
     /* Force mcast msgs to loopback (eg. several QEMUs in same host */
     val = 1;
-    ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
+    ret=qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
                    (const char *)&val, sizeof(val));
     if (ret < 0) {
 	perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
@@ -1818,7 +1818,7 @@
 
     /* allow fast reuse */
     val = 1;
-    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
+    qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
 
     ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
     if (ret < 0) {
diff --git a/os-posix.c b/os-posix.c
index 75d68b5..b46d4dd 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -387,12 +387,3 @@
 
     return 0;
 }
-
-int qemu_get_thread_id(void)
-{
-#if defined (__linux__)
-    return syscall(SYS_gettid);
-#else
-    return getpid();
-#endif
-}
diff --git a/os-win32.c b/os-win32.c
index 0acbaf9..c40c4af 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -48,129 +48,6 @@
     return result;
 }
 
-/***********************************************************/
-/* Polling handling */
-
-typedef struct PollingEntry {
-    PollingFunc *func;
-    void *opaque;
-    struct PollingEntry *next;
-} PollingEntry;
-
-static PollingEntry *first_polling_entry;
-
-int qemu_add_polling_cb(PollingFunc *func, void *opaque)
-{
-    PollingEntry **ppe, *pe;
-    pe = g_malloc0(sizeof(PollingEntry));
-    pe->func = func;
-    pe->opaque = opaque;
-    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
-    *ppe = pe;
-    return 0;
-}
-
-void qemu_del_polling_cb(PollingFunc *func, void *opaque)
-{
-    PollingEntry **ppe, *pe;
-    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
-        pe = *ppe;
-        if (pe->func == func && pe->opaque == opaque) {
-            *ppe = pe->next;
-            g_free(pe);
-            break;
-        }
-    }
-}
-
-/***********************************************************/
-/* Wait objects support */
-typedef struct WaitObjects {
-    int num;
-    HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
-    WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
-    void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
-} WaitObjects;
-
-static WaitObjects wait_objects = {0};
-
-int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
-{
-    WaitObjects *w = &wait_objects;
-
-    if (w->num >= MAXIMUM_WAIT_OBJECTS)
-        return -1;
-    w->events[w->num] = handle;
-    w->func[w->num] = func;
-    w->opaque[w->num] = opaque;
-    w->num++;
-    return 0;
-}
-
-void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
-{
-    int i, found;
-    WaitObjects *w = &wait_objects;
-
-    found = 0;
-    for (i = 0; i < w->num; i++) {
-        if (w->events[i] == handle)
-            found = 1;
-        if (found) {
-            w->events[i] = w->events[i + 1];
-            w->func[i] = w->func[i + 1];
-            w->opaque[i] = w->opaque[i + 1];
-        }
-    }
-    if (found)
-        w->num--;
-}
-
-void os_host_main_loop_wait(int *timeout)
-{
-    int ret, ret2, i;
-    PollingEntry *pe;
-
-    /* XXX: need to suppress polling by better using win32 events */
-    ret = 0;
-    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
-        ret |= pe->func(pe->opaque);
-    }
-    if (ret == 0) {
-        int err;
-        WaitObjects *w = &wait_objects;
-
-        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]);
-
-            /* 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) {
-                } else {
-                    err = GetLastError();
-                    fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
-                }
-            }
-        } else if (ret == WAIT_TIMEOUT) {
-        } else {
-            err = GetLastError();
-            fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
-        }
-    }
-
-    *timeout = 0;
-}
-
 static BOOL WINAPI qemu_ctrl_handler(DWORD type)
 {
     exit(STATUS_CONTROL_C_EXIT);
@@ -266,8 +143,3 @@
     }
     return 0;
 }
-
-int qemu_get_thread_id(void)
-{
-    return GetCurrentThreadId();
-}
diff --git a/posix-aio-compat.c b/posix-aio-compat.c
index aa9df42..269f6c0 100644
--- a/posix-aio-compat.c
+++ b/posix-aio-compat.c
@@ -512,7 +512,7 @@
             die("write()");
     }
 
-    qemu_service_io();
+    qemu_notify_event();
 }
 
 static void paio_remove(struct qemu_paiocb *acb)
diff --git a/qapi-auto-generated/qapi-types.c b/qapi-auto-generated/qapi-types.c
new file mode 100644
index 0000000..da75232
--- /dev/null
+++ b/qapi-auto-generated/qapi-types.c
@@ -0,0 +1,4025 @@
+/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * deallocation functions for schema-defined QAPI types
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *  Michael Roth      <mdroth@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qapi/dealloc-visitor.h"
+#include "qapi-types.h"
+#include "qapi-visit.h"
+
+const char *ErrorClass_lookup[] = {
+    "GenericError",
+    "CommandNotFound",
+    "DeviceEncrypted",
+    "DeviceNotActive",
+    "DeviceNotFound",
+    "KVMMissingCap",
+    NULL,
+};
+
+const char *RunState_lookup[] = {
+    "debug",
+    "inmigrate",
+    "internal-error",
+    "io-error",
+    "paused",
+    "postmigrate",
+    "prelaunch",
+    "finish-migrate",
+    "restore-vm",
+    "running",
+    "save-vm",
+    "shutdown",
+    "suspended",
+    "watchdog",
+    "guest-panicked",
+    NULL,
+};
+
+const char *ImageInfoSpecificKind_lookup[] = {
+    "qcow2",
+    "vmdk",
+    NULL,
+};
+
+const char *DataFormat_lookup[] = {
+    "utf8",
+    "base64",
+    NULL,
+};
+
+const char *MigrationCapability_lookup[] = {
+    "xbzrle",
+    "x-rdma-pin-all",
+    "auto-converge",
+    "zero-blocks",
+    NULL,
+};
+
+const char *BlockDeviceIoStatus_lookup[] = {
+    "ok",
+    "failed",
+    "nospace",
+    NULL,
+};
+
+const char *SpiceQueryMouseMode_lookup[] = {
+    "client",
+    "server",
+    "unknown",
+    NULL,
+};
+
+const char *BlockdevOnError_lookup[] = {
+    "report",
+    "ignore",
+    "enospc",
+    "stop",
+    NULL,
+};
+
+const char *MirrorSyncMode_lookup[] = {
+    "top",
+    "full",
+    "none",
+    NULL,
+};
+
+const char *BlockJobType_lookup[] = {
+    "commit",
+    "stream",
+    "mirror",
+    "backup",
+    NULL,
+};
+
+const char *NewImageMode_lookup[] = {
+    "existing",
+    "absolute-paths",
+    NULL,
+};
+
+const char *TransactionActionKind_lookup[] = {
+    "blockdev-snapshot-sync",
+    "drive-backup",
+    "abort",
+    "blockdev-snapshot-internal-sync",
+    NULL,
+};
+
+const char *NetClientOptionsKind_lookup[] = {
+    "none",
+    "nic",
+    "user",
+    "tap",
+    "socket",
+    "vde",
+    "dump",
+    "bridge",
+    "hubport",
+    "netmap",
+    NULL,
+};
+
+const char *SocketAddressKind_lookup[] = {
+    "inet",
+    "unix",
+    "fd",
+    NULL,
+};
+
+const char *QKeyCode_lookup[] = {
+    "shift",
+    "shift_r",
+    "alt",
+    "alt_r",
+    "altgr",
+    "altgr_r",
+    "ctrl",
+    "ctrl_r",
+    "menu",
+    "esc",
+    "1",
+    "2",
+    "3",
+    "4",
+    "5",
+    "6",
+    "7",
+    "8",
+    "9",
+    "0",
+    "minus",
+    "equal",
+    "backspace",
+    "tab",
+    "q",
+    "w",
+    "e",
+    "r",
+    "t",
+    "y",
+    "u",
+    "i",
+    "o",
+    "p",
+    "bracket_left",
+    "bracket_right",
+    "ret",
+    "a",
+    "s",
+    "d",
+    "f",
+    "g",
+    "h",
+    "j",
+    "k",
+    "l",
+    "semicolon",
+    "apostrophe",
+    "grave_accent",
+    "backslash",
+    "z",
+    "x",
+    "c",
+    "v",
+    "b",
+    "n",
+    "m",
+    "comma",
+    "dot",
+    "slash",
+    "asterisk",
+    "spc",
+    "caps_lock",
+    "f1",
+    "f2",
+    "f3",
+    "f4",
+    "f5",
+    "f6",
+    "f7",
+    "f8",
+    "f9",
+    "f10",
+    "num_lock",
+    "scroll_lock",
+    "kp_divide",
+    "kp_multiply",
+    "kp_subtract",
+    "kp_add",
+    "kp_enter",
+    "kp_decimal",
+    "sysrq",
+    "kp_0",
+    "kp_1",
+    "kp_2",
+    "kp_3",
+    "kp_4",
+    "kp_5",
+    "kp_6",
+    "kp_7",
+    "kp_8",
+    "kp_9",
+    "less",
+    "f11",
+    "f12",
+    "print",
+    "home",
+    "pgup",
+    "pgdn",
+    "end",
+    "left",
+    "up",
+    "down",
+    "right",
+    "insert",
+    "delete",
+    "stop",
+    "again",
+    "props",
+    "undo",
+    "front",
+    "copy",
+    "open",
+    "paste",
+    "find",
+    "cut",
+    "lf",
+    "help",
+    "meta_l",
+    "meta_r",
+    "compose",
+    NULL,
+};
+
+const char *KeyValueKind_lookup[] = {
+    "number",
+    "qcode",
+    NULL,
+};
+
+const char *ChardevBackendKind_lookup[] = {
+    "file",
+    "serial",
+    "parallel",
+    "pipe",
+    "socket",
+    "udp",
+    "pty",
+    "null",
+    "mux",
+    "msmouse",
+    "braille",
+    "stdio",
+    "console",
+    "spicevmc",
+    "spiceport",
+    "vc",
+    "ringbuf",
+    "memory",
+    NULL,
+};
+
+const char *TpmModel_lookup[] = {
+    "tpm-tis",
+    NULL,
+};
+
+const char *TpmType_lookup[] = {
+    "passthrough",
+    NULL,
+};
+
+const char *TpmTypeOptionsKind_lookup[] = {
+    "passthrough",
+    NULL,
+};
+
+const char *CommandLineParameterType_lookup[] = {
+    "string",
+    "boolean",
+    "number",
+    "size",
+    NULL,
+};
+
+const char *X86CPURegister32_lookup[] = {
+    "EAX",
+    "EBX",
+    "ECX",
+    "EDX",
+    "ESP",
+    "EBP",
+    "ESI",
+    "EDI",
+    NULL,
+};
+
+const char *RxState_lookup[] = {
+    "normal",
+    "none",
+    "all",
+    NULL,
+};
+
+const char *BlockdevDiscardOptions_lookup[] = {
+    "ignore",
+    "unmap",
+    NULL,
+};
+
+const char *BlockdevAioOptions_lookup[] = {
+    "threads",
+    "native",
+    NULL,
+};
+
+const char *BlockdevOptionsKind_lookup[] = {
+    "file",
+    "http",
+    "https",
+    "ftp",
+    "ftps",
+    "tftp",
+    "vvfat",
+    "bochs",
+    "cloop",
+    "cow",
+    "dmg",
+    "parallels",
+    "qcow",
+    "qcow2",
+    "qed",
+    "raw",
+    "vdi",
+    "vhdx",
+    "vmdk",
+    "vpc",
+    NULL,
+};
+
+const char *BlockdevRefKind_lookup[] = {
+    "definition",
+    "reference",
+    NULL,
+};
+
+const int BlockdevRef_qtypes[QTYPE_MAX] = {
+    [ QTYPE_QDICT ] = BLOCKDEV_REF_KIND_DEFINITION,
+    [ QTYPE_QSTRING ] = BLOCKDEV_REF_KIND_REFERENCE,
+};
+
+#ifndef QAPI_TYPES_BUILTIN_CLEANUP_DEF_H
+#define QAPI_TYPES_BUILTIN_CLEANUP_DEF_H
+
+
+void qapi_free_strList(strList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_strList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+void qapi_free_intList(intList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_intList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+void qapi_free_numberList(numberList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_numberList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+void qapi_free_boolList(boolList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_boolList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+void qapi_free_int8List(int8List * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int8List(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+void qapi_free_int16List(int16List * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int16List(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+void qapi_free_int32List(int32List * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int32List(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+void qapi_free_int64List(int64List * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int64List(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+void qapi_free_uint8List(uint8List * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_uint8List(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+void qapi_free_uint16List(uint16List * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_uint16List(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+void qapi_free_uint32List(uint32List * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_uint32List(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+void qapi_free_uint64List(uint64List * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_uint64List(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+#endif /* QAPI_TYPES_BUILTIN_CLEANUP_DEF_H */
+
+
+void qapi_free_ErrorClassList(ErrorClassList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ErrorClassList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NameInfoList(NameInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NameInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NameInfo(NameInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NameInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_VersionInfoList(VersionInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_VersionInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_VersionInfo(VersionInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_VersionInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_KvmInfoList(KvmInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_KvmInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_KvmInfo(KvmInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_KvmInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_RunStateList(RunStateList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_RunStateList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_SnapshotInfoList(SnapshotInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SnapshotInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_SnapshotInfo(SnapshotInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SnapshotInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ImageInfoSpecificQCow2List(ImageInfoSpecificQCow2List * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ImageInfoSpecificQCow2List(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ImageInfoSpecificQCow2(ImageInfoSpecificQCow2 * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ImageInfoSpecificQCow2(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ImageInfoSpecificVmdkList(ImageInfoSpecificVmdkList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ImageInfoSpecificVmdkList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ImageInfoSpecificVmdk(ImageInfoSpecificVmdk * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ImageInfoSpecificVmdk(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ImageInfoSpecificList(ImageInfoSpecificList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ImageInfoSpecificList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ImageInfoSpecific(ImageInfoSpecific * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ImageInfoSpecific(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ImageInfoList(ImageInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ImageInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ImageInfo(ImageInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ImageInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ImageCheckList(ImageCheckList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ImageCheckList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ImageCheck(ImageCheck * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ImageCheck(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_StatusInfoList(StatusInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_StatusInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_StatusInfo(StatusInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_StatusInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_UuidInfoList(UuidInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_UuidInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_UuidInfo(UuidInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_UuidInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevInfoList(ChardevInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevInfo(ChardevInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_DataFormatList(DataFormatList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_DataFormatList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_CommandInfoList(CommandInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CommandInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_CommandInfo(CommandInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CommandInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_EventInfoList(EventInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_EventInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_EventInfo(EventInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_EventInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MigrationStatsList(MigrationStatsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MigrationStatsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MigrationStats(MigrationStats * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MigrationStats(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_XBZRLECacheStatsList(XBZRLECacheStatsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_XBZRLECacheStatsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_XBZRLECacheStats(XBZRLECacheStats * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_XBZRLECacheStats(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MigrationInfoList(MigrationInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MigrationInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MigrationInfo(MigrationInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MigrationInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MigrationCapabilityList(MigrationCapabilityList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MigrationCapabilityList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MigrationCapabilityStatusList(MigrationCapabilityStatusList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MigrationCapabilityStatusList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MigrationCapabilityStatus(MigrationCapabilityStatus * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MigrationCapabilityStatus(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MouseInfoList(MouseInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MouseInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MouseInfo(MouseInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MouseInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_CpuInfoList(CpuInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CpuInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_CpuInfo(CpuInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CpuInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockDeviceInfoList(BlockDeviceInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockDeviceInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockDeviceInfo(BlockDeviceInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockDeviceInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockDeviceIoStatusList(BlockDeviceIoStatusList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockDeviceIoStatusList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockDeviceMapEntryList(BlockDeviceMapEntryList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockDeviceMapEntryList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockDeviceMapEntry(BlockDeviceMapEntry * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockDeviceMapEntry(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockDirtyInfoList(BlockDirtyInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockDirtyInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockDirtyInfo(BlockDirtyInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockDirtyInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockInfoList(BlockInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockInfo(BlockInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockDeviceStatsList(BlockDeviceStatsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockDeviceStatsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockDeviceStats(BlockDeviceStats * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockDeviceStats(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockStatsList(BlockStatsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockStatsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockStats(BlockStats * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockStats(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_VncClientInfoList(VncClientInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_VncClientInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_VncClientInfo(VncClientInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_VncClientInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_VncInfoList(VncInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_VncInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_VncInfo(VncInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_VncInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_SpiceChannelList(SpiceChannelList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SpiceChannelList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_SpiceChannel(SpiceChannel * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SpiceChannel(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_SpiceQueryMouseModeList(SpiceQueryMouseModeList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SpiceQueryMouseModeList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_SpiceInfoList(SpiceInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SpiceInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_SpiceInfo(SpiceInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SpiceInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BalloonInfoList(BalloonInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BalloonInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BalloonInfo(BalloonInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BalloonInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_PciMemoryRangeList(PciMemoryRangeList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_PciMemoryRangeList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_PciMemoryRange(PciMemoryRange * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_PciMemoryRange(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_PciMemoryRegionList(PciMemoryRegionList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_PciMemoryRegionList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_PciMemoryRegion(PciMemoryRegion * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_PciMemoryRegion(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_PciBridgeInfoList(PciBridgeInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_PciBridgeInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_PciBridgeInfo(PciBridgeInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_PciBridgeInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_PciDeviceInfoList(PciDeviceInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_PciDeviceInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_PciDeviceInfo(PciDeviceInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_PciDeviceInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_PciInfoList(PciInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_PciInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_PciInfo(PciInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_PciInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOnErrorList(BlockdevOnErrorList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOnErrorList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MirrorSyncModeList(MirrorSyncModeList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MirrorSyncModeList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockJobTypeList(BlockJobTypeList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockJobTypeList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockJobInfoList(BlockJobInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockJobInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockJobInfo(BlockJobInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockJobInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NewImageModeList(NewImageModeList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NewImageModeList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevSnapshotList(BlockdevSnapshotList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevSnapshotList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevSnapshot(BlockdevSnapshot * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevSnapshot(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevSnapshotInternalList(BlockdevSnapshotInternalList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevSnapshotInternalList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevSnapshotInternal(BlockdevSnapshotInternal * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevSnapshotInternal(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_DriveBackupList(DriveBackupList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_DriveBackupList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_DriveBackup(DriveBackup * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_DriveBackup(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_AbortList(AbortList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_AbortList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_Abort(Abort * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_Abort(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TransactionActionList(TransactionActionList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TransactionActionList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TransactionAction(TransactionAction * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TransactionAction(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ObjectPropertyInfoList(ObjectPropertyInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ObjectPropertyInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ObjectPropertyInfo(ObjectPropertyInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ObjectPropertyInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ObjectTypeInfoList(ObjectTypeInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ObjectTypeInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ObjectTypeInfo(ObjectTypeInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ObjectTypeInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_DevicePropertyInfoList(DevicePropertyInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_DevicePropertyInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_DevicePropertyInfo(DevicePropertyInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_DevicePropertyInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevNoneOptionsList(NetdevNoneOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevNoneOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevNoneOptions(NetdevNoneOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevNoneOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetLegacyNicOptionsList(NetLegacyNicOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetLegacyNicOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetLegacyNicOptions(NetLegacyNicOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetLegacyNicOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_StringList(StringList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_StringList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_String(String * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_String(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevUserOptionsList(NetdevUserOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevUserOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevUserOptions(NetdevUserOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevUserOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevTapOptionsList(NetdevTapOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevTapOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevTapOptions(NetdevTapOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevTapOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevSocketOptionsList(NetdevSocketOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevSocketOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevSocketOptions(NetdevSocketOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevSocketOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevVdeOptionsList(NetdevVdeOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevVdeOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevVdeOptions(NetdevVdeOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevVdeOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevDumpOptionsList(NetdevDumpOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevDumpOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevDumpOptions(NetdevDumpOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevDumpOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevBridgeOptionsList(NetdevBridgeOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevBridgeOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevBridgeOptions(NetdevBridgeOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevBridgeOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevHubPortOptionsList(NetdevHubPortOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevHubPortOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevHubPortOptions(NetdevHubPortOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevHubPortOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevNetmapOptionsList(NetdevNetmapOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevNetmapOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevNetmapOptions(NetdevNetmapOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevNetmapOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetClientOptionsList(NetClientOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetClientOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetClientOptions(NetClientOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetClientOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetLegacyList(NetLegacyList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetLegacyList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetLegacy(NetLegacy * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetLegacy(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_NetdevList(NetdevList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NetdevList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_Netdev(Netdev * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_Netdev(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_InetSocketAddressList(InetSocketAddressList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_InetSocketAddressList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_InetSocketAddress(InetSocketAddress * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_InetSocketAddress(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_UnixSocketAddressList(UnixSocketAddressList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_UnixSocketAddressList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_UnixSocketAddress(UnixSocketAddress * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_UnixSocketAddress(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_SocketAddressList(SocketAddressList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SocketAddressList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_SocketAddress(SocketAddress * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SocketAddress(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MachineInfoList(MachineInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MachineInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_MachineInfo(MachineInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MachineInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_CpuDefinitionInfoList(CpuDefinitionInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CpuDefinitionInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_CpuDefinitionInfo(CpuDefinitionInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CpuDefinitionInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_AddfdInfoList(AddfdInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_AddfdInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_AddfdInfo(AddfdInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_AddfdInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_FdsetFdInfoList(FdsetFdInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_FdsetFdInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_FdsetFdInfo(FdsetFdInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_FdsetFdInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_FdsetInfoList(FdsetInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_FdsetInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_FdsetInfo(FdsetInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_FdsetInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TargetInfoList(TargetInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TargetInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TargetInfo(TargetInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TargetInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_QKeyCodeList(QKeyCodeList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_QKeyCodeList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_KeyValueList(KeyValueList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_KeyValueList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_KeyValue(KeyValue * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_KeyValue(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevFileList(ChardevFileList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevFileList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevFile(ChardevFile * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevFile(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevHostdevList(ChardevHostdevList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevHostdevList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevHostdev(ChardevHostdev * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevHostdev(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevSocketList(ChardevSocketList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevSocketList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevSocket(ChardevSocket * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevSocket(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevUdpList(ChardevUdpList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevUdpList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevUdp(ChardevUdp * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevUdp(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevMuxList(ChardevMuxList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevMuxList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevMux(ChardevMux * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevMux(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevStdioList(ChardevStdioList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevStdioList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevStdio(ChardevStdio * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevStdio(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevSpiceChannelList(ChardevSpiceChannelList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevSpiceChannelList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevSpiceChannel(ChardevSpiceChannel * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevSpiceChannel(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevSpicePortList(ChardevSpicePortList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevSpicePortList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevSpicePort(ChardevSpicePort * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevSpicePort(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevVCList(ChardevVCList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevVCList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevVC(ChardevVC * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevVC(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevRingbufList(ChardevRingbufList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevRingbufList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevRingbuf(ChardevRingbuf * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevRingbuf(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevDummyList(ChardevDummyList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevDummyList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevDummy(ChardevDummy * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevDummy(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevBackendList(ChardevBackendList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevBackendList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevBackend(ChardevBackend * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevBackend(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevReturnList(ChardevReturnList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevReturnList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_ChardevReturn(ChardevReturn * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevReturn(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TpmModelList(TpmModelList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TpmModelList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TpmTypeList(TpmTypeList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TpmTypeList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TPMPassthroughOptionsList(TPMPassthroughOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TPMPassthroughOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TPMPassthroughOptions(TPMPassthroughOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TPMPassthroughOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TpmTypeOptionsList(TpmTypeOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TpmTypeOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TpmTypeOptions(TpmTypeOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TpmTypeOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TPMInfoList(TPMInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TPMInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_TPMInfo(TPMInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TPMInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_AcpiTableOptionsList(AcpiTableOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_AcpiTableOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_AcpiTableOptions(AcpiTableOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_AcpiTableOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_CommandLineParameterTypeList(CommandLineParameterTypeList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CommandLineParameterTypeList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_CommandLineParameterInfoList(CommandLineParameterInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CommandLineParameterInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_CommandLineParameterInfo(CommandLineParameterInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CommandLineParameterInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_CommandLineOptionInfoList(CommandLineOptionInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CommandLineOptionInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_CommandLineOptionInfo(CommandLineOptionInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CommandLineOptionInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_X86CPURegister32List(X86CPURegister32List * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_X86CPURegister32List(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_X86CPUFeatureWordInfoList(X86CPUFeatureWordInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_X86CPUFeatureWordInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_X86CPUFeatureWordInfo(X86CPUFeatureWordInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_X86CPUFeatureWordInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_RxStateList(RxStateList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_RxStateList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_RxFilterInfoList(RxFilterInfoList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_RxFilterInfoList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_RxFilterInfo(RxFilterInfo * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_RxFilterInfo(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevDiscardOptionsList(BlockdevDiscardOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevDiscardOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevAioOptionsList(BlockdevAioOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevAioOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevCacheOptionsList(BlockdevCacheOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevCacheOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevCacheOptions(BlockdevCacheOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevCacheOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsBaseList(BlockdevOptionsBaseList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsBaseList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsBase(BlockdevOptionsBase * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsBase(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsFileList(BlockdevOptionsFileList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsFileList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsFile(BlockdevOptionsFile * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsFile(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsVVFATList(BlockdevOptionsVVFATList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsVVFATList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsVVFAT(BlockdevOptionsVVFAT * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsVVFAT(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsGenericFormatList(BlockdevOptionsGenericFormatList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsGenericFormatList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsGenericFormat(BlockdevOptionsGenericFormat * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsGenericFormat(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsGenericCOWFormatList(BlockdevOptionsGenericCOWFormatList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsGenericCOWFormatList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsGenericCOWFormat(BlockdevOptionsGenericCOWFormat * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsGenericCOWFormat(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsQcow2List(BlockdevOptionsQcow2List * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsQcow2List(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsQcow2(BlockdevOptionsQcow2 * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsQcow2(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptionsList(BlockdevOptionsList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptionsList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevOptions(BlockdevOptions * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptions(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevRefList(BlockdevRefList * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevRefList(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+
+void qapi_free_BlockdevRef(BlockdevRef * obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevRef(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
diff --git a/qapi-auto-generated/qapi-types.h b/qapi-auto-generated/qapi-types.h
new file mode 100644
index 0000000..3837683
--- /dev/null
+++ b/qapi-auto-generated/qapi-types.h
@@ -0,0 +1,3313 @@
+/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QAPI types
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QAPI_TYPES_H
+#define QAPI_TYPES_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+
+#ifndef QAPI_TYPES_BUILTIN_STRUCT_DECL_H
+#define QAPI_TYPES_BUILTIN_STRUCT_DECL_H
+
+
+typedef struct strList
+{
+    union {
+        char * value;
+        uint64_t padding;
+    };
+    struct strList *next;
+} strList;
+
+typedef struct intList
+{
+    union {
+        int64_t value;
+        uint64_t padding;
+    };
+    struct intList *next;
+} intList;
+
+typedef struct numberList
+{
+    union {
+        double value;
+        uint64_t padding;
+    };
+    struct numberList *next;
+} numberList;
+
+typedef struct boolList
+{
+    union {
+        bool value;
+        uint64_t padding;
+    };
+    struct boolList *next;
+} boolList;
+
+typedef struct int8List
+{
+    union {
+        int8_t value;
+        uint64_t padding;
+    };
+    struct int8List *next;
+} int8List;
+
+typedef struct int16List
+{
+    union {
+        int16_t value;
+        uint64_t padding;
+    };
+    struct int16List *next;
+} int16List;
+
+typedef struct int32List
+{
+    union {
+        int32_t value;
+        uint64_t padding;
+    };
+    struct int32List *next;
+} int32List;
+
+typedef struct int64List
+{
+    union {
+        int64_t value;
+        uint64_t padding;
+    };
+    struct int64List *next;
+} int64List;
+
+typedef struct uint8List
+{
+    union {
+        uint8_t value;
+        uint64_t padding;
+    };
+    struct uint8List *next;
+} uint8List;
+
+typedef struct uint16List
+{
+    union {
+        uint16_t value;
+        uint64_t padding;
+    };
+    struct uint16List *next;
+} uint16List;
+
+typedef struct uint32List
+{
+    union {
+        uint32_t value;
+        uint64_t padding;
+    };
+    struct uint32List *next;
+} uint32List;
+
+typedef struct uint64List
+{
+    union {
+        uint64_t value;
+        uint64_t padding;
+    };
+    struct uint64List *next;
+} uint64List;
+
+#endif /* QAPI_TYPES_BUILTIN_STRUCT_DECL_H */
+
+
+extern const char *ErrorClass_lookup[];
+typedef enum ErrorClass
+{
+    ERROR_CLASS_GENERIC_ERROR = 0,
+    ERROR_CLASS_COMMAND_NOT_FOUND = 1,
+    ERROR_CLASS_DEVICE_ENCRYPTED = 2,
+    ERROR_CLASS_DEVICE_NOT_ACTIVE = 3,
+    ERROR_CLASS_DEVICE_NOT_FOUND = 4,
+    ERROR_CLASS_K_V_M_MISSING_CAP = 5,
+    ERROR_CLASS_MAX = 6,
+} ErrorClass;
+
+typedef struct ErrorClassList
+{
+    union {
+        ErrorClass value;
+        uint64_t padding;
+    };
+    struct ErrorClassList *next;
+} ErrorClassList;
+
+
+typedef struct NameInfo NameInfo;
+
+typedef struct NameInfoList
+{
+    union {
+        NameInfo *value;
+        uint64_t padding;
+    };
+    struct NameInfoList *next;
+} NameInfoList;
+
+
+typedef struct VersionInfo VersionInfo;
+
+typedef struct VersionInfoList
+{
+    union {
+        VersionInfo *value;
+        uint64_t padding;
+    };
+    struct VersionInfoList *next;
+} VersionInfoList;
+
+
+typedef struct KvmInfo KvmInfo;
+
+typedef struct KvmInfoList
+{
+    union {
+        KvmInfo *value;
+        uint64_t padding;
+    };
+    struct KvmInfoList *next;
+} KvmInfoList;
+
+extern const char *RunState_lookup[];
+typedef enum RunState
+{
+    RUN_STATE_DEBUG = 0,
+    RUN_STATE_INMIGRATE = 1,
+    RUN_STATE_INTERNAL_ERROR = 2,
+    RUN_STATE_IO_ERROR = 3,
+    RUN_STATE_PAUSED = 4,
+    RUN_STATE_POSTMIGRATE = 5,
+    RUN_STATE_PRELAUNCH = 6,
+    RUN_STATE_FINISH_MIGRATE = 7,
+    RUN_STATE_RESTORE_VM = 8,
+    RUN_STATE_RUNNING = 9,
+    RUN_STATE_SAVE_VM = 10,
+    RUN_STATE_SHUTDOWN = 11,
+    RUN_STATE_SUSPENDED = 12,
+    RUN_STATE_WATCHDOG = 13,
+    RUN_STATE_GUEST_PANICKED = 14,
+    RUN_STATE_MAX = 15,
+} RunState;
+
+typedef struct RunStateList
+{
+    union {
+        RunState value;
+        uint64_t padding;
+    };
+    struct RunStateList *next;
+} RunStateList;
+
+
+typedef struct SnapshotInfo SnapshotInfo;
+
+typedef struct SnapshotInfoList
+{
+    union {
+        SnapshotInfo *value;
+        uint64_t padding;
+    };
+    struct SnapshotInfoList *next;
+} SnapshotInfoList;
+
+
+typedef struct ImageInfoSpecificQCow2 ImageInfoSpecificQCow2;
+
+typedef struct ImageInfoSpecificQCow2List
+{
+    union {
+        ImageInfoSpecificQCow2 *value;
+        uint64_t padding;
+    };
+    struct ImageInfoSpecificQCow2List *next;
+} ImageInfoSpecificQCow2List;
+
+
+typedef struct ImageInfoSpecificVmdk ImageInfoSpecificVmdk;
+
+typedef struct ImageInfoSpecificVmdkList
+{
+    union {
+        ImageInfoSpecificVmdk *value;
+        uint64_t padding;
+    };
+    struct ImageInfoSpecificVmdkList *next;
+} ImageInfoSpecificVmdkList;
+
+
+typedef struct ImageInfoSpecific ImageInfoSpecific;
+
+typedef struct ImageInfoSpecificList
+{
+    union {
+        ImageInfoSpecific *value;
+        uint64_t padding;
+    };
+    struct ImageInfoSpecificList *next;
+} ImageInfoSpecificList;
+
+extern const char *ImageInfoSpecificKind_lookup[];
+typedef enum ImageInfoSpecificKind
+{
+    IMAGE_INFO_SPECIFIC_KIND_QCOW2 = 0,
+    IMAGE_INFO_SPECIFIC_KIND_VMDK = 1,
+    IMAGE_INFO_SPECIFIC_KIND_MAX = 2,
+} ImageInfoSpecificKind;
+
+
+typedef struct ImageInfo ImageInfo;
+
+typedef struct ImageInfoList
+{
+    union {
+        ImageInfo *value;
+        uint64_t padding;
+    };
+    struct ImageInfoList *next;
+} ImageInfoList;
+
+
+typedef struct ImageCheck ImageCheck;
+
+typedef struct ImageCheckList
+{
+    union {
+        ImageCheck *value;
+        uint64_t padding;
+    };
+    struct ImageCheckList *next;
+} ImageCheckList;
+
+
+typedef struct StatusInfo StatusInfo;
+
+typedef struct StatusInfoList
+{
+    union {
+        StatusInfo *value;
+        uint64_t padding;
+    };
+    struct StatusInfoList *next;
+} StatusInfoList;
+
+
+typedef struct UuidInfo UuidInfo;
+
+typedef struct UuidInfoList
+{
+    union {
+        UuidInfo *value;
+        uint64_t padding;
+    };
+    struct UuidInfoList *next;
+} UuidInfoList;
+
+
+typedef struct ChardevInfo ChardevInfo;
+
+typedef struct ChardevInfoList
+{
+    union {
+        ChardevInfo *value;
+        uint64_t padding;
+    };
+    struct ChardevInfoList *next;
+} ChardevInfoList;
+
+extern const char *DataFormat_lookup[];
+typedef enum DataFormat
+{
+    DATA_FORMAT_UTF8 = 0,
+    DATA_FORMAT_BASE64 = 1,
+    DATA_FORMAT_MAX = 2,
+} DataFormat;
+
+typedef struct DataFormatList
+{
+    union {
+        DataFormat value;
+        uint64_t padding;
+    };
+    struct DataFormatList *next;
+} DataFormatList;
+
+
+typedef struct CommandInfo CommandInfo;
+
+typedef struct CommandInfoList
+{
+    union {
+        CommandInfo *value;
+        uint64_t padding;
+    };
+    struct CommandInfoList *next;
+} CommandInfoList;
+
+
+typedef struct EventInfo EventInfo;
+
+typedef struct EventInfoList
+{
+    union {
+        EventInfo *value;
+        uint64_t padding;
+    };
+    struct EventInfoList *next;
+} EventInfoList;
+
+
+typedef struct MigrationStats MigrationStats;
+
+typedef struct MigrationStatsList
+{
+    union {
+        MigrationStats *value;
+        uint64_t padding;
+    };
+    struct MigrationStatsList *next;
+} MigrationStatsList;
+
+
+typedef struct XBZRLECacheStats XBZRLECacheStats;
+
+typedef struct XBZRLECacheStatsList
+{
+    union {
+        XBZRLECacheStats *value;
+        uint64_t padding;
+    };
+    struct XBZRLECacheStatsList *next;
+} XBZRLECacheStatsList;
+
+
+typedef struct MigrationInfo MigrationInfo;
+
+typedef struct MigrationInfoList
+{
+    union {
+        MigrationInfo *value;
+        uint64_t padding;
+    };
+    struct MigrationInfoList *next;
+} MigrationInfoList;
+
+extern const char *MigrationCapability_lookup[];
+typedef enum MigrationCapability
+{
+    MIGRATION_CAPABILITY_XBZRLE = 0,
+    MIGRATION_CAPABILITY_X_RDMA_PIN_ALL = 1,
+    MIGRATION_CAPABILITY_AUTO_CONVERGE = 2,
+    MIGRATION_CAPABILITY_ZERO_BLOCKS = 3,
+    MIGRATION_CAPABILITY_MAX = 4,
+} MigrationCapability;
+
+typedef struct MigrationCapabilityList
+{
+    union {
+        MigrationCapability value;
+        uint64_t padding;
+    };
+    struct MigrationCapabilityList *next;
+} MigrationCapabilityList;
+
+
+typedef struct MigrationCapabilityStatus MigrationCapabilityStatus;
+
+typedef struct MigrationCapabilityStatusList
+{
+    union {
+        MigrationCapabilityStatus *value;
+        uint64_t padding;
+    };
+    struct MigrationCapabilityStatusList *next;
+} MigrationCapabilityStatusList;
+
+
+typedef struct MouseInfo MouseInfo;
+
+typedef struct MouseInfoList
+{
+    union {
+        MouseInfo *value;
+        uint64_t padding;
+    };
+    struct MouseInfoList *next;
+} MouseInfoList;
+
+
+typedef struct CpuInfo CpuInfo;
+
+typedef struct CpuInfoList
+{
+    union {
+        CpuInfo *value;
+        uint64_t padding;
+    };
+    struct CpuInfoList *next;
+} CpuInfoList;
+
+
+typedef struct BlockDeviceInfo BlockDeviceInfo;
+
+typedef struct BlockDeviceInfoList
+{
+    union {
+        BlockDeviceInfo *value;
+        uint64_t padding;
+    };
+    struct BlockDeviceInfoList *next;
+} BlockDeviceInfoList;
+
+extern const char *BlockDeviceIoStatus_lookup[];
+typedef enum BlockDeviceIoStatus
+{
+    BLOCK_DEVICE_IO_STATUS_OK = 0,
+    BLOCK_DEVICE_IO_STATUS_FAILED = 1,
+    BLOCK_DEVICE_IO_STATUS_NOSPACE = 2,
+    BLOCK_DEVICE_IO_STATUS_MAX = 3,
+} BlockDeviceIoStatus;
+
+typedef struct BlockDeviceIoStatusList
+{
+    union {
+        BlockDeviceIoStatus value;
+        uint64_t padding;
+    };
+    struct BlockDeviceIoStatusList *next;
+} BlockDeviceIoStatusList;
+
+
+typedef struct BlockDeviceMapEntry BlockDeviceMapEntry;
+
+typedef struct BlockDeviceMapEntryList
+{
+    union {
+        BlockDeviceMapEntry *value;
+        uint64_t padding;
+    };
+    struct BlockDeviceMapEntryList *next;
+} BlockDeviceMapEntryList;
+
+
+typedef struct BlockDirtyInfo BlockDirtyInfo;
+
+typedef struct BlockDirtyInfoList
+{
+    union {
+        BlockDirtyInfo *value;
+        uint64_t padding;
+    };
+    struct BlockDirtyInfoList *next;
+} BlockDirtyInfoList;
+
+
+typedef struct BlockInfo BlockInfo;
+
+typedef struct BlockInfoList
+{
+    union {
+        BlockInfo *value;
+        uint64_t padding;
+    };
+    struct BlockInfoList *next;
+} BlockInfoList;
+
+
+typedef struct BlockDeviceStats BlockDeviceStats;
+
+typedef struct BlockDeviceStatsList
+{
+    union {
+        BlockDeviceStats *value;
+        uint64_t padding;
+    };
+    struct BlockDeviceStatsList *next;
+} BlockDeviceStatsList;
+
+
+typedef struct BlockStats BlockStats;
+
+typedef struct BlockStatsList
+{
+    union {
+        BlockStats *value;
+        uint64_t padding;
+    };
+    struct BlockStatsList *next;
+} BlockStatsList;
+
+
+typedef struct VncClientInfo VncClientInfo;
+
+typedef struct VncClientInfoList
+{
+    union {
+        VncClientInfo *value;
+        uint64_t padding;
+    };
+    struct VncClientInfoList *next;
+} VncClientInfoList;
+
+
+typedef struct VncInfo VncInfo;
+
+typedef struct VncInfoList
+{
+    union {
+        VncInfo *value;
+        uint64_t padding;
+    };
+    struct VncInfoList *next;
+} VncInfoList;
+
+
+typedef struct SpiceChannel SpiceChannel;
+
+typedef struct SpiceChannelList
+{
+    union {
+        SpiceChannel *value;
+        uint64_t padding;
+    };
+    struct SpiceChannelList *next;
+} SpiceChannelList;
+
+extern const char *SpiceQueryMouseMode_lookup[];
+typedef enum SpiceQueryMouseMode
+{
+    SPICE_QUERY_MOUSE_MODE_CLIENT = 0,
+    SPICE_QUERY_MOUSE_MODE_SERVER = 1,
+    SPICE_QUERY_MOUSE_MODE_UNKNOWN = 2,
+    SPICE_QUERY_MOUSE_MODE_MAX = 3,
+} SpiceQueryMouseMode;
+
+typedef struct SpiceQueryMouseModeList
+{
+    union {
+        SpiceQueryMouseMode value;
+        uint64_t padding;
+    };
+    struct SpiceQueryMouseModeList *next;
+} SpiceQueryMouseModeList;
+
+
+typedef struct SpiceInfo SpiceInfo;
+
+typedef struct SpiceInfoList
+{
+    union {
+        SpiceInfo *value;
+        uint64_t padding;
+    };
+    struct SpiceInfoList *next;
+} SpiceInfoList;
+
+
+typedef struct BalloonInfo BalloonInfo;
+
+typedef struct BalloonInfoList
+{
+    union {
+        BalloonInfo *value;
+        uint64_t padding;
+    };
+    struct BalloonInfoList *next;
+} BalloonInfoList;
+
+
+typedef struct PciMemoryRange PciMemoryRange;
+
+typedef struct PciMemoryRangeList
+{
+    union {
+        PciMemoryRange *value;
+        uint64_t padding;
+    };
+    struct PciMemoryRangeList *next;
+} PciMemoryRangeList;
+
+
+typedef struct PciMemoryRegion PciMemoryRegion;
+
+typedef struct PciMemoryRegionList
+{
+    union {
+        PciMemoryRegion *value;
+        uint64_t padding;
+    };
+    struct PciMemoryRegionList *next;
+} PciMemoryRegionList;
+
+
+typedef struct PciBridgeInfo PciBridgeInfo;
+
+typedef struct PciBridgeInfoList
+{
+    union {
+        PciBridgeInfo *value;
+        uint64_t padding;
+    };
+    struct PciBridgeInfoList *next;
+} PciBridgeInfoList;
+
+
+typedef struct PciDeviceInfo PciDeviceInfo;
+
+typedef struct PciDeviceInfoList
+{
+    union {
+        PciDeviceInfo *value;
+        uint64_t padding;
+    };
+    struct PciDeviceInfoList *next;
+} PciDeviceInfoList;
+
+
+typedef struct PciInfo PciInfo;
+
+typedef struct PciInfoList
+{
+    union {
+        PciInfo *value;
+        uint64_t padding;
+    };
+    struct PciInfoList *next;
+} PciInfoList;
+
+extern const char *BlockdevOnError_lookup[];
+typedef enum BlockdevOnError
+{
+    BLOCKDEV_ON_ERROR_REPORT = 0,
+    BLOCKDEV_ON_ERROR_IGNORE = 1,
+    BLOCKDEV_ON_ERROR_ENOSPC = 2,
+    BLOCKDEV_ON_ERROR_STOP = 3,
+    BLOCKDEV_ON_ERROR_MAX = 4,
+} BlockdevOnError;
+
+typedef struct BlockdevOnErrorList
+{
+    union {
+        BlockdevOnError value;
+        uint64_t padding;
+    };
+    struct BlockdevOnErrorList *next;
+} BlockdevOnErrorList;
+
+extern const char *MirrorSyncMode_lookup[];
+typedef enum MirrorSyncMode
+{
+    MIRROR_SYNC_MODE_TOP = 0,
+    MIRROR_SYNC_MODE_FULL = 1,
+    MIRROR_SYNC_MODE_NONE = 2,
+    MIRROR_SYNC_MODE_MAX = 3,
+} MirrorSyncMode;
+
+typedef struct MirrorSyncModeList
+{
+    union {
+        MirrorSyncMode value;
+        uint64_t padding;
+    };
+    struct MirrorSyncModeList *next;
+} MirrorSyncModeList;
+
+extern const char *BlockJobType_lookup[];
+typedef enum BlockJobType
+{
+    BLOCK_JOB_TYPE_COMMIT = 0,
+    BLOCK_JOB_TYPE_STREAM = 1,
+    BLOCK_JOB_TYPE_MIRROR = 2,
+    BLOCK_JOB_TYPE_BACKUP = 3,
+    BLOCK_JOB_TYPE_MAX = 4,
+} BlockJobType;
+
+typedef struct BlockJobTypeList
+{
+    union {
+        BlockJobType value;
+        uint64_t padding;
+    };
+    struct BlockJobTypeList *next;
+} BlockJobTypeList;
+
+
+typedef struct BlockJobInfo BlockJobInfo;
+
+typedef struct BlockJobInfoList
+{
+    union {
+        BlockJobInfo *value;
+        uint64_t padding;
+    };
+    struct BlockJobInfoList *next;
+} BlockJobInfoList;
+
+extern const char *NewImageMode_lookup[];
+typedef enum NewImageMode
+{
+    NEW_IMAGE_MODE_EXISTING = 0,
+    NEW_IMAGE_MODE_ABSOLUTE_PATHS = 1,
+    NEW_IMAGE_MODE_MAX = 2,
+} NewImageMode;
+
+typedef struct NewImageModeList
+{
+    union {
+        NewImageMode value;
+        uint64_t padding;
+    };
+    struct NewImageModeList *next;
+} NewImageModeList;
+
+
+typedef struct BlockdevSnapshot BlockdevSnapshot;
+
+typedef struct BlockdevSnapshotList
+{
+    union {
+        BlockdevSnapshot *value;
+        uint64_t padding;
+    };
+    struct BlockdevSnapshotList *next;
+} BlockdevSnapshotList;
+
+
+typedef struct BlockdevSnapshotInternal BlockdevSnapshotInternal;
+
+typedef struct BlockdevSnapshotInternalList
+{
+    union {
+        BlockdevSnapshotInternal *value;
+        uint64_t padding;
+    };
+    struct BlockdevSnapshotInternalList *next;
+} BlockdevSnapshotInternalList;
+
+
+typedef struct DriveBackup DriveBackup;
+
+typedef struct DriveBackupList
+{
+    union {
+        DriveBackup *value;
+        uint64_t padding;
+    };
+    struct DriveBackupList *next;
+} DriveBackupList;
+
+
+typedef struct Abort Abort;
+
+typedef struct AbortList
+{
+    union {
+        Abort *value;
+        uint64_t padding;
+    };
+    struct AbortList *next;
+} AbortList;
+
+
+typedef struct TransactionAction TransactionAction;
+
+typedef struct TransactionActionList
+{
+    union {
+        TransactionAction *value;
+        uint64_t padding;
+    };
+    struct TransactionActionList *next;
+} TransactionActionList;
+
+extern const char *TransactionActionKind_lookup[];
+typedef enum TransactionActionKind
+{
+    TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC = 0,
+    TRANSACTION_ACTION_KIND_DRIVE_BACKUP = 1,
+    TRANSACTION_ACTION_KIND_ABORT = 2,
+    TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC = 3,
+    TRANSACTION_ACTION_KIND_MAX = 4,
+} TransactionActionKind;
+
+
+typedef struct ObjectPropertyInfo ObjectPropertyInfo;
+
+typedef struct ObjectPropertyInfoList
+{
+    union {
+        ObjectPropertyInfo *value;
+        uint64_t padding;
+    };
+    struct ObjectPropertyInfoList *next;
+} ObjectPropertyInfoList;
+
+
+typedef struct ObjectTypeInfo ObjectTypeInfo;
+
+typedef struct ObjectTypeInfoList
+{
+    union {
+        ObjectTypeInfo *value;
+        uint64_t padding;
+    };
+    struct ObjectTypeInfoList *next;
+} ObjectTypeInfoList;
+
+
+typedef struct DevicePropertyInfo DevicePropertyInfo;
+
+typedef struct DevicePropertyInfoList
+{
+    union {
+        DevicePropertyInfo *value;
+        uint64_t padding;
+    };
+    struct DevicePropertyInfoList *next;
+} DevicePropertyInfoList;
+
+
+typedef struct NetdevNoneOptions NetdevNoneOptions;
+
+typedef struct NetdevNoneOptionsList
+{
+    union {
+        NetdevNoneOptions *value;
+        uint64_t padding;
+    };
+    struct NetdevNoneOptionsList *next;
+} NetdevNoneOptionsList;
+
+
+typedef struct NetLegacyNicOptions NetLegacyNicOptions;
+
+typedef struct NetLegacyNicOptionsList
+{
+    union {
+        NetLegacyNicOptions *value;
+        uint64_t padding;
+    };
+    struct NetLegacyNicOptionsList *next;
+} NetLegacyNicOptionsList;
+
+
+typedef struct String String;
+
+typedef struct StringList
+{
+    union {
+        String *value;
+        uint64_t padding;
+    };
+    struct StringList *next;
+} StringList;
+
+
+typedef struct NetdevUserOptions NetdevUserOptions;
+
+typedef struct NetdevUserOptionsList
+{
+    union {
+        NetdevUserOptions *value;
+        uint64_t padding;
+    };
+    struct NetdevUserOptionsList *next;
+} NetdevUserOptionsList;
+
+
+typedef struct NetdevTapOptions NetdevTapOptions;
+
+typedef struct NetdevTapOptionsList
+{
+    union {
+        NetdevTapOptions *value;
+        uint64_t padding;
+    };
+    struct NetdevTapOptionsList *next;
+} NetdevTapOptionsList;
+
+
+typedef struct NetdevSocketOptions NetdevSocketOptions;
+
+typedef struct NetdevSocketOptionsList
+{
+    union {
+        NetdevSocketOptions *value;
+        uint64_t padding;
+    };
+    struct NetdevSocketOptionsList *next;
+} NetdevSocketOptionsList;
+
+
+typedef struct NetdevVdeOptions NetdevVdeOptions;
+
+typedef struct NetdevVdeOptionsList
+{
+    union {
+        NetdevVdeOptions *value;
+        uint64_t padding;
+    };
+    struct NetdevVdeOptionsList *next;
+} NetdevVdeOptionsList;
+
+
+typedef struct NetdevDumpOptions NetdevDumpOptions;
+
+typedef struct NetdevDumpOptionsList
+{
+    union {
+        NetdevDumpOptions *value;
+        uint64_t padding;
+    };
+    struct NetdevDumpOptionsList *next;
+} NetdevDumpOptionsList;
+
+
+typedef struct NetdevBridgeOptions NetdevBridgeOptions;
+
+typedef struct NetdevBridgeOptionsList
+{
+    union {
+        NetdevBridgeOptions *value;
+        uint64_t padding;
+    };
+    struct NetdevBridgeOptionsList *next;
+} NetdevBridgeOptionsList;
+
+
+typedef struct NetdevHubPortOptions NetdevHubPortOptions;
+
+typedef struct NetdevHubPortOptionsList
+{
+    union {
+        NetdevHubPortOptions *value;
+        uint64_t padding;
+    };
+    struct NetdevHubPortOptionsList *next;
+} NetdevHubPortOptionsList;
+
+
+typedef struct NetdevNetmapOptions NetdevNetmapOptions;
+
+typedef struct NetdevNetmapOptionsList
+{
+    union {
+        NetdevNetmapOptions *value;
+        uint64_t padding;
+    };
+    struct NetdevNetmapOptionsList *next;
+} NetdevNetmapOptionsList;
+
+
+typedef struct NetClientOptions NetClientOptions;
+
+typedef struct NetClientOptionsList
+{
+    union {
+        NetClientOptions *value;
+        uint64_t padding;
+    };
+    struct NetClientOptionsList *next;
+} NetClientOptionsList;
+
+extern const char *NetClientOptionsKind_lookup[];
+typedef enum NetClientOptionsKind
+{
+    NET_CLIENT_OPTIONS_KIND_NONE = 0,
+    NET_CLIENT_OPTIONS_KIND_NIC = 1,
+    NET_CLIENT_OPTIONS_KIND_USER = 2,
+    NET_CLIENT_OPTIONS_KIND_TAP = 3,
+    NET_CLIENT_OPTIONS_KIND_SOCKET = 4,
+    NET_CLIENT_OPTIONS_KIND_VDE = 5,
+    NET_CLIENT_OPTIONS_KIND_DUMP = 6,
+    NET_CLIENT_OPTIONS_KIND_BRIDGE = 7,
+    NET_CLIENT_OPTIONS_KIND_HUBPORT = 8,
+    NET_CLIENT_OPTIONS_KIND_NETMAP = 9,
+    NET_CLIENT_OPTIONS_KIND_MAX = 10,
+} NetClientOptionsKind;
+
+
+typedef struct NetLegacy NetLegacy;
+
+typedef struct NetLegacyList
+{
+    union {
+        NetLegacy *value;
+        uint64_t padding;
+    };
+    struct NetLegacyList *next;
+} NetLegacyList;
+
+
+typedef struct Netdev Netdev;
+
+typedef struct NetdevList
+{
+    union {
+        Netdev *value;
+        uint64_t padding;
+    };
+    struct NetdevList *next;
+} NetdevList;
+
+
+typedef struct InetSocketAddress InetSocketAddress;
+
+typedef struct InetSocketAddressList
+{
+    union {
+        InetSocketAddress *value;
+        uint64_t padding;
+    };
+    struct InetSocketAddressList *next;
+} InetSocketAddressList;
+
+
+typedef struct UnixSocketAddress UnixSocketAddress;
+
+typedef struct UnixSocketAddressList
+{
+    union {
+        UnixSocketAddress *value;
+        uint64_t padding;
+    };
+    struct UnixSocketAddressList *next;
+} UnixSocketAddressList;
+
+
+typedef struct SocketAddress SocketAddress;
+
+typedef struct SocketAddressList
+{
+    union {
+        SocketAddress *value;
+        uint64_t padding;
+    };
+    struct SocketAddressList *next;
+} SocketAddressList;
+
+extern const char *SocketAddressKind_lookup[];
+typedef enum SocketAddressKind
+{
+    SOCKET_ADDRESS_KIND_INET = 0,
+    SOCKET_ADDRESS_KIND_UNIX = 1,
+    SOCKET_ADDRESS_KIND_FD = 2,
+    SOCKET_ADDRESS_KIND_MAX = 3,
+} SocketAddressKind;
+
+
+typedef struct MachineInfo MachineInfo;
+
+typedef struct MachineInfoList
+{
+    union {
+        MachineInfo *value;
+        uint64_t padding;
+    };
+    struct MachineInfoList *next;
+} MachineInfoList;
+
+
+typedef struct CpuDefinitionInfo CpuDefinitionInfo;
+
+typedef struct CpuDefinitionInfoList
+{
+    union {
+        CpuDefinitionInfo *value;
+        uint64_t padding;
+    };
+    struct CpuDefinitionInfoList *next;
+} CpuDefinitionInfoList;
+
+
+typedef struct AddfdInfo AddfdInfo;
+
+typedef struct AddfdInfoList
+{
+    union {
+        AddfdInfo *value;
+        uint64_t padding;
+    };
+    struct AddfdInfoList *next;
+} AddfdInfoList;
+
+
+typedef struct FdsetFdInfo FdsetFdInfo;
+
+typedef struct FdsetFdInfoList
+{
+    union {
+        FdsetFdInfo *value;
+        uint64_t padding;
+    };
+    struct FdsetFdInfoList *next;
+} FdsetFdInfoList;
+
+
+typedef struct FdsetInfo FdsetInfo;
+
+typedef struct FdsetInfoList
+{
+    union {
+        FdsetInfo *value;
+        uint64_t padding;
+    };
+    struct FdsetInfoList *next;
+} FdsetInfoList;
+
+
+typedef struct TargetInfo TargetInfo;
+
+typedef struct TargetInfoList
+{
+    union {
+        TargetInfo *value;
+        uint64_t padding;
+    };
+    struct TargetInfoList *next;
+} TargetInfoList;
+
+extern const char *QKeyCode_lookup[];
+typedef enum QKeyCode
+{
+    Q_KEY_CODE_SHIFT = 0,
+    Q_KEY_CODE_SHIFT_R = 1,
+    Q_KEY_CODE_ALT = 2,
+    Q_KEY_CODE_ALT_R = 3,
+    Q_KEY_CODE_ALTGR = 4,
+    Q_KEY_CODE_ALTGR_R = 5,
+    Q_KEY_CODE_CTRL = 6,
+    Q_KEY_CODE_CTRL_R = 7,
+    Q_KEY_CODE_MENU = 8,
+    Q_KEY_CODE_ESC = 9,
+    Q_KEY_CODE_1 = 10,
+    Q_KEY_CODE_2 = 11,
+    Q_KEY_CODE_3 = 12,
+    Q_KEY_CODE_4 = 13,
+    Q_KEY_CODE_5 = 14,
+    Q_KEY_CODE_6 = 15,
+    Q_KEY_CODE_7 = 16,
+    Q_KEY_CODE_8 = 17,
+    Q_KEY_CODE_9 = 18,
+    Q_KEY_CODE_0 = 19,
+    Q_KEY_CODE_MINUS = 20,
+    Q_KEY_CODE_EQUAL = 21,
+    Q_KEY_CODE_BACKSPACE = 22,
+    Q_KEY_CODE_TAB = 23,
+    Q_KEY_CODE_Q = 24,
+    Q_KEY_CODE_W = 25,
+    Q_KEY_CODE_E = 26,
+    Q_KEY_CODE_R = 27,
+    Q_KEY_CODE_T = 28,
+    Q_KEY_CODE_Y = 29,
+    Q_KEY_CODE_U = 30,
+    Q_KEY_CODE_I = 31,
+    Q_KEY_CODE_O = 32,
+    Q_KEY_CODE_P = 33,
+    Q_KEY_CODE_BRACKET_LEFT = 34,
+    Q_KEY_CODE_BRACKET_RIGHT = 35,
+    Q_KEY_CODE_RET = 36,
+    Q_KEY_CODE_A = 37,
+    Q_KEY_CODE_S = 38,
+    Q_KEY_CODE_D = 39,
+    Q_KEY_CODE_F = 40,
+    Q_KEY_CODE_G = 41,
+    Q_KEY_CODE_H = 42,
+    Q_KEY_CODE_J = 43,
+    Q_KEY_CODE_K = 44,
+    Q_KEY_CODE_L = 45,
+    Q_KEY_CODE_SEMICOLON = 46,
+    Q_KEY_CODE_APOSTROPHE = 47,
+    Q_KEY_CODE_GRAVE_ACCENT = 48,
+    Q_KEY_CODE_BACKSLASH = 49,
+    Q_KEY_CODE_Z = 50,
+    Q_KEY_CODE_X = 51,
+    Q_KEY_CODE_C = 52,
+    Q_KEY_CODE_V = 53,
+    Q_KEY_CODE_B = 54,
+    Q_KEY_CODE_N = 55,
+    Q_KEY_CODE_M = 56,
+    Q_KEY_CODE_COMMA = 57,
+    Q_KEY_CODE_DOT = 58,
+    Q_KEY_CODE_SLASH = 59,
+    Q_KEY_CODE_ASTERISK = 60,
+    Q_KEY_CODE_SPC = 61,
+    Q_KEY_CODE_CAPS_LOCK = 62,
+    Q_KEY_CODE_F1 = 63,
+    Q_KEY_CODE_F2 = 64,
+    Q_KEY_CODE_F3 = 65,
+    Q_KEY_CODE_F4 = 66,
+    Q_KEY_CODE_F5 = 67,
+    Q_KEY_CODE_F6 = 68,
+    Q_KEY_CODE_F7 = 69,
+    Q_KEY_CODE_F8 = 70,
+    Q_KEY_CODE_F9 = 71,
+    Q_KEY_CODE_F10 = 72,
+    Q_KEY_CODE_NUM_LOCK = 73,
+    Q_KEY_CODE_SCROLL_LOCK = 74,
+    Q_KEY_CODE_KP_DIVIDE = 75,
+    Q_KEY_CODE_KP_MULTIPLY = 76,
+    Q_KEY_CODE_KP_SUBTRACT = 77,
+    Q_KEY_CODE_KP_ADD = 78,
+    Q_KEY_CODE_KP_ENTER = 79,
+    Q_KEY_CODE_KP_DECIMAL = 80,
+    Q_KEY_CODE_SYSRQ = 81,
+    Q_KEY_CODE_KP_0 = 82,
+    Q_KEY_CODE_KP_1 = 83,
+    Q_KEY_CODE_KP_2 = 84,
+    Q_KEY_CODE_KP_3 = 85,
+    Q_KEY_CODE_KP_4 = 86,
+    Q_KEY_CODE_KP_5 = 87,
+    Q_KEY_CODE_KP_6 = 88,
+    Q_KEY_CODE_KP_7 = 89,
+    Q_KEY_CODE_KP_8 = 90,
+    Q_KEY_CODE_KP_9 = 91,
+    Q_KEY_CODE_LESS = 92,
+    Q_KEY_CODE_F11 = 93,
+    Q_KEY_CODE_F12 = 94,
+    Q_KEY_CODE_PRINT = 95,
+    Q_KEY_CODE_HOME = 96,
+    Q_KEY_CODE_PGUP = 97,
+    Q_KEY_CODE_PGDN = 98,
+    Q_KEY_CODE_END = 99,
+    Q_KEY_CODE_LEFT = 100,
+    Q_KEY_CODE_UP = 101,
+    Q_KEY_CODE_DOWN = 102,
+    Q_KEY_CODE_RIGHT = 103,
+    Q_KEY_CODE_INSERT = 104,
+    Q_KEY_CODE_DELETE = 105,
+    Q_KEY_CODE_STOP = 106,
+    Q_KEY_CODE_AGAIN = 107,
+    Q_KEY_CODE_PROPS = 108,
+    Q_KEY_CODE_UNDO = 109,
+    Q_KEY_CODE_FRONT = 110,
+    Q_KEY_CODE_COPY = 111,
+    Q_KEY_CODE_OPEN = 112,
+    Q_KEY_CODE_PASTE = 113,
+    Q_KEY_CODE_FIND = 114,
+    Q_KEY_CODE_CUT = 115,
+    Q_KEY_CODE_LF = 116,
+    Q_KEY_CODE_HELP = 117,
+    Q_KEY_CODE_META_L = 118,
+    Q_KEY_CODE_META_R = 119,
+    Q_KEY_CODE_COMPOSE = 120,
+    Q_KEY_CODE_MAX = 121,
+} QKeyCode;
+
+typedef struct QKeyCodeList
+{
+    union {
+        QKeyCode value;
+        uint64_t padding;
+    };
+    struct QKeyCodeList *next;
+} QKeyCodeList;
+
+
+typedef struct KeyValue KeyValue;
+
+typedef struct KeyValueList
+{
+    union {
+        KeyValue *value;
+        uint64_t padding;
+    };
+    struct KeyValueList *next;
+} KeyValueList;
+
+extern const char *KeyValueKind_lookup[];
+typedef enum KeyValueKind
+{
+    KEY_VALUE_KIND_NUMBER = 0,
+    KEY_VALUE_KIND_QCODE = 1,
+    KEY_VALUE_KIND_MAX = 2,
+} KeyValueKind;
+
+
+typedef struct ChardevFile ChardevFile;
+
+typedef struct ChardevFileList
+{
+    union {
+        ChardevFile *value;
+        uint64_t padding;
+    };
+    struct ChardevFileList *next;
+} ChardevFileList;
+
+
+typedef struct ChardevHostdev ChardevHostdev;
+
+typedef struct ChardevHostdevList
+{
+    union {
+        ChardevHostdev *value;
+        uint64_t padding;
+    };
+    struct ChardevHostdevList *next;
+} ChardevHostdevList;
+
+
+typedef struct ChardevSocket ChardevSocket;
+
+typedef struct ChardevSocketList
+{
+    union {
+        ChardevSocket *value;
+        uint64_t padding;
+    };
+    struct ChardevSocketList *next;
+} ChardevSocketList;
+
+
+typedef struct ChardevUdp ChardevUdp;
+
+typedef struct ChardevUdpList
+{
+    union {
+        ChardevUdp *value;
+        uint64_t padding;
+    };
+    struct ChardevUdpList *next;
+} ChardevUdpList;
+
+
+typedef struct ChardevMux ChardevMux;
+
+typedef struct ChardevMuxList
+{
+    union {
+        ChardevMux *value;
+        uint64_t padding;
+    };
+    struct ChardevMuxList *next;
+} ChardevMuxList;
+
+
+typedef struct ChardevStdio ChardevStdio;
+
+typedef struct ChardevStdioList
+{
+    union {
+        ChardevStdio *value;
+        uint64_t padding;
+    };
+    struct ChardevStdioList *next;
+} ChardevStdioList;
+
+
+typedef struct ChardevSpiceChannel ChardevSpiceChannel;
+
+typedef struct ChardevSpiceChannelList
+{
+    union {
+        ChardevSpiceChannel *value;
+        uint64_t padding;
+    };
+    struct ChardevSpiceChannelList *next;
+} ChardevSpiceChannelList;
+
+
+typedef struct ChardevSpicePort ChardevSpicePort;
+
+typedef struct ChardevSpicePortList
+{
+    union {
+        ChardevSpicePort *value;
+        uint64_t padding;
+    };
+    struct ChardevSpicePortList *next;
+} ChardevSpicePortList;
+
+
+typedef struct ChardevVC ChardevVC;
+
+typedef struct ChardevVCList
+{
+    union {
+        ChardevVC *value;
+        uint64_t padding;
+    };
+    struct ChardevVCList *next;
+} ChardevVCList;
+
+
+typedef struct ChardevRingbuf ChardevRingbuf;
+
+typedef struct ChardevRingbufList
+{
+    union {
+        ChardevRingbuf *value;
+        uint64_t padding;
+    };
+    struct ChardevRingbufList *next;
+} ChardevRingbufList;
+
+
+typedef struct ChardevDummy ChardevDummy;
+
+typedef struct ChardevDummyList
+{
+    union {
+        ChardevDummy *value;
+        uint64_t padding;
+    };
+    struct ChardevDummyList *next;
+} ChardevDummyList;
+
+
+typedef struct ChardevBackend ChardevBackend;
+
+typedef struct ChardevBackendList
+{
+    union {
+        ChardevBackend *value;
+        uint64_t padding;
+    };
+    struct ChardevBackendList *next;
+} ChardevBackendList;
+
+extern const char *ChardevBackendKind_lookup[];
+typedef enum ChardevBackendKind
+{
+    CHARDEV_BACKEND_KIND_FILE = 0,
+    CHARDEV_BACKEND_KIND_SERIAL = 1,
+    CHARDEV_BACKEND_KIND_PARALLEL = 2,
+    CHARDEV_BACKEND_KIND_PIPE = 3,
+    CHARDEV_BACKEND_KIND_SOCKET = 4,
+    CHARDEV_BACKEND_KIND_UDP = 5,
+    CHARDEV_BACKEND_KIND_PTY = 6,
+    CHARDEV_BACKEND_KIND_NULL = 7,
+    CHARDEV_BACKEND_KIND_MUX = 8,
+    CHARDEV_BACKEND_KIND_MSMOUSE = 9,
+    CHARDEV_BACKEND_KIND_BRAILLE = 10,
+    CHARDEV_BACKEND_KIND_STDIO = 11,
+    CHARDEV_BACKEND_KIND_CONSOLE = 12,
+    CHARDEV_BACKEND_KIND_SPICEVMC = 13,
+    CHARDEV_BACKEND_KIND_SPICEPORT = 14,
+    CHARDEV_BACKEND_KIND_VC = 15,
+    CHARDEV_BACKEND_KIND_RINGBUF = 16,
+    CHARDEV_BACKEND_KIND_MEMORY = 17,
+    CHARDEV_BACKEND_KIND_MAX = 18,
+} ChardevBackendKind;
+
+
+typedef struct ChardevReturn ChardevReturn;
+
+typedef struct ChardevReturnList
+{
+    union {
+        ChardevReturn *value;
+        uint64_t padding;
+    };
+    struct ChardevReturnList *next;
+} ChardevReturnList;
+
+extern const char *TpmModel_lookup[];
+typedef enum TpmModel
+{
+    TPM_MODEL_TPM_TIS = 0,
+    TPM_MODEL_MAX = 1,
+} TpmModel;
+
+typedef struct TpmModelList
+{
+    union {
+        TpmModel value;
+        uint64_t padding;
+    };
+    struct TpmModelList *next;
+} TpmModelList;
+
+extern const char *TpmType_lookup[];
+typedef enum TpmType
+{
+    TPM_TYPE_PASSTHROUGH = 0,
+    TPM_TYPE_MAX = 1,
+} TpmType;
+
+typedef struct TpmTypeList
+{
+    union {
+        TpmType value;
+        uint64_t padding;
+    };
+    struct TpmTypeList *next;
+} TpmTypeList;
+
+
+typedef struct TPMPassthroughOptions TPMPassthroughOptions;
+
+typedef struct TPMPassthroughOptionsList
+{
+    union {
+        TPMPassthroughOptions *value;
+        uint64_t padding;
+    };
+    struct TPMPassthroughOptionsList *next;
+} TPMPassthroughOptionsList;
+
+
+typedef struct TpmTypeOptions TpmTypeOptions;
+
+typedef struct TpmTypeOptionsList
+{
+    union {
+        TpmTypeOptions *value;
+        uint64_t padding;
+    };
+    struct TpmTypeOptionsList *next;
+} TpmTypeOptionsList;
+
+extern const char *TpmTypeOptionsKind_lookup[];
+typedef enum TpmTypeOptionsKind
+{
+    TPM_TYPE_OPTIONS_KIND_PASSTHROUGH = 0,
+    TPM_TYPE_OPTIONS_KIND_MAX = 1,
+} TpmTypeOptionsKind;
+
+
+typedef struct TPMInfo TPMInfo;
+
+typedef struct TPMInfoList
+{
+    union {
+        TPMInfo *value;
+        uint64_t padding;
+    };
+    struct TPMInfoList *next;
+} TPMInfoList;
+
+
+typedef struct AcpiTableOptions AcpiTableOptions;
+
+typedef struct AcpiTableOptionsList
+{
+    union {
+        AcpiTableOptions *value;
+        uint64_t padding;
+    };
+    struct AcpiTableOptionsList *next;
+} AcpiTableOptionsList;
+
+extern const char *CommandLineParameterType_lookup[];
+typedef enum CommandLineParameterType
+{
+    COMMAND_LINE_PARAMETER_TYPE_STRING = 0,
+    COMMAND_LINE_PARAMETER_TYPE_BOOLEAN = 1,
+    COMMAND_LINE_PARAMETER_TYPE_NUMBER = 2,
+    COMMAND_LINE_PARAMETER_TYPE_SIZE = 3,
+    COMMAND_LINE_PARAMETER_TYPE_MAX = 4,
+} CommandLineParameterType;
+
+typedef struct CommandLineParameterTypeList
+{
+    union {
+        CommandLineParameterType value;
+        uint64_t padding;
+    };
+    struct CommandLineParameterTypeList *next;
+} CommandLineParameterTypeList;
+
+
+typedef struct CommandLineParameterInfo CommandLineParameterInfo;
+
+typedef struct CommandLineParameterInfoList
+{
+    union {
+        CommandLineParameterInfo *value;
+        uint64_t padding;
+    };
+    struct CommandLineParameterInfoList *next;
+} CommandLineParameterInfoList;
+
+
+typedef struct CommandLineOptionInfo CommandLineOptionInfo;
+
+typedef struct CommandLineOptionInfoList
+{
+    union {
+        CommandLineOptionInfo *value;
+        uint64_t padding;
+    };
+    struct CommandLineOptionInfoList *next;
+} CommandLineOptionInfoList;
+
+extern const char *X86CPURegister32_lookup[];
+typedef enum X86CPURegister32
+{
+    X86_C_P_U_REGISTER32_EAX = 0,
+    X86_C_P_U_REGISTER32_EBX = 1,
+    X86_C_P_U_REGISTER32_ECX = 2,
+    X86_C_P_U_REGISTER32_EDX = 3,
+    X86_C_P_U_REGISTER32_ESP = 4,
+    X86_C_P_U_REGISTER32_EBP = 5,
+    X86_C_P_U_REGISTER32_ESI = 6,
+    X86_C_P_U_REGISTER32_EDI = 7,
+    X86_C_P_U_REGISTER32_MAX = 8,
+} X86CPURegister32;
+
+typedef struct X86CPURegister32List
+{
+    union {
+        X86CPURegister32 value;
+        uint64_t padding;
+    };
+    struct X86CPURegister32List *next;
+} X86CPURegister32List;
+
+
+typedef struct X86CPUFeatureWordInfo X86CPUFeatureWordInfo;
+
+typedef struct X86CPUFeatureWordInfoList
+{
+    union {
+        X86CPUFeatureWordInfo *value;
+        uint64_t padding;
+    };
+    struct X86CPUFeatureWordInfoList *next;
+} X86CPUFeatureWordInfoList;
+
+extern const char *RxState_lookup[];
+typedef enum RxState
+{
+    RX_STATE_NORMAL = 0,
+    RX_STATE_NONE = 1,
+    RX_STATE_ALL = 2,
+    RX_STATE_MAX = 3,
+} RxState;
+
+typedef struct RxStateList
+{
+    union {
+        RxState value;
+        uint64_t padding;
+    };
+    struct RxStateList *next;
+} RxStateList;
+
+
+typedef struct RxFilterInfo RxFilterInfo;
+
+typedef struct RxFilterInfoList
+{
+    union {
+        RxFilterInfo *value;
+        uint64_t padding;
+    };
+    struct RxFilterInfoList *next;
+} RxFilterInfoList;
+
+extern const char *BlockdevDiscardOptions_lookup[];
+typedef enum BlockdevDiscardOptions
+{
+    BLOCKDEV_DISCARD_OPTIONS_IGNORE = 0,
+    BLOCKDEV_DISCARD_OPTIONS_UNMAP = 1,
+    BLOCKDEV_DISCARD_OPTIONS_MAX = 2,
+} BlockdevDiscardOptions;
+
+typedef struct BlockdevDiscardOptionsList
+{
+    union {
+        BlockdevDiscardOptions value;
+        uint64_t padding;
+    };
+    struct BlockdevDiscardOptionsList *next;
+} BlockdevDiscardOptionsList;
+
+extern const char *BlockdevAioOptions_lookup[];
+typedef enum BlockdevAioOptions
+{
+    BLOCKDEV_AIO_OPTIONS_THREADS = 0,
+    BLOCKDEV_AIO_OPTIONS_NATIVE = 1,
+    BLOCKDEV_AIO_OPTIONS_MAX = 2,
+} BlockdevAioOptions;
+
+typedef struct BlockdevAioOptionsList
+{
+    union {
+        BlockdevAioOptions value;
+        uint64_t padding;
+    };
+    struct BlockdevAioOptionsList *next;
+} BlockdevAioOptionsList;
+
+
+typedef struct BlockdevCacheOptions BlockdevCacheOptions;
+
+typedef struct BlockdevCacheOptionsList
+{
+    union {
+        BlockdevCacheOptions *value;
+        uint64_t padding;
+    };
+    struct BlockdevCacheOptionsList *next;
+} BlockdevCacheOptionsList;
+
+
+typedef struct BlockdevOptionsBase BlockdevOptionsBase;
+
+typedef struct BlockdevOptionsBaseList
+{
+    union {
+        BlockdevOptionsBase *value;
+        uint64_t padding;
+    };
+    struct BlockdevOptionsBaseList *next;
+} BlockdevOptionsBaseList;
+
+
+typedef struct BlockdevOptionsFile BlockdevOptionsFile;
+
+typedef struct BlockdevOptionsFileList
+{
+    union {
+        BlockdevOptionsFile *value;
+        uint64_t padding;
+    };
+    struct BlockdevOptionsFileList *next;
+} BlockdevOptionsFileList;
+
+
+typedef struct BlockdevOptionsVVFAT BlockdevOptionsVVFAT;
+
+typedef struct BlockdevOptionsVVFATList
+{
+    union {
+        BlockdevOptionsVVFAT *value;
+        uint64_t padding;
+    };
+    struct BlockdevOptionsVVFATList *next;
+} BlockdevOptionsVVFATList;
+
+
+typedef struct BlockdevOptionsGenericFormat BlockdevOptionsGenericFormat;
+
+typedef struct BlockdevOptionsGenericFormatList
+{
+    union {
+        BlockdevOptionsGenericFormat *value;
+        uint64_t padding;
+    };
+    struct BlockdevOptionsGenericFormatList *next;
+} BlockdevOptionsGenericFormatList;
+
+
+typedef struct BlockdevOptionsGenericCOWFormat BlockdevOptionsGenericCOWFormat;
+
+typedef struct BlockdevOptionsGenericCOWFormatList
+{
+    union {
+        BlockdevOptionsGenericCOWFormat *value;
+        uint64_t padding;
+    };
+    struct BlockdevOptionsGenericCOWFormatList *next;
+} BlockdevOptionsGenericCOWFormatList;
+
+
+typedef struct BlockdevOptionsQcow2 BlockdevOptionsQcow2;
+
+typedef struct BlockdevOptionsQcow2List
+{
+    union {
+        BlockdevOptionsQcow2 *value;
+        uint64_t padding;
+    };
+    struct BlockdevOptionsQcow2List *next;
+} BlockdevOptionsQcow2List;
+
+
+typedef struct BlockdevOptions BlockdevOptions;
+
+typedef struct BlockdevOptionsList
+{
+    union {
+        BlockdevOptions *value;
+        uint64_t padding;
+    };
+    struct BlockdevOptionsList *next;
+} BlockdevOptionsList;
+
+extern const char *BlockdevOptionsKind_lookup[];
+typedef enum BlockdevOptionsKind
+{
+    BLOCKDEV_OPTIONS_KIND_FILE = 0,
+    BLOCKDEV_OPTIONS_KIND_HTTP = 1,
+    BLOCKDEV_OPTIONS_KIND_HTTPS = 2,
+    BLOCKDEV_OPTIONS_KIND_FTP = 3,
+    BLOCKDEV_OPTIONS_KIND_FTPS = 4,
+    BLOCKDEV_OPTIONS_KIND_TFTP = 5,
+    BLOCKDEV_OPTIONS_KIND_VVFAT = 6,
+    BLOCKDEV_OPTIONS_KIND_BOCHS = 7,
+    BLOCKDEV_OPTIONS_KIND_CLOOP = 8,
+    BLOCKDEV_OPTIONS_KIND_COW = 9,
+    BLOCKDEV_OPTIONS_KIND_DMG = 10,
+    BLOCKDEV_OPTIONS_KIND_PARALLELS = 11,
+    BLOCKDEV_OPTIONS_KIND_QCOW = 12,
+    BLOCKDEV_OPTIONS_KIND_QCOW2 = 13,
+    BLOCKDEV_OPTIONS_KIND_QED = 14,
+    BLOCKDEV_OPTIONS_KIND_RAW = 15,
+    BLOCKDEV_OPTIONS_KIND_VDI = 16,
+    BLOCKDEV_OPTIONS_KIND_VHDX = 17,
+    BLOCKDEV_OPTIONS_KIND_VMDK = 18,
+    BLOCKDEV_OPTIONS_KIND_VPC = 19,
+    BLOCKDEV_OPTIONS_KIND_MAX = 20,
+} BlockdevOptionsKind;
+
+
+typedef struct BlockdevRef BlockdevRef;
+
+typedef struct BlockdevRefList
+{
+    union {
+        BlockdevRef *value;
+        uint64_t padding;
+    };
+    struct BlockdevRefList *next;
+} BlockdevRefList;
+
+extern const char *BlockdevRefKind_lookup[];
+typedef enum BlockdevRefKind
+{
+    BLOCKDEV_REF_KIND_DEFINITION = 0,
+    BLOCKDEV_REF_KIND_REFERENCE = 1,
+    BLOCKDEV_REF_KIND_MAX = 2,
+} BlockdevRefKind;
+
+#ifndef QAPI_TYPES_BUILTIN_CLEANUP_DECL_H
+#define QAPI_TYPES_BUILTIN_CLEANUP_DECL_H
+
+void qapi_free_strList(strList * obj);
+void qapi_free_intList(intList * obj);
+void qapi_free_numberList(numberList * obj);
+void qapi_free_boolList(boolList * obj);
+void qapi_free_int8List(int8List * obj);
+void qapi_free_int16List(int16List * obj);
+void qapi_free_int32List(int32List * obj);
+void qapi_free_int64List(int64List * obj);
+void qapi_free_uint8List(uint8List * obj);
+void qapi_free_uint16List(uint16List * obj);
+void qapi_free_uint32List(uint32List * obj);
+void qapi_free_uint64List(uint64List * obj);
+
+#endif /* QAPI_TYPES_BUILTIN_CLEANUP_DECL_H */
+
+
+void qapi_free_ErrorClassList(ErrorClassList * obj);
+
+struct NameInfo
+{
+    bool has_name;
+    char * name;
+};
+
+void qapi_free_NameInfoList(NameInfoList * obj);
+void qapi_free_NameInfo(NameInfo * obj);
+
+struct VersionInfo
+{
+    struct 
+    {
+        int64_t major;
+        int64_t minor;
+        int64_t micro;
+    } qemu;
+    char * package;
+};
+
+void qapi_free_VersionInfoList(VersionInfoList * obj);
+void qapi_free_VersionInfo(VersionInfo * obj);
+
+struct KvmInfo
+{
+    bool enabled;
+    bool present;
+};
+
+void qapi_free_KvmInfoList(KvmInfoList * obj);
+void qapi_free_KvmInfo(KvmInfo * obj);
+
+void qapi_free_RunStateList(RunStateList * obj);
+
+struct SnapshotInfo
+{
+    char * id;
+    char * name;
+    int64_t vm_state_size;
+    int64_t date_sec;
+    int64_t date_nsec;
+    int64_t vm_clock_sec;
+    int64_t vm_clock_nsec;
+};
+
+void qapi_free_SnapshotInfoList(SnapshotInfoList * obj);
+void qapi_free_SnapshotInfo(SnapshotInfo * obj);
+
+struct ImageInfoSpecificQCow2
+{
+    char * compat;
+    bool has_lazy_refcounts;
+    bool lazy_refcounts;
+};
+
+void qapi_free_ImageInfoSpecificQCow2List(ImageInfoSpecificQCow2List * obj);
+void qapi_free_ImageInfoSpecificQCow2(ImageInfoSpecificQCow2 * obj);
+
+struct ImageInfoSpecificVmdk
+{
+    char * create_type;
+    int64_t cid;
+    int64_t parent_cid;
+    ImageInfoList * extents;
+};
+
+void qapi_free_ImageInfoSpecificVmdkList(ImageInfoSpecificVmdkList * obj);
+void qapi_free_ImageInfoSpecificVmdk(ImageInfoSpecificVmdk * obj);
+
+struct ImageInfoSpecific
+{
+    ImageInfoSpecificKind kind;
+    union {
+        void *data;
+        ImageInfoSpecificQCow2 * qcow2;
+        ImageInfoSpecificVmdk * vmdk;
+    };
+};
+void qapi_free_ImageInfoSpecificList(ImageInfoSpecificList * obj);
+void qapi_free_ImageInfoSpecific(ImageInfoSpecific * obj);
+
+struct ImageInfo
+{
+    char * filename;
+    char * format;
+    bool has_dirty_flag;
+    bool dirty_flag;
+    bool has_actual_size;
+    int64_t actual_size;
+    int64_t virtual_size;
+    bool has_cluster_size;
+    int64_t cluster_size;
+    bool has_encrypted;
+    bool encrypted;
+    bool has_compressed;
+    bool compressed;
+    bool has_backing_filename;
+    char * backing_filename;
+    bool has_full_backing_filename;
+    char * full_backing_filename;
+    bool has_backing_filename_format;
+    char * backing_filename_format;
+    bool has_snapshots;
+    SnapshotInfoList * snapshots;
+    bool has_backing_image;
+    ImageInfo * backing_image;
+    bool has_format_specific;
+    ImageInfoSpecific * format_specific;
+};
+
+void qapi_free_ImageInfoList(ImageInfoList * obj);
+void qapi_free_ImageInfo(ImageInfo * obj);
+
+struct ImageCheck
+{
+    char * filename;
+    char * format;
+    int64_t check_errors;
+    bool has_image_end_offset;
+    int64_t image_end_offset;
+    bool has_corruptions;
+    int64_t corruptions;
+    bool has_leaks;
+    int64_t leaks;
+    bool has_corruptions_fixed;
+    int64_t corruptions_fixed;
+    bool has_leaks_fixed;
+    int64_t leaks_fixed;
+    bool has_total_clusters;
+    int64_t total_clusters;
+    bool has_allocated_clusters;
+    int64_t allocated_clusters;
+    bool has_fragmented_clusters;
+    int64_t fragmented_clusters;
+    bool has_compressed_clusters;
+    int64_t compressed_clusters;
+};
+
+void qapi_free_ImageCheckList(ImageCheckList * obj);
+void qapi_free_ImageCheck(ImageCheck * obj);
+
+struct StatusInfo
+{
+    bool running;
+    bool singlestep;
+    RunState status;
+};
+
+void qapi_free_StatusInfoList(StatusInfoList * obj);
+void qapi_free_StatusInfo(StatusInfo * obj);
+
+struct UuidInfo
+{
+    char * UUID;
+};
+
+void qapi_free_UuidInfoList(UuidInfoList * obj);
+void qapi_free_UuidInfo(UuidInfo * obj);
+
+struct ChardevInfo
+{
+    char * label;
+    char * filename;
+};
+
+void qapi_free_ChardevInfoList(ChardevInfoList * obj);
+void qapi_free_ChardevInfo(ChardevInfo * obj);
+
+void qapi_free_DataFormatList(DataFormatList * obj);
+
+struct CommandInfo
+{
+    char * name;
+};
+
+void qapi_free_CommandInfoList(CommandInfoList * obj);
+void qapi_free_CommandInfo(CommandInfo * obj);
+
+struct EventInfo
+{
+    char * name;
+};
+
+void qapi_free_EventInfoList(EventInfoList * obj);
+void qapi_free_EventInfo(EventInfo * obj);
+
+struct MigrationStats
+{
+    int64_t transferred;
+    int64_t remaining;
+    int64_t total;
+    int64_t duplicate;
+    int64_t skipped;
+    int64_t normal;
+    int64_t normal_bytes;
+    int64_t dirty_pages_rate;
+    double mbps;
+};
+
+void qapi_free_MigrationStatsList(MigrationStatsList * obj);
+void qapi_free_MigrationStats(MigrationStats * obj);
+
+struct XBZRLECacheStats
+{
+    int64_t cache_size;
+    int64_t bytes;
+    int64_t pages;
+    int64_t cache_miss;
+    int64_t overflow;
+};
+
+void qapi_free_XBZRLECacheStatsList(XBZRLECacheStatsList * obj);
+void qapi_free_XBZRLECacheStats(XBZRLECacheStats * obj);
+
+struct MigrationInfo
+{
+    bool has_status;
+    char * status;
+    bool has_ram;
+    MigrationStats * ram;
+    bool has_disk;
+    MigrationStats * disk;
+    bool has_xbzrle_cache;
+    XBZRLECacheStats * xbzrle_cache;
+    bool has_total_time;
+    int64_t total_time;
+    bool has_expected_downtime;
+    int64_t expected_downtime;
+    bool has_downtime;
+    int64_t downtime;
+    bool has_setup_time;
+    int64_t setup_time;
+};
+
+void qapi_free_MigrationInfoList(MigrationInfoList * obj);
+void qapi_free_MigrationInfo(MigrationInfo * obj);
+
+void qapi_free_MigrationCapabilityList(MigrationCapabilityList * obj);
+
+struct MigrationCapabilityStatus
+{
+    MigrationCapability capability;
+    bool state;
+};
+
+void qapi_free_MigrationCapabilityStatusList(MigrationCapabilityStatusList * obj);
+void qapi_free_MigrationCapabilityStatus(MigrationCapabilityStatus * obj);
+
+struct MouseInfo
+{
+    char * name;
+    int64_t index;
+    bool current;
+    bool absolute;
+};
+
+void qapi_free_MouseInfoList(MouseInfoList * obj);
+void qapi_free_MouseInfo(MouseInfo * obj);
+
+struct CpuInfo
+{
+    int64_t CPU;
+    bool current;
+    bool halted;
+    bool has_pc;
+    int64_t pc;
+    bool has_nip;
+    int64_t nip;
+    bool has_npc;
+    int64_t npc;
+    bool has_PC;
+    int64_t PC;
+    int64_t thread_id;
+};
+
+void qapi_free_CpuInfoList(CpuInfoList * obj);
+void qapi_free_CpuInfo(CpuInfo * obj);
+
+struct BlockDeviceInfo
+{
+    char * file;
+    bool ro;
+    char * drv;
+    bool has_backing_file;
+    char * backing_file;
+    int64_t backing_file_depth;
+    bool encrypted;
+    bool encryption_key_missing;
+    int64_t bps;
+    int64_t bps_rd;
+    int64_t bps_wr;
+    int64_t iops;
+    int64_t iops_rd;
+    int64_t iops_wr;
+    ImageInfo * image;
+    bool has_bps_max;
+    int64_t bps_max;
+    bool has_bps_rd_max;
+    int64_t bps_rd_max;
+    bool has_bps_wr_max;
+    int64_t bps_wr_max;
+    bool has_iops_max;
+    int64_t iops_max;
+    bool has_iops_rd_max;
+    int64_t iops_rd_max;
+    bool has_iops_wr_max;
+    int64_t iops_wr_max;
+    bool has_iops_size;
+    int64_t iops_size;
+};
+
+void qapi_free_BlockDeviceInfoList(BlockDeviceInfoList * obj);
+void qapi_free_BlockDeviceInfo(BlockDeviceInfo * obj);
+
+void qapi_free_BlockDeviceIoStatusList(BlockDeviceIoStatusList * obj);
+
+struct BlockDeviceMapEntry
+{
+    int64_t start;
+    int64_t length;
+    int64_t depth;
+    bool zero;
+    bool data;
+    bool has_offset;
+    int64_t offset;
+};
+
+void qapi_free_BlockDeviceMapEntryList(BlockDeviceMapEntryList * obj);
+void qapi_free_BlockDeviceMapEntry(BlockDeviceMapEntry * obj);
+
+struct BlockDirtyInfo
+{
+    int64_t count;
+    int64_t granularity;
+};
+
+void qapi_free_BlockDirtyInfoList(BlockDirtyInfoList * obj);
+void qapi_free_BlockDirtyInfo(BlockDirtyInfo * obj);
+
+struct BlockInfo
+{
+    char * device;
+    char * type;
+    bool removable;
+    bool locked;
+    bool has_inserted;
+    BlockDeviceInfo * inserted;
+    bool has_tray_open;
+    bool tray_open;
+    bool has_io_status;
+    BlockDeviceIoStatus io_status;
+    bool has_dirty_bitmaps;
+    BlockDirtyInfoList * dirty_bitmaps;
+};
+
+void qapi_free_BlockInfoList(BlockInfoList * obj);
+void qapi_free_BlockInfo(BlockInfo * obj);
+
+struct BlockDeviceStats
+{
+    int64_t rd_bytes;
+    int64_t wr_bytes;
+    int64_t rd_operations;
+    int64_t wr_operations;
+    int64_t flush_operations;
+    int64_t flush_total_time_ns;
+    int64_t wr_total_time_ns;
+    int64_t rd_total_time_ns;
+    int64_t wr_highest_offset;
+};
+
+void qapi_free_BlockDeviceStatsList(BlockDeviceStatsList * obj);
+void qapi_free_BlockDeviceStats(BlockDeviceStats * obj);
+
+struct BlockStats
+{
+    bool has_device;
+    char * device;
+    BlockDeviceStats * stats;
+    bool has_parent;
+    BlockStats * parent;
+};
+
+void qapi_free_BlockStatsList(BlockStatsList * obj);
+void qapi_free_BlockStats(BlockStats * obj);
+
+struct VncClientInfo
+{
+    char * host;
+    char * family;
+    char * service;
+    bool has_x509_dname;
+    char * x509_dname;
+    bool has_sasl_username;
+    char * sasl_username;
+};
+
+void qapi_free_VncClientInfoList(VncClientInfoList * obj);
+void qapi_free_VncClientInfo(VncClientInfo * obj);
+
+struct VncInfo
+{
+    bool enabled;
+    bool has_host;
+    char * host;
+    bool has_family;
+    char * family;
+    bool has_service;
+    char * service;
+    bool has_auth;
+    char * auth;
+    bool has_clients;
+    VncClientInfoList * clients;
+};
+
+void qapi_free_VncInfoList(VncInfoList * obj);
+void qapi_free_VncInfo(VncInfo * obj);
+
+struct SpiceChannel
+{
+    char * host;
+    char * family;
+    char * port;
+    int64_t connection_id;
+    int64_t channel_type;
+    int64_t channel_id;
+    bool tls;
+};
+
+void qapi_free_SpiceChannelList(SpiceChannelList * obj);
+void qapi_free_SpiceChannel(SpiceChannel * obj);
+
+void qapi_free_SpiceQueryMouseModeList(SpiceQueryMouseModeList * obj);
+
+struct SpiceInfo
+{
+    bool enabled;
+    bool migrated;
+    bool has_host;
+    char * host;
+    bool has_port;
+    int64_t port;
+    bool has_tls_port;
+    int64_t tls_port;
+    bool has_auth;
+    char * auth;
+    bool has_compiled_version;
+    char * compiled_version;
+    SpiceQueryMouseMode mouse_mode;
+    bool has_channels;
+    SpiceChannelList * channels;
+};
+
+void qapi_free_SpiceInfoList(SpiceInfoList * obj);
+void qapi_free_SpiceInfo(SpiceInfo * obj);
+
+struct BalloonInfo
+{
+    int64_t actual;
+};
+
+void qapi_free_BalloonInfoList(BalloonInfoList * obj);
+void qapi_free_BalloonInfo(BalloonInfo * obj);
+
+struct PciMemoryRange
+{
+    int64_t base;
+    int64_t limit;
+};
+
+void qapi_free_PciMemoryRangeList(PciMemoryRangeList * obj);
+void qapi_free_PciMemoryRange(PciMemoryRange * obj);
+
+struct PciMemoryRegion
+{
+    int64_t bar;
+    char * type;
+    int64_t address;
+    int64_t size;
+    bool has_prefetch;
+    bool prefetch;
+    bool has_mem_type_64;
+    bool mem_type_64;
+};
+
+void qapi_free_PciMemoryRegionList(PciMemoryRegionList * obj);
+void qapi_free_PciMemoryRegion(PciMemoryRegion * obj);
+
+struct PciBridgeInfo
+{
+    struct 
+    {
+        int64_t number;
+        int64_t secondary;
+        int64_t subordinate;
+        PciMemoryRange * io_range;
+        PciMemoryRange * memory_range;
+        PciMemoryRange * prefetchable_range;
+    } bus;
+    bool has_devices;
+    PciDeviceInfoList * devices;
+};
+
+void qapi_free_PciBridgeInfoList(PciBridgeInfoList * obj);
+void qapi_free_PciBridgeInfo(PciBridgeInfo * obj);
+
+struct PciDeviceInfo
+{
+    int64_t bus;
+    int64_t slot;
+    int64_t function;
+    struct 
+    {
+        bool has_desc;
+        char * desc;
+        int64_t q_class;
+    } class_info;
+    struct 
+    {
+        int64_t device;
+        int64_t vendor;
+    } id;
+    bool has_irq;
+    int64_t irq;
+    char * qdev_id;
+    bool has_pci_bridge;
+    PciBridgeInfo * pci_bridge;
+    PciMemoryRegionList * regions;
+};
+
+void qapi_free_PciDeviceInfoList(PciDeviceInfoList * obj);
+void qapi_free_PciDeviceInfo(PciDeviceInfo * obj);
+
+struct PciInfo
+{
+    int64_t bus;
+    PciDeviceInfoList * devices;
+};
+
+void qapi_free_PciInfoList(PciInfoList * obj);
+void qapi_free_PciInfo(PciInfo * obj);
+
+void qapi_free_BlockdevOnErrorList(BlockdevOnErrorList * obj);
+
+void qapi_free_MirrorSyncModeList(MirrorSyncModeList * obj);
+
+void qapi_free_BlockJobTypeList(BlockJobTypeList * obj);
+
+struct BlockJobInfo
+{
+    char * type;
+    char * device;
+    int64_t len;
+    int64_t offset;
+    bool busy;
+    bool paused;
+    int64_t speed;
+    BlockDeviceIoStatus io_status;
+};
+
+void qapi_free_BlockJobInfoList(BlockJobInfoList * obj);
+void qapi_free_BlockJobInfo(BlockJobInfo * obj);
+
+void qapi_free_NewImageModeList(NewImageModeList * obj);
+
+struct BlockdevSnapshot
+{
+    char * device;
+    char * snapshot_file;
+    bool has_format;
+    char * format;
+    bool has_mode;
+    NewImageMode mode;
+};
+
+void qapi_free_BlockdevSnapshotList(BlockdevSnapshotList * obj);
+void qapi_free_BlockdevSnapshot(BlockdevSnapshot * obj);
+
+struct BlockdevSnapshotInternal
+{
+    char * device;
+    char * name;
+};
+
+void qapi_free_BlockdevSnapshotInternalList(BlockdevSnapshotInternalList * obj);
+void qapi_free_BlockdevSnapshotInternal(BlockdevSnapshotInternal * obj);
+
+struct DriveBackup
+{
+    char * device;
+    char * target;
+    bool has_format;
+    char * format;
+    MirrorSyncMode sync;
+    bool has_mode;
+    NewImageMode mode;
+    bool has_speed;
+    int64_t speed;
+    bool has_on_source_error;
+    BlockdevOnError on_source_error;
+    bool has_on_target_error;
+    BlockdevOnError on_target_error;
+};
+
+void qapi_free_DriveBackupList(DriveBackupList * obj);
+void qapi_free_DriveBackup(DriveBackup * obj);
+
+struct Abort
+{
+};
+
+void qapi_free_AbortList(AbortList * obj);
+void qapi_free_Abort(Abort * obj);
+
+struct TransactionAction
+{
+    TransactionActionKind kind;
+    union {
+        void *data;
+        BlockdevSnapshot * blockdev_snapshot_sync;
+        DriveBackup * drive_backup;
+        Abort * abort;
+        BlockdevSnapshotInternal * blockdev_snapshot_internal_sync;
+    };
+};
+void qapi_free_TransactionActionList(TransactionActionList * obj);
+void qapi_free_TransactionAction(TransactionAction * obj);
+
+struct ObjectPropertyInfo
+{
+    char * name;
+    char * type;
+};
+
+void qapi_free_ObjectPropertyInfoList(ObjectPropertyInfoList * obj);
+void qapi_free_ObjectPropertyInfo(ObjectPropertyInfo * obj);
+
+struct ObjectTypeInfo
+{
+    char * name;
+};
+
+void qapi_free_ObjectTypeInfoList(ObjectTypeInfoList * obj);
+void qapi_free_ObjectTypeInfo(ObjectTypeInfo * obj);
+
+struct DevicePropertyInfo
+{
+    char * name;
+    char * type;
+};
+
+void qapi_free_DevicePropertyInfoList(DevicePropertyInfoList * obj);
+void qapi_free_DevicePropertyInfo(DevicePropertyInfo * obj);
+
+struct NetdevNoneOptions
+{
+};
+
+void qapi_free_NetdevNoneOptionsList(NetdevNoneOptionsList * obj);
+void qapi_free_NetdevNoneOptions(NetdevNoneOptions * obj);
+
+struct NetLegacyNicOptions
+{
+    bool has_netdev;
+    char * netdev;
+    bool has_macaddr;
+    char * macaddr;
+    bool has_model;
+    char * model;
+    bool has_addr;
+    char * addr;
+    bool has_vectors;
+    uint32_t vectors;
+};
+
+void qapi_free_NetLegacyNicOptionsList(NetLegacyNicOptionsList * obj);
+void qapi_free_NetLegacyNicOptions(NetLegacyNicOptions * obj);
+
+struct String
+{
+    char * str;
+};
+
+void qapi_free_StringList(StringList * obj);
+void qapi_free_String(String * obj);
+
+struct NetdevUserOptions
+{
+    bool has_hostname;
+    char * hostname;
+    bool has_q_restrict;
+    bool q_restrict;
+    bool has_ip;
+    char * ip;
+    bool has_net;
+    char * net;
+    bool has_host;
+    char * host;
+    bool has_tftp;
+    char * tftp;
+    bool has_bootfile;
+    char * bootfile;
+    bool has_dhcpstart;
+    char * dhcpstart;
+    bool has_dns;
+    char * dns;
+    bool has_dnssearch;
+    StringList * dnssearch;
+    bool has_smb;
+    char * smb;
+    bool has_smbserver;
+    char * smbserver;
+    bool has_hostfwd;
+    StringList * hostfwd;
+    bool has_guestfwd;
+    StringList * guestfwd;
+};
+
+void qapi_free_NetdevUserOptionsList(NetdevUserOptionsList * obj);
+void qapi_free_NetdevUserOptions(NetdevUserOptions * obj);
+
+struct NetdevTapOptions
+{
+    bool has_ifname;
+    char * ifname;
+    bool has_fd;
+    char * fd;
+    bool has_fds;
+    char * fds;
+    bool has_script;
+    char * script;
+    bool has_downscript;
+    char * downscript;
+    bool has_helper;
+    char * helper;
+    bool has_sndbuf;
+    uint64_t sndbuf;
+    bool has_vnet_hdr;
+    bool vnet_hdr;
+    bool has_vhost;
+    bool vhost;
+    bool has_vhostfd;
+    char * vhostfd;
+    bool has_vhostfds;
+    char * vhostfds;
+    bool has_vhostforce;
+    bool vhostforce;
+    bool has_queues;
+    uint32_t queues;
+};
+
+void qapi_free_NetdevTapOptionsList(NetdevTapOptionsList * obj);
+void qapi_free_NetdevTapOptions(NetdevTapOptions * obj);
+
+struct NetdevSocketOptions
+{
+    bool has_fd;
+    char * fd;
+    bool has_listen;
+    char * listen;
+    bool has_connect;
+    char * connect;
+    bool has_mcast;
+    char * mcast;
+    bool has_localaddr;
+    char * localaddr;
+    bool has_udp;
+    char * udp;
+};
+
+void qapi_free_NetdevSocketOptionsList(NetdevSocketOptionsList * obj);
+void qapi_free_NetdevSocketOptions(NetdevSocketOptions * obj);
+
+struct NetdevVdeOptions
+{
+    bool has_sock;
+    char * sock;
+    bool has_port;
+    uint16_t port;
+    bool has_group;
+    char * group;
+    bool has_mode;
+    uint16_t mode;
+};
+
+void qapi_free_NetdevVdeOptionsList(NetdevVdeOptionsList * obj);
+void qapi_free_NetdevVdeOptions(NetdevVdeOptions * obj);
+
+struct NetdevDumpOptions
+{
+    bool has_len;
+    uint64_t len;
+    bool has_file;
+    char * file;
+};
+
+void qapi_free_NetdevDumpOptionsList(NetdevDumpOptionsList * obj);
+void qapi_free_NetdevDumpOptions(NetdevDumpOptions * obj);
+
+struct NetdevBridgeOptions
+{
+    bool has_br;
+    char * br;
+    bool has_helper;
+    char * helper;
+};
+
+void qapi_free_NetdevBridgeOptionsList(NetdevBridgeOptionsList * obj);
+void qapi_free_NetdevBridgeOptions(NetdevBridgeOptions * obj);
+
+struct NetdevHubPortOptions
+{
+    int32_t hubid;
+};
+
+void qapi_free_NetdevHubPortOptionsList(NetdevHubPortOptionsList * obj);
+void qapi_free_NetdevHubPortOptions(NetdevHubPortOptions * obj);
+
+struct NetdevNetmapOptions
+{
+    char * ifname;
+    bool has_devname;
+    char * devname;
+};
+
+void qapi_free_NetdevNetmapOptionsList(NetdevNetmapOptionsList * obj);
+void qapi_free_NetdevNetmapOptions(NetdevNetmapOptions * obj);
+
+struct NetClientOptions
+{
+    NetClientOptionsKind kind;
+    union {
+        void *data;
+        NetdevNoneOptions * none;
+        NetLegacyNicOptions * nic;
+        NetdevUserOptions * user;
+        NetdevTapOptions * tap;
+        NetdevSocketOptions * socket;
+        NetdevVdeOptions * vde;
+        NetdevDumpOptions * dump;
+        NetdevBridgeOptions * bridge;
+        NetdevHubPortOptions * hubport;
+        NetdevNetmapOptions * netmap;
+    };
+};
+void qapi_free_NetClientOptionsList(NetClientOptionsList * obj);
+void qapi_free_NetClientOptions(NetClientOptions * obj);
+
+struct NetLegacy
+{
+    bool has_vlan;
+    int32_t vlan;
+    bool has_id;
+    char * id;
+    bool has_name;
+    char * name;
+    NetClientOptions * opts;
+};
+
+void qapi_free_NetLegacyList(NetLegacyList * obj);
+void qapi_free_NetLegacy(NetLegacy * obj);
+
+struct Netdev
+{
+    char * id;
+    NetClientOptions * opts;
+};
+
+void qapi_free_NetdevList(NetdevList * obj);
+void qapi_free_Netdev(Netdev * obj);
+
+struct InetSocketAddress
+{
+    char * host;
+    char * port;
+    bool has_to;
+    uint16_t to;
+    bool has_ipv4;
+    bool ipv4;
+    bool has_ipv6;
+    bool ipv6;
+};
+
+void qapi_free_InetSocketAddressList(InetSocketAddressList * obj);
+void qapi_free_InetSocketAddress(InetSocketAddress * obj);
+
+struct UnixSocketAddress
+{
+    char * path;
+};
+
+void qapi_free_UnixSocketAddressList(UnixSocketAddressList * obj);
+void qapi_free_UnixSocketAddress(UnixSocketAddress * obj);
+
+struct SocketAddress
+{
+    SocketAddressKind kind;
+    union {
+        void *data;
+        InetSocketAddress * inet;
+        UnixSocketAddress * q_unix;
+        String * fd;
+    };
+};
+void qapi_free_SocketAddressList(SocketAddressList * obj);
+void qapi_free_SocketAddress(SocketAddress * obj);
+
+struct MachineInfo
+{
+    char * name;
+    bool has_alias;
+    char * alias;
+    bool has_is_default;
+    bool is_default;
+    int64_t cpu_max;
+};
+
+void qapi_free_MachineInfoList(MachineInfoList * obj);
+void qapi_free_MachineInfo(MachineInfo * obj);
+
+struct CpuDefinitionInfo
+{
+    char * name;
+};
+
+void qapi_free_CpuDefinitionInfoList(CpuDefinitionInfoList * obj);
+void qapi_free_CpuDefinitionInfo(CpuDefinitionInfo * obj);
+
+struct AddfdInfo
+{
+    int64_t fdset_id;
+    int64_t fd;
+};
+
+void qapi_free_AddfdInfoList(AddfdInfoList * obj);
+void qapi_free_AddfdInfo(AddfdInfo * obj);
+
+struct FdsetFdInfo
+{
+    int64_t fd;
+    bool has_opaque;
+    char * opaque;
+};
+
+void qapi_free_FdsetFdInfoList(FdsetFdInfoList * obj);
+void qapi_free_FdsetFdInfo(FdsetFdInfo * obj);
+
+struct FdsetInfo
+{
+    int64_t fdset_id;
+    FdsetFdInfoList * fds;
+};
+
+void qapi_free_FdsetInfoList(FdsetInfoList * obj);
+void qapi_free_FdsetInfo(FdsetInfo * obj);
+
+struct TargetInfo
+{
+    char * arch;
+};
+
+void qapi_free_TargetInfoList(TargetInfoList * obj);
+void qapi_free_TargetInfo(TargetInfo * obj);
+
+void qapi_free_QKeyCodeList(QKeyCodeList * obj);
+
+struct KeyValue
+{
+    KeyValueKind kind;
+    union {
+        void *data;
+        int64_t number;
+        QKeyCode qcode;
+    };
+};
+void qapi_free_KeyValueList(KeyValueList * obj);
+void qapi_free_KeyValue(KeyValue * obj);
+
+struct ChardevFile
+{
+    bool has_in;
+    char * in;
+    char * out;
+};
+
+void qapi_free_ChardevFileList(ChardevFileList * obj);
+void qapi_free_ChardevFile(ChardevFile * obj);
+
+struct ChardevHostdev
+{
+    char * device;
+};
+
+void qapi_free_ChardevHostdevList(ChardevHostdevList * obj);
+void qapi_free_ChardevHostdev(ChardevHostdev * obj);
+
+struct ChardevSocket
+{
+    SocketAddress * addr;
+    bool has_server;
+    bool server;
+    bool has_wait;
+    bool wait;
+    bool has_nodelay;
+    bool nodelay;
+    bool has_telnet;
+    bool telnet;
+};
+
+void qapi_free_ChardevSocketList(ChardevSocketList * obj);
+void qapi_free_ChardevSocket(ChardevSocket * obj);
+
+struct ChardevUdp
+{
+    SocketAddress * remote;
+    bool has_local;
+    SocketAddress * local;
+};
+
+void qapi_free_ChardevUdpList(ChardevUdpList * obj);
+void qapi_free_ChardevUdp(ChardevUdp * obj);
+
+struct ChardevMux
+{
+    char * chardev;
+};
+
+void qapi_free_ChardevMuxList(ChardevMuxList * obj);
+void qapi_free_ChardevMux(ChardevMux * obj);
+
+struct ChardevStdio
+{
+    bool has_signal;
+    bool signal;
+};
+
+void qapi_free_ChardevStdioList(ChardevStdioList * obj);
+void qapi_free_ChardevStdio(ChardevStdio * obj);
+
+struct ChardevSpiceChannel
+{
+    char * type;
+};
+
+void qapi_free_ChardevSpiceChannelList(ChardevSpiceChannelList * obj);
+void qapi_free_ChardevSpiceChannel(ChardevSpiceChannel * obj);
+
+struct ChardevSpicePort
+{
+    char * fqdn;
+};
+
+void qapi_free_ChardevSpicePortList(ChardevSpicePortList * obj);
+void qapi_free_ChardevSpicePort(ChardevSpicePort * obj);
+
+struct ChardevVC
+{
+    bool has_width;
+    int64_t width;
+    bool has_height;
+    int64_t height;
+    bool has_cols;
+    int64_t cols;
+    bool has_rows;
+    int64_t rows;
+};
+
+void qapi_free_ChardevVCList(ChardevVCList * obj);
+void qapi_free_ChardevVC(ChardevVC * obj);
+
+struct ChardevRingbuf
+{
+    bool has_size;
+    int64_t size;
+};
+
+void qapi_free_ChardevRingbufList(ChardevRingbufList * obj);
+void qapi_free_ChardevRingbuf(ChardevRingbuf * obj);
+
+struct ChardevDummy
+{
+};
+
+void qapi_free_ChardevDummyList(ChardevDummyList * obj);
+void qapi_free_ChardevDummy(ChardevDummy * obj);
+
+struct ChardevBackend
+{
+    ChardevBackendKind kind;
+    union {
+        void *data;
+        ChardevFile * file;
+        ChardevHostdev * serial;
+        ChardevHostdev * parallel;
+        ChardevHostdev * pipe;
+        ChardevSocket * socket;
+        ChardevUdp * udp;
+        ChardevDummy * pty;
+        ChardevDummy * null;
+        ChardevMux * mux;
+        ChardevDummy * msmouse;
+        ChardevDummy * braille;
+        ChardevStdio * stdio;
+        ChardevDummy * console;
+        ChardevSpiceChannel * spicevmc;
+        ChardevSpicePort * spiceport;
+        ChardevVC * vc;
+        ChardevRingbuf * ringbuf;
+        ChardevRingbuf * memory;
+    };
+};
+void qapi_free_ChardevBackendList(ChardevBackendList * obj);
+void qapi_free_ChardevBackend(ChardevBackend * obj);
+
+struct ChardevReturn
+{
+    bool has_pty;
+    char * pty;
+};
+
+void qapi_free_ChardevReturnList(ChardevReturnList * obj);
+void qapi_free_ChardevReturn(ChardevReturn * obj);
+
+void qapi_free_TpmModelList(TpmModelList * obj);
+
+void qapi_free_TpmTypeList(TpmTypeList * obj);
+
+struct TPMPassthroughOptions
+{
+    bool has_path;
+    char * path;
+    bool has_cancel_path;
+    char * cancel_path;
+};
+
+void qapi_free_TPMPassthroughOptionsList(TPMPassthroughOptionsList * obj);
+void qapi_free_TPMPassthroughOptions(TPMPassthroughOptions * obj);
+
+struct TpmTypeOptions
+{
+    TpmTypeOptionsKind kind;
+    union {
+        void *data;
+        TPMPassthroughOptions * passthrough;
+    };
+};
+void qapi_free_TpmTypeOptionsList(TpmTypeOptionsList * obj);
+void qapi_free_TpmTypeOptions(TpmTypeOptions * obj);
+
+struct TPMInfo
+{
+    char * id;
+    TpmModel model;
+    TpmTypeOptions * options;
+};
+
+void qapi_free_TPMInfoList(TPMInfoList * obj);
+void qapi_free_TPMInfo(TPMInfo * obj);
+
+struct AcpiTableOptions
+{
+    bool has_sig;
+    char * sig;
+    bool has_rev;
+    uint8_t rev;
+    bool has_oem_id;
+    char * oem_id;
+    bool has_oem_table_id;
+    char * oem_table_id;
+    bool has_oem_rev;
+    uint32_t oem_rev;
+    bool has_asl_compiler_id;
+    char * asl_compiler_id;
+    bool has_asl_compiler_rev;
+    uint32_t asl_compiler_rev;
+    bool has_file;
+    char * file;
+    bool has_data;
+    char * data;
+};
+
+void qapi_free_AcpiTableOptionsList(AcpiTableOptionsList * obj);
+void qapi_free_AcpiTableOptions(AcpiTableOptions * obj);
+
+void qapi_free_CommandLineParameterTypeList(CommandLineParameterTypeList * obj);
+
+struct CommandLineParameterInfo
+{
+    char * name;
+    CommandLineParameterType type;
+    bool has_help;
+    char * help;
+};
+
+void qapi_free_CommandLineParameterInfoList(CommandLineParameterInfoList * obj);
+void qapi_free_CommandLineParameterInfo(CommandLineParameterInfo * obj);
+
+struct CommandLineOptionInfo
+{
+    char * option;
+    CommandLineParameterInfoList * parameters;
+};
+
+void qapi_free_CommandLineOptionInfoList(CommandLineOptionInfoList * obj);
+void qapi_free_CommandLineOptionInfo(CommandLineOptionInfo * obj);
+
+void qapi_free_X86CPURegister32List(X86CPURegister32List * obj);
+
+struct X86CPUFeatureWordInfo
+{
+    int64_t cpuid_input_eax;
+    bool has_cpuid_input_ecx;
+    int64_t cpuid_input_ecx;
+    X86CPURegister32 cpuid_register;
+    int64_t features;
+};
+
+void qapi_free_X86CPUFeatureWordInfoList(X86CPUFeatureWordInfoList * obj);
+void qapi_free_X86CPUFeatureWordInfo(X86CPUFeatureWordInfo * obj);
+
+void qapi_free_RxStateList(RxStateList * obj);
+
+struct RxFilterInfo
+{
+    char * name;
+    bool promiscuous;
+    RxState multicast;
+    RxState unicast;
+    bool broadcast_allowed;
+    bool multicast_overflow;
+    bool unicast_overflow;
+    char * main_mac;
+    intList * vlan_table;
+    strList * unicast_table;
+    strList * multicast_table;
+};
+
+void qapi_free_RxFilterInfoList(RxFilterInfoList * obj);
+void qapi_free_RxFilterInfo(RxFilterInfo * obj);
+
+void qapi_free_BlockdevDiscardOptionsList(BlockdevDiscardOptionsList * obj);
+
+void qapi_free_BlockdevAioOptionsList(BlockdevAioOptionsList * obj);
+
+struct BlockdevCacheOptions
+{
+    bool has_writeback;
+    bool writeback;
+    bool has_direct;
+    bool direct;
+    bool has_no_flush;
+    bool no_flush;
+};
+
+void qapi_free_BlockdevCacheOptionsList(BlockdevCacheOptionsList * obj);
+void qapi_free_BlockdevCacheOptions(BlockdevCacheOptions * obj);
+
+struct BlockdevOptionsBase
+{
+    char * driver;
+    bool has_id;
+    char * id;
+    bool has_discard;
+    BlockdevDiscardOptions discard;
+    bool has_cache;
+    BlockdevCacheOptions * cache;
+    bool has_aio;
+    BlockdevAioOptions aio;
+    bool has_rerror;
+    BlockdevOnError rerror;
+    bool has_werror;
+    BlockdevOnError werror;
+    bool has_read_only;
+    bool read_only;
+};
+
+void qapi_free_BlockdevOptionsBaseList(BlockdevOptionsBaseList * obj);
+void qapi_free_BlockdevOptionsBase(BlockdevOptionsBase * obj);
+
+struct BlockdevOptionsFile
+{
+    char * filename;
+};
+
+void qapi_free_BlockdevOptionsFileList(BlockdevOptionsFileList * obj);
+void qapi_free_BlockdevOptionsFile(BlockdevOptionsFile * obj);
+
+struct BlockdevOptionsVVFAT
+{
+    char * dir;
+    bool has_fat_type;
+    int64_t fat_type;
+    bool has_floppy;
+    bool floppy;
+    bool has_rw;
+    bool rw;
+};
+
+void qapi_free_BlockdevOptionsVVFATList(BlockdevOptionsVVFATList * obj);
+void qapi_free_BlockdevOptionsVVFAT(BlockdevOptionsVVFAT * obj);
+
+struct BlockdevOptionsGenericFormat
+{
+    BlockdevRef * file;
+};
+
+void qapi_free_BlockdevOptionsGenericFormatList(BlockdevOptionsGenericFormatList * obj);
+void qapi_free_BlockdevOptionsGenericFormat(BlockdevOptionsGenericFormat * obj);
+
+struct BlockdevOptionsGenericCOWFormat
+{
+    BlockdevOptionsGenericFormat * base;
+    bool has_backing;
+    BlockdevRef * backing;
+};
+
+void qapi_free_BlockdevOptionsGenericCOWFormatList(BlockdevOptionsGenericCOWFormatList * obj);
+void qapi_free_BlockdevOptionsGenericCOWFormat(BlockdevOptionsGenericCOWFormat * obj);
+
+struct BlockdevOptionsQcow2
+{
+    BlockdevOptionsGenericCOWFormat * base;
+    bool has_lazy_refcounts;
+    bool lazy_refcounts;
+    bool has_pass_discard_request;
+    bool pass_discard_request;
+    bool has_pass_discard_snapshot;
+    bool pass_discard_snapshot;
+    bool has_pass_discard_other;
+    bool pass_discard_other;
+};
+
+void qapi_free_BlockdevOptionsQcow2List(BlockdevOptionsQcow2List * obj);
+void qapi_free_BlockdevOptionsQcow2(BlockdevOptionsQcow2 * obj);
+
+struct BlockdevOptions
+{
+    BlockdevOptionsKind kind;
+    union {
+        void *data;
+        BlockdevOptionsFile * file;
+        BlockdevOptionsFile * http;
+        BlockdevOptionsFile * https;
+        BlockdevOptionsFile * ftp;
+        BlockdevOptionsFile * ftps;
+        BlockdevOptionsFile * tftp;
+        BlockdevOptionsVVFAT * vvfat;
+        BlockdevOptionsGenericFormat * bochs;
+        BlockdevOptionsGenericFormat * cloop;
+        BlockdevOptionsGenericCOWFormat * cow;
+        BlockdevOptionsGenericFormat * dmg;
+        BlockdevOptionsGenericFormat * parallels;
+        BlockdevOptionsGenericCOWFormat * qcow;
+        BlockdevOptionsQcow2 * qcow2;
+        BlockdevOptionsGenericCOWFormat * qed;
+        BlockdevOptionsGenericFormat * raw;
+        BlockdevOptionsGenericFormat * vdi;
+        BlockdevOptionsGenericFormat * vhdx;
+        BlockdevOptionsGenericCOWFormat * vmdk;
+        BlockdevOptionsGenericFormat * vpc;
+    };
+    bool has_id;
+    char * id;
+    bool has_discard;
+    BlockdevDiscardOptions discard;
+    bool has_cache;
+    BlockdevCacheOptions * cache;
+    bool has_aio;
+    BlockdevAioOptions aio;
+    bool has_rerror;
+    BlockdevOnError rerror;
+    bool has_werror;
+    BlockdevOnError werror;
+    bool has_read_only;
+    bool read_only;
+};
+void qapi_free_BlockdevOptionsList(BlockdevOptionsList * obj);
+void qapi_free_BlockdevOptions(BlockdevOptions * obj);
+
+struct BlockdevRef
+{
+    BlockdevRefKind kind;
+    union {
+        void *data;
+        BlockdevOptions * definition;
+        char * reference;
+    };
+};
+extern const int BlockdevRef_qtypes[];
+void qapi_free_BlockdevRefList(BlockdevRefList * obj);
+void qapi_free_BlockdevRef(BlockdevRef * obj);
+
+#endif
diff --git a/qapi-auto-generated/qapi-visit.c b/qapi-auto-generated/qapi-visit.c
new file mode 100644
index 0000000..af20d3e
--- /dev/null
+++ b/qapi-auto-generated/qapi-visit.c
@@ -0,0 +1,6982 @@
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QAPI visitor functions
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "qapi-visit.h"
+
+#ifndef QAPI_VISIT_BUILTIN_VISITOR_DEF_H
+#define QAPI_VISIT_BUILTIN_VISITOR_DEF_H
+
+
+void visit_type_strList(Visitor *m, strList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                strList *native_i = (strList *)i;
+                visit_type_str(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_intList(Visitor *m, intList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                intList *native_i = (intList *)i;
+                visit_type_int(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_numberList(Visitor *m, numberList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                numberList *native_i = (numberList *)i;
+                visit_type_number(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_boolList(Visitor *m, boolList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                boolList *native_i = (boolList *)i;
+                visit_type_bool(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_int8List(Visitor *m, int8List ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                int8List *native_i = (int8List *)i;
+                visit_type_int8(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_int16List(Visitor *m, int16List ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                int16List *native_i = (int16List *)i;
+                visit_type_int16(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_int32List(Visitor *m, int32List ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                int32List *native_i = (int32List *)i;
+                visit_type_int32(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_int64List(Visitor *m, int64List ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                int64List *native_i = (int64List *)i;
+                visit_type_int64(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_uint8List(Visitor *m, uint8List ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                uint8List *native_i = (uint8List *)i;
+                visit_type_uint8(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_uint16List(Visitor *m, uint16List ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                uint16List *native_i = (uint16List *)i;
+                visit_type_uint16(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_uint32List(Visitor *m, uint32List ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                uint32List *native_i = (uint32List *)i;
+                visit_type_uint32(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_uint64List(Visitor *m, uint64List ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                uint64List *native_i = (uint64List *)i;
+                visit_type_uint64(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+#endif /* QAPI_VISIT_BUILTIN_VISITOR_DEF_H */
+
+
+void visit_type_ErrorClassList(Visitor *m, ErrorClassList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ErrorClassList *native_i = (ErrorClassList *)i;
+                visit_type_ErrorClass(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ErrorClass(Visitor *m, ErrorClass * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, ErrorClass_lookup, "ErrorClass", name, errp);
+}
+
+static void visit_type_NameInfo_fields(Visitor *m, NameInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_name : NULL, "name", &err);
+    if (obj && (*obj)->has_name) {
+        visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NameInfo(Visitor *m, NameInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NameInfo", name, sizeof(NameInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NameInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NameInfoList(Visitor *m, NameInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NameInfoList *native_i = (NameInfoList *)i;
+                visit_type_NameInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_VersionInfo_qemu_fields(Visitor *m, VersionInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->qemu.major : NULL, "major", &err);
+    visit_type_int(m, obj ? &(*obj)->qemu.minor : NULL, "minor", &err);
+    visit_type_int(m, obj ? &(*obj)->qemu.micro : NULL, "micro", &err);
+
+    error_propagate(errp, err);
+}
+
+static void visit_type_VersionInfo_fields(Visitor *m, VersionInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    if (!error_is_set(errp)) {
+        Error **errp = &err; /* from outer scope */
+        Error *err = NULL;
+        visit_start_struct(m, NULL, "", "qemu", 0, &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_VersionInfo_qemu_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+    visit_type_str(m, obj ? &(*obj)->package : NULL, "package", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_VersionInfo(Visitor *m, VersionInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "VersionInfo", name, sizeof(VersionInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_VersionInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_VersionInfoList(Visitor *m, VersionInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                VersionInfoList *native_i = (VersionInfoList *)i;
+                visit_type_VersionInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_KvmInfo_fields(Visitor *m, KvmInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_bool(m, obj ? &(*obj)->enabled : NULL, "enabled", &err);
+    visit_type_bool(m, obj ? &(*obj)->present : NULL, "present", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_KvmInfo(Visitor *m, KvmInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "KvmInfo", name, sizeof(KvmInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_KvmInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_KvmInfoList(Visitor *m, KvmInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                KvmInfoList *native_i = (KvmInfoList *)i;
+                visit_type_KvmInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_RunStateList(Visitor *m, RunStateList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                RunStateList *native_i = (RunStateList *)i;
+                visit_type_RunState(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_RunState(Visitor *m, RunState * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, RunState_lookup, "RunState", name, errp);
+}
+
+static void visit_type_SnapshotInfo_fields(Visitor *m, SnapshotInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->id : NULL, "id", &err);
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+    visit_type_int(m, obj ? &(*obj)->vm_state_size : NULL, "vm-state-size", &err);
+    visit_type_int(m, obj ? &(*obj)->date_sec : NULL, "date-sec", &err);
+    visit_type_int(m, obj ? &(*obj)->date_nsec : NULL, "date-nsec", &err);
+    visit_type_int(m, obj ? &(*obj)->vm_clock_sec : NULL, "vm-clock-sec", &err);
+    visit_type_int(m, obj ? &(*obj)->vm_clock_nsec : NULL, "vm-clock-nsec", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_SnapshotInfo(Visitor *m, SnapshotInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "SnapshotInfo", name, sizeof(SnapshotInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_SnapshotInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_SnapshotInfoList(Visitor *m, SnapshotInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                SnapshotInfoList *native_i = (SnapshotInfoList *)i;
+                visit_type_SnapshotInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ImageInfoSpecificQCow2_fields(Visitor *m, ImageInfoSpecificQCow2 ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->compat : NULL, "compat", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_lazy_refcounts : NULL, "lazy-refcounts", &err);
+    if (obj && (*obj)->has_lazy_refcounts) {
+        visit_type_bool(m, obj ? &(*obj)->lazy_refcounts : NULL, "lazy-refcounts", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ImageInfoSpecificQCow2(Visitor *m, ImageInfoSpecificQCow2 ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ImageInfoSpecificQCow2", name, sizeof(ImageInfoSpecificQCow2), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ImageInfoSpecificQCow2_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ImageInfoSpecificQCow2List(Visitor *m, ImageInfoSpecificQCow2List ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ImageInfoSpecificQCow2List *native_i = (ImageInfoSpecificQCow2List *)i;
+                visit_type_ImageInfoSpecificQCow2(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ImageInfoSpecificVmdk_fields(Visitor *m, ImageInfoSpecificVmdk ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->create_type : NULL, "create-type", &err);
+    visit_type_int(m, obj ? &(*obj)->cid : NULL, "cid", &err);
+    visit_type_int(m, obj ? &(*obj)->parent_cid : NULL, "parent-cid", &err);
+    visit_type_ImageInfoList(m, obj ? &(*obj)->extents : NULL, "extents", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ImageInfoSpecificVmdk(Visitor *m, ImageInfoSpecificVmdk ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ImageInfoSpecificVmdk", name, sizeof(ImageInfoSpecificVmdk), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ImageInfoSpecificVmdk_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ImageInfoSpecificVmdkList(Visitor *m, ImageInfoSpecificVmdkList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ImageInfoSpecificVmdkList *native_i = (ImageInfoSpecificVmdkList *)i;
+                visit_type_ImageInfoSpecificVmdk(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ImageInfoSpecificKind(Visitor *m, ImageInfoSpecificKind * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, ImageInfoSpecificKind_lookup, "ImageInfoSpecificKind", name, errp);
+}
+
+void visit_type_ImageInfoSpecific(Visitor *m, ImageInfoSpecific ** obj, const char *name, Error **errp)
+{
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_struct(m, (void **)obj, "ImageInfoSpecific", name, sizeof(ImageInfoSpecific), &err);
+        if (!err) {
+            if (obj && *obj) {
+                visit_type_ImageInfoSpecificKind(m, &(*obj)->kind, "type", &err);
+                if (!err) {
+                    switch ((*obj)->kind) {
+                    case IMAGE_INFO_SPECIFIC_KIND_QCOW2:
+                        visit_type_ImageInfoSpecificQCow2(m, &(*obj)->qcow2, "data", &err);
+                        break;
+                    case IMAGE_INFO_SPECIFIC_KIND_VMDK:
+                        visit_type_ImageInfoSpecificVmdk(m, &(*obj)->vmdk, "data", &err);
+                        break;
+                    default:
+                        abort();
+                    }
+                }
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ImageInfoSpecificList(Visitor *m, ImageInfoSpecificList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ImageInfoSpecificList *native_i = (ImageInfoSpecificList *)i;
+                visit_type_ImageInfoSpecific(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ImageInfo_fields(Visitor *m, ImageInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->filename : NULL, "filename", &err);
+    visit_type_str(m, obj ? &(*obj)->format : NULL, "format", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_dirty_flag : NULL, "dirty-flag", &err);
+    if (obj && (*obj)->has_dirty_flag) {
+        visit_type_bool(m, obj ? &(*obj)->dirty_flag : NULL, "dirty-flag", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_actual_size : NULL, "actual-size", &err);
+    if (obj && (*obj)->has_actual_size) {
+        visit_type_int(m, obj ? &(*obj)->actual_size : NULL, "actual-size", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_int(m, obj ? &(*obj)->virtual_size : NULL, "virtual-size", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_cluster_size : NULL, "cluster-size", &err);
+    if (obj && (*obj)->has_cluster_size) {
+        visit_type_int(m, obj ? &(*obj)->cluster_size : NULL, "cluster-size", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_encrypted : NULL, "encrypted", &err);
+    if (obj && (*obj)->has_encrypted) {
+        visit_type_bool(m, obj ? &(*obj)->encrypted : NULL, "encrypted", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_compressed : NULL, "compressed", &err);
+    if (obj && (*obj)->has_compressed) {
+        visit_type_bool(m, obj ? &(*obj)->compressed : NULL, "compressed", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_backing_filename : NULL, "backing-filename", &err);
+    if (obj && (*obj)->has_backing_filename) {
+        visit_type_str(m, obj ? &(*obj)->backing_filename : NULL, "backing-filename", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_full_backing_filename : NULL, "full-backing-filename", &err);
+    if (obj && (*obj)->has_full_backing_filename) {
+        visit_type_str(m, obj ? &(*obj)->full_backing_filename : NULL, "full-backing-filename", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_backing_filename_format : NULL, "backing-filename-format", &err);
+    if (obj && (*obj)->has_backing_filename_format) {
+        visit_type_str(m, obj ? &(*obj)->backing_filename_format : NULL, "backing-filename-format", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_snapshots : NULL, "snapshots", &err);
+    if (obj && (*obj)->has_snapshots) {
+        visit_type_SnapshotInfoList(m, obj ? &(*obj)->snapshots : NULL, "snapshots", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_backing_image : NULL, "backing-image", &err);
+    if (obj && (*obj)->has_backing_image) {
+        visit_type_ImageInfo(m, obj ? &(*obj)->backing_image : NULL, "backing-image", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_format_specific : NULL, "format-specific", &err);
+    if (obj && (*obj)->has_format_specific) {
+        visit_type_ImageInfoSpecific(m, obj ? &(*obj)->format_specific : NULL, "format-specific", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ImageInfo(Visitor *m, ImageInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ImageInfo", name, sizeof(ImageInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ImageInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ImageInfoList(Visitor *m, ImageInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ImageInfoList *native_i = (ImageInfoList *)i;
+                visit_type_ImageInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ImageCheck_fields(Visitor *m, ImageCheck ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->filename : NULL, "filename", &err);
+    visit_type_str(m, obj ? &(*obj)->format : NULL, "format", &err);
+    visit_type_int(m, obj ? &(*obj)->check_errors : NULL, "check-errors", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_image_end_offset : NULL, "image-end-offset", &err);
+    if (obj && (*obj)->has_image_end_offset) {
+        visit_type_int(m, obj ? &(*obj)->image_end_offset : NULL, "image-end-offset", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_corruptions : NULL, "corruptions", &err);
+    if (obj && (*obj)->has_corruptions) {
+        visit_type_int(m, obj ? &(*obj)->corruptions : NULL, "corruptions", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_leaks : NULL, "leaks", &err);
+    if (obj && (*obj)->has_leaks) {
+        visit_type_int(m, obj ? &(*obj)->leaks : NULL, "leaks", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_corruptions_fixed : NULL, "corruptions-fixed", &err);
+    if (obj && (*obj)->has_corruptions_fixed) {
+        visit_type_int(m, obj ? &(*obj)->corruptions_fixed : NULL, "corruptions-fixed", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_leaks_fixed : NULL, "leaks-fixed", &err);
+    if (obj && (*obj)->has_leaks_fixed) {
+        visit_type_int(m, obj ? &(*obj)->leaks_fixed : NULL, "leaks-fixed", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_total_clusters : NULL, "total-clusters", &err);
+    if (obj && (*obj)->has_total_clusters) {
+        visit_type_int(m, obj ? &(*obj)->total_clusters : NULL, "total-clusters", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_allocated_clusters : NULL, "allocated-clusters", &err);
+    if (obj && (*obj)->has_allocated_clusters) {
+        visit_type_int(m, obj ? &(*obj)->allocated_clusters : NULL, "allocated-clusters", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_fragmented_clusters : NULL, "fragmented-clusters", &err);
+    if (obj && (*obj)->has_fragmented_clusters) {
+        visit_type_int(m, obj ? &(*obj)->fragmented_clusters : NULL, "fragmented-clusters", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_compressed_clusters : NULL, "compressed-clusters", &err);
+    if (obj && (*obj)->has_compressed_clusters) {
+        visit_type_int(m, obj ? &(*obj)->compressed_clusters : NULL, "compressed-clusters", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ImageCheck(Visitor *m, ImageCheck ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ImageCheck", name, sizeof(ImageCheck), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ImageCheck_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ImageCheckList(Visitor *m, ImageCheckList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ImageCheckList *native_i = (ImageCheckList *)i;
+                visit_type_ImageCheck(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_StatusInfo_fields(Visitor *m, StatusInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_bool(m, obj ? &(*obj)->running : NULL, "running", &err);
+    visit_type_bool(m, obj ? &(*obj)->singlestep : NULL, "singlestep", &err);
+    visit_type_RunState(m, obj ? &(*obj)->status : NULL, "status", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_StatusInfo(Visitor *m, StatusInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "StatusInfo", name, sizeof(StatusInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_StatusInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_StatusInfoList(Visitor *m, StatusInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                StatusInfoList *native_i = (StatusInfoList *)i;
+                visit_type_StatusInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_UuidInfo_fields(Visitor *m, UuidInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->UUID : NULL, "UUID", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_UuidInfo(Visitor *m, UuidInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "UuidInfo", name, sizeof(UuidInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_UuidInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_UuidInfoList(Visitor *m, UuidInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                UuidInfoList *native_i = (UuidInfoList *)i;
+                visit_type_UuidInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevInfo_fields(Visitor *m, ChardevInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->label : NULL, "label", &err);
+    visit_type_str(m, obj ? &(*obj)->filename : NULL, "filename", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevInfo(Visitor *m, ChardevInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevInfo", name, sizeof(ChardevInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevInfoList(Visitor *m, ChardevInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevInfoList *native_i = (ChardevInfoList *)i;
+                visit_type_ChardevInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_DataFormatList(Visitor *m, DataFormatList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                DataFormatList *native_i = (DataFormatList *)i;
+                visit_type_DataFormat(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_DataFormat(Visitor *m, DataFormat * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, DataFormat_lookup, "DataFormat", name, errp);
+}
+
+static void visit_type_CommandInfo_fields(Visitor *m, CommandInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_CommandInfo(Visitor *m, CommandInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "CommandInfo", name, sizeof(CommandInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_CommandInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_CommandInfoList(Visitor *m, CommandInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                CommandInfoList *native_i = (CommandInfoList *)i;
+                visit_type_CommandInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_EventInfo_fields(Visitor *m, EventInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_EventInfo(Visitor *m, EventInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "EventInfo", name, sizeof(EventInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_EventInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_EventInfoList(Visitor *m, EventInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                EventInfoList *native_i = (EventInfoList *)i;
+                visit_type_EventInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_MigrationStats_fields(Visitor *m, MigrationStats ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->transferred : NULL, "transferred", &err);
+    visit_type_int(m, obj ? &(*obj)->remaining : NULL, "remaining", &err);
+    visit_type_int(m, obj ? &(*obj)->total : NULL, "total", &err);
+    visit_type_int(m, obj ? &(*obj)->duplicate : NULL, "duplicate", &err);
+    visit_type_int(m, obj ? &(*obj)->skipped : NULL, "skipped", &err);
+    visit_type_int(m, obj ? &(*obj)->normal : NULL, "normal", &err);
+    visit_type_int(m, obj ? &(*obj)->normal_bytes : NULL, "normal-bytes", &err);
+    visit_type_int(m, obj ? &(*obj)->dirty_pages_rate : NULL, "dirty-pages-rate", &err);
+    visit_type_number(m, obj ? &(*obj)->mbps : NULL, "mbps", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_MigrationStats(Visitor *m, MigrationStats ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "MigrationStats", name, sizeof(MigrationStats), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_MigrationStats_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_MigrationStatsList(Visitor *m, MigrationStatsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                MigrationStatsList *native_i = (MigrationStatsList *)i;
+                visit_type_MigrationStats(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_XBZRLECacheStats_fields(Visitor *m, XBZRLECacheStats ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->cache_size : NULL, "cache-size", &err);
+    visit_type_int(m, obj ? &(*obj)->bytes : NULL, "bytes", &err);
+    visit_type_int(m, obj ? &(*obj)->pages : NULL, "pages", &err);
+    visit_type_int(m, obj ? &(*obj)->cache_miss : NULL, "cache-miss", &err);
+    visit_type_int(m, obj ? &(*obj)->overflow : NULL, "overflow", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_XBZRLECacheStats(Visitor *m, XBZRLECacheStats ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "XBZRLECacheStats", name, sizeof(XBZRLECacheStats), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_XBZRLECacheStats_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_XBZRLECacheStatsList(Visitor *m, XBZRLECacheStatsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                XBZRLECacheStatsList *native_i = (XBZRLECacheStatsList *)i;
+                visit_type_XBZRLECacheStats(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_MigrationInfo_fields(Visitor *m, MigrationInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_status : NULL, "status", &err);
+    if (obj && (*obj)->has_status) {
+        visit_type_str(m, obj ? &(*obj)->status : NULL, "status", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_ram : NULL, "ram", &err);
+    if (obj && (*obj)->has_ram) {
+        visit_type_MigrationStats(m, obj ? &(*obj)->ram : NULL, "ram", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_disk : NULL, "disk", &err);
+    if (obj && (*obj)->has_disk) {
+        visit_type_MigrationStats(m, obj ? &(*obj)->disk : NULL, "disk", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_xbzrle_cache : NULL, "xbzrle-cache", &err);
+    if (obj && (*obj)->has_xbzrle_cache) {
+        visit_type_XBZRLECacheStats(m, obj ? &(*obj)->xbzrle_cache : NULL, "xbzrle-cache", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_total_time : NULL, "total-time", &err);
+    if (obj && (*obj)->has_total_time) {
+        visit_type_int(m, obj ? &(*obj)->total_time : NULL, "total-time", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_expected_downtime : NULL, "expected-downtime", &err);
+    if (obj && (*obj)->has_expected_downtime) {
+        visit_type_int(m, obj ? &(*obj)->expected_downtime : NULL, "expected-downtime", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_downtime : NULL, "downtime", &err);
+    if (obj && (*obj)->has_downtime) {
+        visit_type_int(m, obj ? &(*obj)->downtime : NULL, "downtime", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_setup_time : NULL, "setup-time", &err);
+    if (obj && (*obj)->has_setup_time) {
+        visit_type_int(m, obj ? &(*obj)->setup_time : NULL, "setup-time", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_MigrationInfo(Visitor *m, MigrationInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "MigrationInfo", name, sizeof(MigrationInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_MigrationInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_MigrationInfoList(Visitor *m, MigrationInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                MigrationInfoList *native_i = (MigrationInfoList *)i;
+                visit_type_MigrationInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_MigrationCapabilityList(Visitor *m, MigrationCapabilityList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                MigrationCapabilityList *native_i = (MigrationCapabilityList *)i;
+                visit_type_MigrationCapability(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_MigrationCapability(Visitor *m, MigrationCapability * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, MigrationCapability_lookup, "MigrationCapability", name, errp);
+}
+
+static void visit_type_MigrationCapabilityStatus_fields(Visitor *m, MigrationCapabilityStatus ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_MigrationCapability(m, obj ? &(*obj)->capability : NULL, "capability", &err);
+    visit_type_bool(m, obj ? &(*obj)->state : NULL, "state", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_MigrationCapabilityStatus(Visitor *m, MigrationCapabilityStatus ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "MigrationCapabilityStatus", name, sizeof(MigrationCapabilityStatus), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_MigrationCapabilityStatus_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_MigrationCapabilityStatusList(Visitor *m, MigrationCapabilityStatusList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                MigrationCapabilityStatusList *native_i = (MigrationCapabilityStatusList *)i;
+                visit_type_MigrationCapabilityStatus(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_MouseInfo_fields(Visitor *m, MouseInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+    visit_type_int(m, obj ? &(*obj)->index : NULL, "index", &err);
+    visit_type_bool(m, obj ? &(*obj)->current : NULL, "current", &err);
+    visit_type_bool(m, obj ? &(*obj)->absolute : NULL, "absolute", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_MouseInfo(Visitor *m, MouseInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "MouseInfo", name, sizeof(MouseInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_MouseInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_MouseInfoList(Visitor *m, MouseInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                MouseInfoList *native_i = (MouseInfoList *)i;
+                visit_type_MouseInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_CpuInfo_fields(Visitor *m, CpuInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->CPU : NULL, "CPU", &err);
+    visit_type_bool(m, obj ? &(*obj)->current : NULL, "current", &err);
+    visit_type_bool(m, obj ? &(*obj)->halted : NULL, "halted", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_pc : NULL, "pc", &err);
+    if (obj && (*obj)->has_pc) {
+        visit_type_int(m, obj ? &(*obj)->pc : NULL, "pc", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_nip : NULL, "nip", &err);
+    if (obj && (*obj)->has_nip) {
+        visit_type_int(m, obj ? &(*obj)->nip : NULL, "nip", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_npc : NULL, "npc", &err);
+    if (obj && (*obj)->has_npc) {
+        visit_type_int(m, obj ? &(*obj)->npc : NULL, "npc", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_PC : NULL, "PC", &err);
+    if (obj && (*obj)->has_PC) {
+        visit_type_int(m, obj ? &(*obj)->PC : NULL, "PC", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_int(m, obj ? &(*obj)->thread_id : NULL, "thread_id", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_CpuInfo(Visitor *m, CpuInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "CpuInfo", name, sizeof(CpuInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_CpuInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_CpuInfoList(Visitor *m, CpuInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                CpuInfoList *native_i = (CpuInfoList *)i;
+                visit_type_CpuInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockDeviceInfo_fields(Visitor *m, BlockDeviceInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->file : NULL, "file", &err);
+    visit_type_bool(m, obj ? &(*obj)->ro : NULL, "ro", &err);
+    visit_type_str(m, obj ? &(*obj)->drv : NULL, "drv", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_backing_file : NULL, "backing_file", &err);
+    if (obj && (*obj)->has_backing_file) {
+        visit_type_str(m, obj ? &(*obj)->backing_file : NULL, "backing_file", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_int(m, obj ? &(*obj)->backing_file_depth : NULL, "backing_file_depth", &err);
+    visit_type_bool(m, obj ? &(*obj)->encrypted : NULL, "encrypted", &err);
+    visit_type_bool(m, obj ? &(*obj)->encryption_key_missing : NULL, "encryption_key_missing", &err);
+    visit_type_int(m, obj ? &(*obj)->bps : NULL, "bps", &err);
+    visit_type_int(m, obj ? &(*obj)->bps_rd : NULL, "bps_rd", &err);
+    visit_type_int(m, obj ? &(*obj)->bps_wr : NULL, "bps_wr", &err);
+    visit_type_int(m, obj ? &(*obj)->iops : NULL, "iops", &err);
+    visit_type_int(m, obj ? &(*obj)->iops_rd : NULL, "iops_rd", &err);
+    visit_type_int(m, obj ? &(*obj)->iops_wr : NULL, "iops_wr", &err);
+    visit_type_ImageInfo(m, obj ? &(*obj)->image : NULL, "image", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_bps_max : NULL, "bps_max", &err);
+    if (obj && (*obj)->has_bps_max) {
+        visit_type_int(m, obj ? &(*obj)->bps_max : NULL, "bps_max", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_bps_rd_max : NULL, "bps_rd_max", &err);
+    if (obj && (*obj)->has_bps_rd_max) {
+        visit_type_int(m, obj ? &(*obj)->bps_rd_max : NULL, "bps_rd_max", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_bps_wr_max : NULL, "bps_wr_max", &err);
+    if (obj && (*obj)->has_bps_wr_max) {
+        visit_type_int(m, obj ? &(*obj)->bps_wr_max : NULL, "bps_wr_max", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_iops_max : NULL, "iops_max", &err);
+    if (obj && (*obj)->has_iops_max) {
+        visit_type_int(m, obj ? &(*obj)->iops_max : NULL, "iops_max", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_iops_rd_max : NULL, "iops_rd_max", &err);
+    if (obj && (*obj)->has_iops_rd_max) {
+        visit_type_int(m, obj ? &(*obj)->iops_rd_max : NULL, "iops_rd_max", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_iops_wr_max : NULL, "iops_wr_max", &err);
+    if (obj && (*obj)->has_iops_wr_max) {
+        visit_type_int(m, obj ? &(*obj)->iops_wr_max : NULL, "iops_wr_max", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_iops_size : NULL, "iops_size", &err);
+    if (obj && (*obj)->has_iops_size) {
+        visit_type_int(m, obj ? &(*obj)->iops_size : NULL, "iops_size", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockDeviceInfo(Visitor *m, BlockDeviceInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockDeviceInfo", name, sizeof(BlockDeviceInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockDeviceInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockDeviceInfoList(Visitor *m, BlockDeviceInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockDeviceInfoList *native_i = (BlockDeviceInfoList *)i;
+                visit_type_BlockDeviceInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockDeviceIoStatusList(Visitor *m, BlockDeviceIoStatusList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockDeviceIoStatusList *native_i = (BlockDeviceIoStatusList *)i;
+                visit_type_BlockDeviceIoStatus(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockDeviceIoStatus(Visitor *m, BlockDeviceIoStatus * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, BlockDeviceIoStatus_lookup, "BlockDeviceIoStatus", name, errp);
+}
+
+static void visit_type_BlockDeviceMapEntry_fields(Visitor *m, BlockDeviceMapEntry ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->start : NULL, "start", &err);
+    visit_type_int(m, obj ? &(*obj)->length : NULL, "length", &err);
+    visit_type_int(m, obj ? &(*obj)->depth : NULL, "depth", &err);
+    visit_type_bool(m, obj ? &(*obj)->zero : NULL, "zero", &err);
+    visit_type_bool(m, obj ? &(*obj)->data : NULL, "data", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_offset : NULL, "offset", &err);
+    if (obj && (*obj)->has_offset) {
+        visit_type_int(m, obj ? &(*obj)->offset : NULL, "offset", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockDeviceMapEntry(Visitor *m, BlockDeviceMapEntry ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockDeviceMapEntry", name, sizeof(BlockDeviceMapEntry), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockDeviceMapEntry_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockDeviceMapEntryList(Visitor *m, BlockDeviceMapEntryList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockDeviceMapEntryList *native_i = (BlockDeviceMapEntryList *)i;
+                visit_type_BlockDeviceMapEntry(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockDirtyInfo_fields(Visitor *m, BlockDirtyInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->count : NULL, "count", &err);
+    visit_type_int(m, obj ? &(*obj)->granularity : NULL, "granularity", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockDirtyInfo(Visitor *m, BlockDirtyInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockDirtyInfo", name, sizeof(BlockDirtyInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockDirtyInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockDirtyInfoList(Visitor *m, BlockDirtyInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockDirtyInfoList *native_i = (BlockDirtyInfoList *)i;
+                visit_type_BlockDirtyInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockInfo_fields(Visitor *m, BlockInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->device : NULL, "device", &err);
+    visit_type_str(m, obj ? &(*obj)->type : NULL, "type", &err);
+    visit_type_bool(m, obj ? &(*obj)->removable : NULL, "removable", &err);
+    visit_type_bool(m, obj ? &(*obj)->locked : NULL, "locked", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_inserted : NULL, "inserted", &err);
+    if (obj && (*obj)->has_inserted) {
+        visit_type_BlockDeviceInfo(m, obj ? &(*obj)->inserted : NULL, "inserted", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_tray_open : NULL, "tray_open", &err);
+    if (obj && (*obj)->has_tray_open) {
+        visit_type_bool(m, obj ? &(*obj)->tray_open : NULL, "tray_open", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_io_status : NULL, "io-status", &err);
+    if (obj && (*obj)->has_io_status) {
+        visit_type_BlockDeviceIoStatus(m, obj ? &(*obj)->io_status : NULL, "io-status", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_dirty_bitmaps : NULL, "dirty-bitmaps", &err);
+    if (obj && (*obj)->has_dirty_bitmaps) {
+        visit_type_BlockDirtyInfoList(m, obj ? &(*obj)->dirty_bitmaps : NULL, "dirty-bitmaps", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockInfo(Visitor *m, BlockInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockInfo", name, sizeof(BlockInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockInfoList(Visitor *m, BlockInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockInfoList *native_i = (BlockInfoList *)i;
+                visit_type_BlockInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockDeviceStats_fields(Visitor *m, BlockDeviceStats ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->rd_bytes : NULL, "rd_bytes", &err);
+    visit_type_int(m, obj ? &(*obj)->wr_bytes : NULL, "wr_bytes", &err);
+    visit_type_int(m, obj ? &(*obj)->rd_operations : NULL, "rd_operations", &err);
+    visit_type_int(m, obj ? &(*obj)->wr_operations : NULL, "wr_operations", &err);
+    visit_type_int(m, obj ? &(*obj)->flush_operations : NULL, "flush_operations", &err);
+    visit_type_int(m, obj ? &(*obj)->flush_total_time_ns : NULL, "flush_total_time_ns", &err);
+    visit_type_int(m, obj ? &(*obj)->wr_total_time_ns : NULL, "wr_total_time_ns", &err);
+    visit_type_int(m, obj ? &(*obj)->rd_total_time_ns : NULL, "rd_total_time_ns", &err);
+    visit_type_int(m, obj ? &(*obj)->wr_highest_offset : NULL, "wr_highest_offset", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockDeviceStats(Visitor *m, BlockDeviceStats ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockDeviceStats", name, sizeof(BlockDeviceStats), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockDeviceStats_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockDeviceStatsList(Visitor *m, BlockDeviceStatsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockDeviceStatsList *native_i = (BlockDeviceStatsList *)i;
+                visit_type_BlockDeviceStats(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockStats_fields(Visitor *m, BlockStats ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_device : NULL, "device", &err);
+    if (obj && (*obj)->has_device) {
+        visit_type_str(m, obj ? &(*obj)->device : NULL, "device", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_BlockDeviceStats(m, obj ? &(*obj)->stats : NULL, "stats", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_parent : NULL, "parent", &err);
+    if (obj && (*obj)->has_parent) {
+        visit_type_BlockStats(m, obj ? &(*obj)->parent : NULL, "parent", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockStats(Visitor *m, BlockStats ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockStats", name, sizeof(BlockStats), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockStats_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockStatsList(Visitor *m, BlockStatsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockStatsList *native_i = (BlockStatsList *)i;
+                visit_type_BlockStats(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_VncClientInfo_fields(Visitor *m, VncClientInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->host : NULL, "host", &err);
+    visit_type_str(m, obj ? &(*obj)->family : NULL, "family", &err);
+    visit_type_str(m, obj ? &(*obj)->service : NULL, "service", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_x509_dname : NULL, "x509_dname", &err);
+    if (obj && (*obj)->has_x509_dname) {
+        visit_type_str(m, obj ? &(*obj)->x509_dname : NULL, "x509_dname", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_sasl_username : NULL, "sasl_username", &err);
+    if (obj && (*obj)->has_sasl_username) {
+        visit_type_str(m, obj ? &(*obj)->sasl_username : NULL, "sasl_username", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_VncClientInfo(Visitor *m, VncClientInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "VncClientInfo", name, sizeof(VncClientInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_VncClientInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_VncClientInfoList(Visitor *m, VncClientInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                VncClientInfoList *native_i = (VncClientInfoList *)i;
+                visit_type_VncClientInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_VncInfo_fields(Visitor *m, VncInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_bool(m, obj ? &(*obj)->enabled : NULL, "enabled", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_host : NULL, "host", &err);
+    if (obj && (*obj)->has_host) {
+        visit_type_str(m, obj ? &(*obj)->host : NULL, "host", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_family : NULL, "family", &err);
+    if (obj && (*obj)->has_family) {
+        visit_type_str(m, obj ? &(*obj)->family : NULL, "family", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_service : NULL, "service", &err);
+    if (obj && (*obj)->has_service) {
+        visit_type_str(m, obj ? &(*obj)->service : NULL, "service", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_auth : NULL, "auth", &err);
+    if (obj && (*obj)->has_auth) {
+        visit_type_str(m, obj ? &(*obj)->auth : NULL, "auth", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_clients : NULL, "clients", &err);
+    if (obj && (*obj)->has_clients) {
+        visit_type_VncClientInfoList(m, obj ? &(*obj)->clients : NULL, "clients", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_VncInfo(Visitor *m, VncInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "VncInfo", name, sizeof(VncInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_VncInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_VncInfoList(Visitor *m, VncInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                VncInfoList *native_i = (VncInfoList *)i;
+                visit_type_VncInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_SpiceChannel_fields(Visitor *m, SpiceChannel ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->host : NULL, "host", &err);
+    visit_type_str(m, obj ? &(*obj)->family : NULL, "family", &err);
+    visit_type_str(m, obj ? &(*obj)->port : NULL, "port", &err);
+    visit_type_int(m, obj ? &(*obj)->connection_id : NULL, "connection-id", &err);
+    visit_type_int(m, obj ? &(*obj)->channel_type : NULL, "channel-type", &err);
+    visit_type_int(m, obj ? &(*obj)->channel_id : NULL, "channel-id", &err);
+    visit_type_bool(m, obj ? &(*obj)->tls : NULL, "tls", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_SpiceChannel(Visitor *m, SpiceChannel ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "SpiceChannel", name, sizeof(SpiceChannel), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_SpiceChannel_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_SpiceChannelList(Visitor *m, SpiceChannelList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                SpiceChannelList *native_i = (SpiceChannelList *)i;
+                visit_type_SpiceChannel(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_SpiceQueryMouseModeList(Visitor *m, SpiceQueryMouseModeList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                SpiceQueryMouseModeList *native_i = (SpiceQueryMouseModeList *)i;
+                visit_type_SpiceQueryMouseMode(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_SpiceQueryMouseMode(Visitor *m, SpiceQueryMouseMode * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, SpiceQueryMouseMode_lookup, "SpiceQueryMouseMode", name, errp);
+}
+
+static void visit_type_SpiceInfo_fields(Visitor *m, SpiceInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_bool(m, obj ? &(*obj)->enabled : NULL, "enabled", &err);
+    visit_type_bool(m, obj ? &(*obj)->migrated : NULL, "migrated", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_host : NULL, "host", &err);
+    if (obj && (*obj)->has_host) {
+        visit_type_str(m, obj ? &(*obj)->host : NULL, "host", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_port : NULL, "port", &err);
+    if (obj && (*obj)->has_port) {
+        visit_type_int(m, obj ? &(*obj)->port : NULL, "port", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_tls_port : NULL, "tls-port", &err);
+    if (obj && (*obj)->has_tls_port) {
+        visit_type_int(m, obj ? &(*obj)->tls_port : NULL, "tls-port", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_auth : NULL, "auth", &err);
+    if (obj && (*obj)->has_auth) {
+        visit_type_str(m, obj ? &(*obj)->auth : NULL, "auth", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_compiled_version : NULL, "compiled-version", &err);
+    if (obj && (*obj)->has_compiled_version) {
+        visit_type_str(m, obj ? &(*obj)->compiled_version : NULL, "compiled-version", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_SpiceQueryMouseMode(m, obj ? &(*obj)->mouse_mode : NULL, "mouse-mode", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_channels : NULL, "channels", &err);
+    if (obj && (*obj)->has_channels) {
+        visit_type_SpiceChannelList(m, obj ? &(*obj)->channels : NULL, "channels", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_SpiceInfo(Visitor *m, SpiceInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "SpiceInfo", name, sizeof(SpiceInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_SpiceInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_SpiceInfoList(Visitor *m, SpiceInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                SpiceInfoList *native_i = (SpiceInfoList *)i;
+                visit_type_SpiceInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BalloonInfo_fields(Visitor *m, BalloonInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->actual : NULL, "actual", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BalloonInfo(Visitor *m, BalloonInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BalloonInfo", name, sizeof(BalloonInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BalloonInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BalloonInfoList(Visitor *m, BalloonInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BalloonInfoList *native_i = (BalloonInfoList *)i;
+                visit_type_BalloonInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_PciMemoryRange_fields(Visitor *m, PciMemoryRange ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->base : NULL, "base", &err);
+    visit_type_int(m, obj ? &(*obj)->limit : NULL, "limit", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_PciMemoryRange(Visitor *m, PciMemoryRange ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "PciMemoryRange", name, sizeof(PciMemoryRange), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_PciMemoryRange_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_PciMemoryRangeList(Visitor *m, PciMemoryRangeList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                PciMemoryRangeList *native_i = (PciMemoryRangeList *)i;
+                visit_type_PciMemoryRange(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_PciMemoryRegion_fields(Visitor *m, PciMemoryRegion ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->bar : NULL, "bar", &err);
+    visit_type_str(m, obj ? &(*obj)->type : NULL, "type", &err);
+    visit_type_int(m, obj ? &(*obj)->address : NULL, "address", &err);
+    visit_type_int(m, obj ? &(*obj)->size : NULL, "size", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_prefetch : NULL, "prefetch", &err);
+    if (obj && (*obj)->has_prefetch) {
+        visit_type_bool(m, obj ? &(*obj)->prefetch : NULL, "prefetch", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_mem_type_64 : NULL, "mem_type_64", &err);
+    if (obj && (*obj)->has_mem_type_64) {
+        visit_type_bool(m, obj ? &(*obj)->mem_type_64 : NULL, "mem_type_64", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_PciMemoryRegion(Visitor *m, PciMemoryRegion ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "PciMemoryRegion", name, sizeof(PciMemoryRegion), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_PciMemoryRegion_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_PciMemoryRegionList(Visitor *m, PciMemoryRegionList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                PciMemoryRegionList *native_i = (PciMemoryRegionList *)i;
+                visit_type_PciMemoryRegion(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_PciBridgeInfo_bus_fields(Visitor *m, PciBridgeInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->bus.number : NULL, "number", &err);
+    visit_type_int(m, obj ? &(*obj)->bus.secondary : NULL, "secondary", &err);
+    visit_type_int(m, obj ? &(*obj)->bus.subordinate : NULL, "subordinate", &err);
+    visit_type_PciMemoryRange(m, obj ? &(*obj)->bus.io_range : NULL, "io_range", &err);
+    visit_type_PciMemoryRange(m, obj ? &(*obj)->bus.memory_range : NULL, "memory_range", &err);
+    visit_type_PciMemoryRange(m, obj ? &(*obj)->bus.prefetchable_range : NULL, "prefetchable_range", &err);
+
+    error_propagate(errp, err);
+}
+
+static void visit_type_PciBridgeInfo_fields(Visitor *m, PciBridgeInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    if (!error_is_set(errp)) {
+        Error **errp = &err; /* from outer scope */
+        Error *err = NULL;
+        visit_start_struct(m, NULL, "", "bus", 0, &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_PciBridgeInfo_bus_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+    visit_start_optional(m, obj ? &(*obj)->has_devices : NULL, "devices", &err);
+    if (obj && (*obj)->has_devices) {
+        visit_type_PciDeviceInfoList(m, obj ? &(*obj)->devices : NULL, "devices", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_PciBridgeInfo(Visitor *m, PciBridgeInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "PciBridgeInfo", name, sizeof(PciBridgeInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_PciBridgeInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_PciBridgeInfoList(Visitor *m, PciBridgeInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                PciBridgeInfoList *native_i = (PciBridgeInfoList *)i;
+                visit_type_PciBridgeInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_PciDeviceInfo_class_info_fields(Visitor *m, PciDeviceInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->class_info.has_desc : NULL, "desc", &err);
+    if (obj && (*obj)->class_info.has_desc) {
+        visit_type_str(m, obj ? &(*obj)->class_info.desc : NULL, "desc", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_int(m, obj ? &(*obj)->class_info.q_class : NULL, "class", &err);
+
+    error_propagate(errp, err);
+}
+
+static void visit_type_PciDeviceInfo_id_fields(Visitor *m, PciDeviceInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->id.device : NULL, "device", &err);
+    visit_type_int(m, obj ? &(*obj)->id.vendor : NULL, "vendor", &err);
+
+    error_propagate(errp, err);
+}
+
+static void visit_type_PciDeviceInfo_fields(Visitor *m, PciDeviceInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->bus : NULL, "bus", &err);
+    visit_type_int(m, obj ? &(*obj)->slot : NULL, "slot", &err);
+    visit_type_int(m, obj ? &(*obj)->function : NULL, "function", &err);
+    if (!error_is_set(errp)) {
+        Error **errp = &err; /* from outer scope */
+        Error *err = NULL;
+        visit_start_struct(m, NULL, "", "class_info", 0, &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_PciDeviceInfo_class_info_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+    if (!error_is_set(errp)) {
+        Error **errp = &err; /* from outer scope */
+        Error *err = NULL;
+        visit_start_struct(m, NULL, "", "id", 0, &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_PciDeviceInfo_id_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+    visit_start_optional(m, obj ? &(*obj)->has_irq : NULL, "irq", &err);
+    if (obj && (*obj)->has_irq) {
+        visit_type_int(m, obj ? &(*obj)->irq : NULL, "irq", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_str(m, obj ? &(*obj)->qdev_id : NULL, "qdev_id", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_pci_bridge : NULL, "pci_bridge", &err);
+    if (obj && (*obj)->has_pci_bridge) {
+        visit_type_PciBridgeInfo(m, obj ? &(*obj)->pci_bridge : NULL, "pci_bridge", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_PciMemoryRegionList(m, obj ? &(*obj)->regions : NULL, "regions", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_PciDeviceInfo(Visitor *m, PciDeviceInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "PciDeviceInfo", name, sizeof(PciDeviceInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_PciDeviceInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_PciDeviceInfoList(Visitor *m, PciDeviceInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                PciDeviceInfoList *native_i = (PciDeviceInfoList *)i;
+                visit_type_PciDeviceInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_PciInfo_fields(Visitor *m, PciInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->bus : NULL, "bus", &err);
+    visit_type_PciDeviceInfoList(m, obj ? &(*obj)->devices : NULL, "devices", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_PciInfo(Visitor *m, PciInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "PciInfo", name, sizeof(PciInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_PciInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_PciInfoList(Visitor *m, PciInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                PciInfoList *native_i = (PciInfoList *)i;
+                visit_type_PciInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevOnErrorList(Visitor *m, BlockdevOnErrorList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevOnErrorList *native_i = (BlockdevOnErrorList *)i;
+                visit_type_BlockdevOnError(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevOnError(Visitor *m, BlockdevOnError * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, BlockdevOnError_lookup, "BlockdevOnError", name, errp);
+}
+
+void visit_type_MirrorSyncModeList(Visitor *m, MirrorSyncModeList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                MirrorSyncModeList *native_i = (MirrorSyncModeList *)i;
+                visit_type_MirrorSyncMode(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_MirrorSyncMode(Visitor *m, MirrorSyncMode * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, MirrorSyncMode_lookup, "MirrorSyncMode", name, errp);
+}
+
+void visit_type_BlockJobTypeList(Visitor *m, BlockJobTypeList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockJobTypeList *native_i = (BlockJobTypeList *)i;
+                visit_type_BlockJobType(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockJobType(Visitor *m, BlockJobType * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, BlockJobType_lookup, "BlockJobType", name, errp);
+}
+
+static void visit_type_BlockJobInfo_fields(Visitor *m, BlockJobInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->type : NULL, "type", &err);
+    visit_type_str(m, obj ? &(*obj)->device : NULL, "device", &err);
+    visit_type_int(m, obj ? &(*obj)->len : NULL, "len", &err);
+    visit_type_int(m, obj ? &(*obj)->offset : NULL, "offset", &err);
+    visit_type_bool(m, obj ? &(*obj)->busy : NULL, "busy", &err);
+    visit_type_bool(m, obj ? &(*obj)->paused : NULL, "paused", &err);
+    visit_type_int(m, obj ? &(*obj)->speed : NULL, "speed", &err);
+    visit_type_BlockDeviceIoStatus(m, obj ? &(*obj)->io_status : NULL, "io-status", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockJobInfo(Visitor *m, BlockJobInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockJobInfo", name, sizeof(BlockJobInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockJobInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockJobInfoList(Visitor *m, BlockJobInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockJobInfoList *native_i = (BlockJobInfoList *)i;
+                visit_type_BlockJobInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NewImageModeList(Visitor *m, NewImageModeList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NewImageModeList *native_i = (NewImageModeList *)i;
+                visit_type_NewImageMode(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NewImageMode(Visitor *m, NewImageMode * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, NewImageMode_lookup, "NewImageMode", name, errp);
+}
+
+static void visit_type_BlockdevSnapshot_fields(Visitor *m, BlockdevSnapshot ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->device : NULL, "device", &err);
+    visit_type_str(m, obj ? &(*obj)->snapshot_file : NULL, "snapshot-file", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_format : NULL, "format", &err);
+    if (obj && (*obj)->has_format) {
+        visit_type_str(m, obj ? &(*obj)->format : NULL, "format", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_mode : NULL, "mode", &err);
+    if (obj && (*obj)->has_mode) {
+        visit_type_NewImageMode(m, obj ? &(*obj)->mode : NULL, "mode", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockdevSnapshot(Visitor *m, BlockdevSnapshot ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockdevSnapshot", name, sizeof(BlockdevSnapshot), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockdevSnapshot_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevSnapshotList(Visitor *m, BlockdevSnapshotList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevSnapshotList *native_i = (BlockdevSnapshotList *)i;
+                visit_type_BlockdevSnapshot(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockdevSnapshotInternal_fields(Visitor *m, BlockdevSnapshotInternal ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->device : NULL, "device", &err);
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockdevSnapshotInternal(Visitor *m, BlockdevSnapshotInternal ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockdevSnapshotInternal", name, sizeof(BlockdevSnapshotInternal), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockdevSnapshotInternal_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevSnapshotInternalList(Visitor *m, BlockdevSnapshotInternalList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevSnapshotInternalList *native_i = (BlockdevSnapshotInternalList *)i;
+                visit_type_BlockdevSnapshotInternal(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_DriveBackup_fields(Visitor *m, DriveBackup ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->device : NULL, "device", &err);
+    visit_type_str(m, obj ? &(*obj)->target : NULL, "target", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_format : NULL, "format", &err);
+    if (obj && (*obj)->has_format) {
+        visit_type_str(m, obj ? &(*obj)->format : NULL, "format", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_MirrorSyncMode(m, obj ? &(*obj)->sync : NULL, "sync", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_mode : NULL, "mode", &err);
+    if (obj && (*obj)->has_mode) {
+        visit_type_NewImageMode(m, obj ? &(*obj)->mode : NULL, "mode", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_speed : NULL, "speed", &err);
+    if (obj && (*obj)->has_speed) {
+        visit_type_int(m, obj ? &(*obj)->speed : NULL, "speed", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_on_source_error : NULL, "on-source-error", &err);
+    if (obj && (*obj)->has_on_source_error) {
+        visit_type_BlockdevOnError(m, obj ? &(*obj)->on_source_error : NULL, "on-source-error", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_on_target_error : NULL, "on-target-error", &err);
+    if (obj && (*obj)->has_on_target_error) {
+        visit_type_BlockdevOnError(m, obj ? &(*obj)->on_target_error : NULL, "on-target-error", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_DriveBackup(Visitor *m, DriveBackup ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "DriveBackup", name, sizeof(DriveBackup), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_DriveBackup_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_DriveBackupList(Visitor *m, DriveBackupList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                DriveBackupList *native_i = (DriveBackupList *)i;
+                visit_type_DriveBackup(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_Abort_fields(Visitor *m, Abort ** obj, Error **errp)
+{
+    Error *err = NULL;
+
+    error_propagate(errp, err);
+}
+
+void visit_type_Abort(Visitor *m, Abort ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "Abort", name, sizeof(Abort), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_Abort_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_AbortList(Visitor *m, AbortList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                AbortList *native_i = (AbortList *)i;
+                visit_type_Abort(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_TransactionActionKind(Visitor *m, TransactionActionKind * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, TransactionActionKind_lookup, "TransactionActionKind", name, errp);
+}
+
+void visit_type_TransactionAction(Visitor *m, TransactionAction ** obj, const char *name, Error **errp)
+{
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_struct(m, (void **)obj, "TransactionAction", name, sizeof(TransactionAction), &err);
+        if (!err) {
+            if (obj && *obj) {
+                visit_type_TransactionActionKind(m, &(*obj)->kind, "type", &err);
+                if (!err) {
+                    switch ((*obj)->kind) {
+                    case TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC:
+                        visit_type_BlockdevSnapshot(m, &(*obj)->blockdev_snapshot_sync, "data", &err);
+                        break;
+                    case TRANSACTION_ACTION_KIND_DRIVE_BACKUP:
+                        visit_type_DriveBackup(m, &(*obj)->drive_backup, "data", &err);
+                        break;
+                    case TRANSACTION_ACTION_KIND_ABORT:
+                        visit_type_Abort(m, &(*obj)->abort, "data", &err);
+                        break;
+                    case TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC:
+                        visit_type_BlockdevSnapshotInternal(m, &(*obj)->blockdev_snapshot_internal_sync, "data", &err);
+                        break;
+                    default:
+                        abort();
+                    }
+                }
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_TransactionActionList(Visitor *m, TransactionActionList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                TransactionActionList *native_i = (TransactionActionList *)i;
+                visit_type_TransactionAction(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ObjectPropertyInfo_fields(Visitor *m, ObjectPropertyInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+    visit_type_str(m, obj ? &(*obj)->type : NULL, "type", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ObjectPropertyInfo(Visitor *m, ObjectPropertyInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ObjectPropertyInfo", name, sizeof(ObjectPropertyInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ObjectPropertyInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ObjectPropertyInfoList(Visitor *m, ObjectPropertyInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ObjectPropertyInfoList *native_i = (ObjectPropertyInfoList *)i;
+                visit_type_ObjectPropertyInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ObjectTypeInfo_fields(Visitor *m, ObjectTypeInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ObjectTypeInfo(Visitor *m, ObjectTypeInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ObjectTypeInfo", name, sizeof(ObjectTypeInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ObjectTypeInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ObjectTypeInfoList(Visitor *m, ObjectTypeInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ObjectTypeInfoList *native_i = (ObjectTypeInfoList *)i;
+                visit_type_ObjectTypeInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_DevicePropertyInfo_fields(Visitor *m, DevicePropertyInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+    visit_type_str(m, obj ? &(*obj)->type : NULL, "type", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_DevicePropertyInfo(Visitor *m, DevicePropertyInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "DevicePropertyInfo", name, sizeof(DevicePropertyInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_DevicePropertyInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_DevicePropertyInfoList(Visitor *m, DevicePropertyInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                DevicePropertyInfoList *native_i = (DevicePropertyInfoList *)i;
+                visit_type_DevicePropertyInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_NetdevNoneOptions_fields(Visitor *m, NetdevNoneOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NetdevNoneOptions(Visitor *m, NetdevNoneOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NetdevNoneOptions", name, sizeof(NetdevNoneOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NetdevNoneOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetdevNoneOptionsList(Visitor *m, NetdevNoneOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetdevNoneOptionsList *native_i = (NetdevNoneOptionsList *)i;
+                visit_type_NetdevNoneOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_NetLegacyNicOptions_fields(Visitor *m, NetLegacyNicOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_netdev : NULL, "netdev", &err);
+    if (obj && (*obj)->has_netdev) {
+        visit_type_str(m, obj ? &(*obj)->netdev : NULL, "netdev", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_macaddr : NULL, "macaddr", &err);
+    if (obj && (*obj)->has_macaddr) {
+        visit_type_str(m, obj ? &(*obj)->macaddr : NULL, "macaddr", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_model : NULL, "model", &err);
+    if (obj && (*obj)->has_model) {
+        visit_type_str(m, obj ? &(*obj)->model : NULL, "model", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_addr : NULL, "addr", &err);
+    if (obj && (*obj)->has_addr) {
+        visit_type_str(m, obj ? &(*obj)->addr : NULL, "addr", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_vectors : NULL, "vectors", &err);
+    if (obj && (*obj)->has_vectors) {
+        visit_type_uint32(m, obj ? &(*obj)->vectors : NULL, "vectors", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NetLegacyNicOptions(Visitor *m, NetLegacyNicOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NetLegacyNicOptions", name, sizeof(NetLegacyNicOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NetLegacyNicOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetLegacyNicOptionsList(Visitor *m, NetLegacyNicOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetLegacyNicOptionsList *native_i = (NetLegacyNicOptionsList *)i;
+                visit_type_NetLegacyNicOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_String_fields(Visitor *m, String ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->str : NULL, "str", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_String(Visitor *m, String ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "String", name, sizeof(String), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_String_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_StringList(Visitor *m, StringList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                StringList *native_i = (StringList *)i;
+                visit_type_String(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_NetdevUserOptions_fields(Visitor *m, NetdevUserOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_hostname : NULL, "hostname", &err);
+    if (obj && (*obj)->has_hostname) {
+        visit_type_str(m, obj ? &(*obj)->hostname : NULL, "hostname", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_q_restrict : NULL, "restrict", &err);
+    if (obj && (*obj)->has_q_restrict) {
+        visit_type_bool(m, obj ? &(*obj)->q_restrict : NULL, "restrict", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_ip : NULL, "ip", &err);
+    if (obj && (*obj)->has_ip) {
+        visit_type_str(m, obj ? &(*obj)->ip : NULL, "ip", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_net : NULL, "net", &err);
+    if (obj && (*obj)->has_net) {
+        visit_type_str(m, obj ? &(*obj)->net : NULL, "net", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_host : NULL, "host", &err);
+    if (obj && (*obj)->has_host) {
+        visit_type_str(m, obj ? &(*obj)->host : NULL, "host", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_tftp : NULL, "tftp", &err);
+    if (obj && (*obj)->has_tftp) {
+        visit_type_str(m, obj ? &(*obj)->tftp : NULL, "tftp", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_bootfile : NULL, "bootfile", &err);
+    if (obj && (*obj)->has_bootfile) {
+        visit_type_str(m, obj ? &(*obj)->bootfile : NULL, "bootfile", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_dhcpstart : NULL, "dhcpstart", &err);
+    if (obj && (*obj)->has_dhcpstart) {
+        visit_type_str(m, obj ? &(*obj)->dhcpstart : NULL, "dhcpstart", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_dns : NULL, "dns", &err);
+    if (obj && (*obj)->has_dns) {
+        visit_type_str(m, obj ? &(*obj)->dns : NULL, "dns", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_dnssearch : NULL, "dnssearch", &err);
+    if (obj && (*obj)->has_dnssearch) {
+        visit_type_StringList(m, obj ? &(*obj)->dnssearch : NULL, "dnssearch", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_smb : NULL, "smb", &err);
+    if (obj && (*obj)->has_smb) {
+        visit_type_str(m, obj ? &(*obj)->smb : NULL, "smb", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_smbserver : NULL, "smbserver", &err);
+    if (obj && (*obj)->has_smbserver) {
+        visit_type_str(m, obj ? &(*obj)->smbserver : NULL, "smbserver", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_hostfwd : NULL, "hostfwd", &err);
+    if (obj && (*obj)->has_hostfwd) {
+        visit_type_StringList(m, obj ? &(*obj)->hostfwd : NULL, "hostfwd", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_guestfwd : NULL, "guestfwd", &err);
+    if (obj && (*obj)->has_guestfwd) {
+        visit_type_StringList(m, obj ? &(*obj)->guestfwd : NULL, "guestfwd", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NetdevUserOptions(Visitor *m, NetdevUserOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NetdevUserOptions", name, sizeof(NetdevUserOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NetdevUserOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetdevUserOptionsList(Visitor *m, NetdevUserOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetdevUserOptionsList *native_i = (NetdevUserOptionsList *)i;
+                visit_type_NetdevUserOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_NetdevTapOptions_fields(Visitor *m, NetdevTapOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_ifname : NULL, "ifname", &err);
+    if (obj && (*obj)->has_ifname) {
+        visit_type_str(m, obj ? &(*obj)->ifname : NULL, "ifname", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_fd : NULL, "fd", &err);
+    if (obj && (*obj)->has_fd) {
+        visit_type_str(m, obj ? &(*obj)->fd : NULL, "fd", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_fds : NULL, "fds", &err);
+    if (obj && (*obj)->has_fds) {
+        visit_type_str(m, obj ? &(*obj)->fds : NULL, "fds", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_script : NULL, "script", &err);
+    if (obj && (*obj)->has_script) {
+        visit_type_str(m, obj ? &(*obj)->script : NULL, "script", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_downscript : NULL, "downscript", &err);
+    if (obj && (*obj)->has_downscript) {
+        visit_type_str(m, obj ? &(*obj)->downscript : NULL, "downscript", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_helper : NULL, "helper", &err);
+    if (obj && (*obj)->has_helper) {
+        visit_type_str(m, obj ? &(*obj)->helper : NULL, "helper", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_sndbuf : NULL, "sndbuf", &err);
+    if (obj && (*obj)->has_sndbuf) {
+        visit_type_size(m, obj ? &(*obj)->sndbuf : NULL, "sndbuf", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_vnet_hdr : NULL, "vnet_hdr", &err);
+    if (obj && (*obj)->has_vnet_hdr) {
+        visit_type_bool(m, obj ? &(*obj)->vnet_hdr : NULL, "vnet_hdr", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_vhost : NULL, "vhost", &err);
+    if (obj && (*obj)->has_vhost) {
+        visit_type_bool(m, obj ? &(*obj)->vhost : NULL, "vhost", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_vhostfd : NULL, "vhostfd", &err);
+    if (obj && (*obj)->has_vhostfd) {
+        visit_type_str(m, obj ? &(*obj)->vhostfd : NULL, "vhostfd", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_vhostfds : NULL, "vhostfds", &err);
+    if (obj && (*obj)->has_vhostfds) {
+        visit_type_str(m, obj ? &(*obj)->vhostfds : NULL, "vhostfds", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_vhostforce : NULL, "vhostforce", &err);
+    if (obj && (*obj)->has_vhostforce) {
+        visit_type_bool(m, obj ? &(*obj)->vhostforce : NULL, "vhostforce", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_queues : NULL, "queues", &err);
+    if (obj && (*obj)->has_queues) {
+        visit_type_uint32(m, obj ? &(*obj)->queues : NULL, "queues", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NetdevTapOptions(Visitor *m, NetdevTapOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NetdevTapOptions", name, sizeof(NetdevTapOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NetdevTapOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetdevTapOptionsList(Visitor *m, NetdevTapOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetdevTapOptionsList *native_i = (NetdevTapOptionsList *)i;
+                visit_type_NetdevTapOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_NetdevSocketOptions_fields(Visitor *m, NetdevSocketOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_fd : NULL, "fd", &err);
+    if (obj && (*obj)->has_fd) {
+        visit_type_str(m, obj ? &(*obj)->fd : NULL, "fd", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_listen : NULL, "listen", &err);
+    if (obj && (*obj)->has_listen) {
+        visit_type_str(m, obj ? &(*obj)->listen : NULL, "listen", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_connect : NULL, "connect", &err);
+    if (obj && (*obj)->has_connect) {
+        visit_type_str(m, obj ? &(*obj)->connect : NULL, "connect", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_mcast : NULL, "mcast", &err);
+    if (obj && (*obj)->has_mcast) {
+        visit_type_str(m, obj ? &(*obj)->mcast : NULL, "mcast", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_localaddr : NULL, "localaddr", &err);
+    if (obj && (*obj)->has_localaddr) {
+        visit_type_str(m, obj ? &(*obj)->localaddr : NULL, "localaddr", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_udp : NULL, "udp", &err);
+    if (obj && (*obj)->has_udp) {
+        visit_type_str(m, obj ? &(*obj)->udp : NULL, "udp", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NetdevSocketOptions(Visitor *m, NetdevSocketOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NetdevSocketOptions", name, sizeof(NetdevSocketOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NetdevSocketOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetdevSocketOptionsList(Visitor *m, NetdevSocketOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetdevSocketOptionsList *native_i = (NetdevSocketOptionsList *)i;
+                visit_type_NetdevSocketOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_NetdevVdeOptions_fields(Visitor *m, NetdevVdeOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_sock : NULL, "sock", &err);
+    if (obj && (*obj)->has_sock) {
+        visit_type_str(m, obj ? &(*obj)->sock : NULL, "sock", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_port : NULL, "port", &err);
+    if (obj && (*obj)->has_port) {
+        visit_type_uint16(m, obj ? &(*obj)->port : NULL, "port", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_group : NULL, "group", &err);
+    if (obj && (*obj)->has_group) {
+        visit_type_str(m, obj ? &(*obj)->group : NULL, "group", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_mode : NULL, "mode", &err);
+    if (obj && (*obj)->has_mode) {
+        visit_type_uint16(m, obj ? &(*obj)->mode : NULL, "mode", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NetdevVdeOptions(Visitor *m, NetdevVdeOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NetdevVdeOptions", name, sizeof(NetdevVdeOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NetdevVdeOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetdevVdeOptionsList(Visitor *m, NetdevVdeOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetdevVdeOptionsList *native_i = (NetdevVdeOptionsList *)i;
+                visit_type_NetdevVdeOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_NetdevDumpOptions_fields(Visitor *m, NetdevDumpOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_len : NULL, "len", &err);
+    if (obj && (*obj)->has_len) {
+        visit_type_size(m, obj ? &(*obj)->len : NULL, "len", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_file : NULL, "file", &err);
+    if (obj && (*obj)->has_file) {
+        visit_type_str(m, obj ? &(*obj)->file : NULL, "file", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NetdevDumpOptions(Visitor *m, NetdevDumpOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NetdevDumpOptions", name, sizeof(NetdevDumpOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NetdevDumpOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetdevDumpOptionsList(Visitor *m, NetdevDumpOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetdevDumpOptionsList *native_i = (NetdevDumpOptionsList *)i;
+                visit_type_NetdevDumpOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_NetdevBridgeOptions_fields(Visitor *m, NetdevBridgeOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_br : NULL, "br", &err);
+    if (obj && (*obj)->has_br) {
+        visit_type_str(m, obj ? &(*obj)->br : NULL, "br", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_helper : NULL, "helper", &err);
+    if (obj && (*obj)->has_helper) {
+        visit_type_str(m, obj ? &(*obj)->helper : NULL, "helper", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NetdevBridgeOptions(Visitor *m, NetdevBridgeOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NetdevBridgeOptions", name, sizeof(NetdevBridgeOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NetdevBridgeOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetdevBridgeOptionsList(Visitor *m, NetdevBridgeOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetdevBridgeOptionsList *native_i = (NetdevBridgeOptionsList *)i;
+                visit_type_NetdevBridgeOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_NetdevHubPortOptions_fields(Visitor *m, NetdevHubPortOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int32(m, obj ? &(*obj)->hubid : NULL, "hubid", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NetdevHubPortOptions(Visitor *m, NetdevHubPortOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NetdevHubPortOptions", name, sizeof(NetdevHubPortOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NetdevHubPortOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetdevHubPortOptionsList(Visitor *m, NetdevHubPortOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetdevHubPortOptionsList *native_i = (NetdevHubPortOptionsList *)i;
+                visit_type_NetdevHubPortOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_NetdevNetmapOptions_fields(Visitor *m, NetdevNetmapOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->ifname : NULL, "ifname", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_devname : NULL, "devname", &err);
+    if (obj && (*obj)->has_devname) {
+        visit_type_str(m, obj ? &(*obj)->devname : NULL, "devname", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NetdevNetmapOptions(Visitor *m, NetdevNetmapOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NetdevNetmapOptions", name, sizeof(NetdevNetmapOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NetdevNetmapOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetdevNetmapOptionsList(Visitor *m, NetdevNetmapOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetdevNetmapOptionsList *native_i = (NetdevNetmapOptionsList *)i;
+                visit_type_NetdevNetmapOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetClientOptionsKind(Visitor *m, NetClientOptionsKind * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, NetClientOptionsKind_lookup, "NetClientOptionsKind", name, errp);
+}
+
+void visit_type_NetClientOptions(Visitor *m, NetClientOptions ** obj, const char *name, Error **errp)
+{
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_struct(m, (void **)obj, "NetClientOptions", name, sizeof(NetClientOptions), &err);
+        if (!err) {
+            if (obj && *obj) {
+                visit_type_NetClientOptionsKind(m, &(*obj)->kind, "type", &err);
+                if (!err) {
+                    switch ((*obj)->kind) {
+                    case NET_CLIENT_OPTIONS_KIND_NONE:
+                        visit_type_NetdevNoneOptions(m, &(*obj)->none, "data", &err);
+                        break;
+                    case NET_CLIENT_OPTIONS_KIND_NIC:
+                        visit_type_NetLegacyNicOptions(m, &(*obj)->nic, "data", &err);
+                        break;
+                    case NET_CLIENT_OPTIONS_KIND_USER:
+                        visit_type_NetdevUserOptions(m, &(*obj)->user, "data", &err);
+                        break;
+                    case NET_CLIENT_OPTIONS_KIND_TAP:
+                        visit_type_NetdevTapOptions(m, &(*obj)->tap, "data", &err);
+                        break;
+                    case NET_CLIENT_OPTIONS_KIND_SOCKET:
+                        visit_type_NetdevSocketOptions(m, &(*obj)->socket, "data", &err);
+                        break;
+                    case NET_CLIENT_OPTIONS_KIND_VDE:
+                        visit_type_NetdevVdeOptions(m, &(*obj)->vde, "data", &err);
+                        break;
+                    case NET_CLIENT_OPTIONS_KIND_DUMP:
+                        visit_type_NetdevDumpOptions(m, &(*obj)->dump, "data", &err);
+                        break;
+                    case NET_CLIENT_OPTIONS_KIND_BRIDGE:
+                        visit_type_NetdevBridgeOptions(m, &(*obj)->bridge, "data", &err);
+                        break;
+                    case NET_CLIENT_OPTIONS_KIND_HUBPORT:
+                        visit_type_NetdevHubPortOptions(m, &(*obj)->hubport, "data", &err);
+                        break;
+                    case NET_CLIENT_OPTIONS_KIND_NETMAP:
+                        visit_type_NetdevNetmapOptions(m, &(*obj)->netmap, "data", &err);
+                        break;
+                    default:
+                        abort();
+                    }
+                }
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetClientOptionsList(Visitor *m, NetClientOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetClientOptionsList *native_i = (NetClientOptionsList *)i;
+                visit_type_NetClientOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_NetLegacy_fields(Visitor *m, NetLegacy ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_vlan : NULL, "vlan", &err);
+    if (obj && (*obj)->has_vlan) {
+        visit_type_int32(m, obj ? &(*obj)->vlan : NULL, "vlan", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_id : NULL, "id", &err);
+    if (obj && (*obj)->has_id) {
+        visit_type_str(m, obj ? &(*obj)->id : NULL, "id", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_name : NULL, "name", &err);
+    if (obj && (*obj)->has_name) {
+        visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_NetClientOptions(m, obj ? &(*obj)->opts : NULL, "opts", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_NetLegacy(Visitor *m, NetLegacy ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "NetLegacy", name, sizeof(NetLegacy), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_NetLegacy_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetLegacyList(Visitor *m, NetLegacyList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetLegacyList *native_i = (NetLegacyList *)i;
+                visit_type_NetLegacy(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_Netdev_fields(Visitor *m, Netdev ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->id : NULL, "id", &err);
+    visit_type_NetClientOptions(m, obj ? &(*obj)->opts : NULL, "opts", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_Netdev(Visitor *m, Netdev ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "Netdev", name, sizeof(Netdev), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_Netdev_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_NetdevList(Visitor *m, NetdevList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                NetdevList *native_i = (NetdevList *)i;
+                visit_type_Netdev(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_InetSocketAddress_fields(Visitor *m, InetSocketAddress ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->host : NULL, "host", &err);
+    visit_type_str(m, obj ? &(*obj)->port : NULL, "port", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_to : NULL, "to", &err);
+    if (obj && (*obj)->has_to) {
+        visit_type_uint16(m, obj ? &(*obj)->to : NULL, "to", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_ipv4 : NULL, "ipv4", &err);
+    if (obj && (*obj)->has_ipv4) {
+        visit_type_bool(m, obj ? &(*obj)->ipv4 : NULL, "ipv4", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_ipv6 : NULL, "ipv6", &err);
+    if (obj && (*obj)->has_ipv6) {
+        visit_type_bool(m, obj ? &(*obj)->ipv6 : NULL, "ipv6", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_InetSocketAddress(Visitor *m, InetSocketAddress ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "InetSocketAddress", name, sizeof(InetSocketAddress), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_InetSocketAddress_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_InetSocketAddressList(Visitor *m, InetSocketAddressList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                InetSocketAddressList *native_i = (InetSocketAddressList *)i;
+                visit_type_InetSocketAddress(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_UnixSocketAddress_fields(Visitor *m, UnixSocketAddress ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->path : NULL, "path", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_UnixSocketAddress(Visitor *m, UnixSocketAddress ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "UnixSocketAddress", name, sizeof(UnixSocketAddress), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_UnixSocketAddress_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_UnixSocketAddressList(Visitor *m, UnixSocketAddressList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                UnixSocketAddressList *native_i = (UnixSocketAddressList *)i;
+                visit_type_UnixSocketAddress(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_SocketAddressKind(Visitor *m, SocketAddressKind * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, SocketAddressKind_lookup, "SocketAddressKind", name, errp);
+}
+
+void visit_type_SocketAddress(Visitor *m, SocketAddress ** obj, const char *name, Error **errp)
+{
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_struct(m, (void **)obj, "SocketAddress", name, sizeof(SocketAddress), &err);
+        if (!err) {
+            if (obj && *obj) {
+                visit_type_SocketAddressKind(m, &(*obj)->kind, "type", &err);
+                if (!err) {
+                    switch ((*obj)->kind) {
+                    case SOCKET_ADDRESS_KIND_INET:
+                        visit_type_InetSocketAddress(m, &(*obj)->inet, "data", &err);
+                        break;
+                    case SOCKET_ADDRESS_KIND_UNIX:
+                        visit_type_UnixSocketAddress(m, &(*obj)->q_unix, "data", &err);
+                        break;
+                    case SOCKET_ADDRESS_KIND_FD:
+                        visit_type_String(m, &(*obj)->fd, "data", &err);
+                        break;
+                    default:
+                        abort();
+                    }
+                }
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_SocketAddressList(Visitor *m, SocketAddressList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                SocketAddressList *native_i = (SocketAddressList *)i;
+                visit_type_SocketAddress(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_MachineInfo_fields(Visitor *m, MachineInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_alias : NULL, "alias", &err);
+    if (obj && (*obj)->has_alias) {
+        visit_type_str(m, obj ? &(*obj)->alias : NULL, "alias", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_is_default : NULL, "is-default", &err);
+    if (obj && (*obj)->has_is_default) {
+        visit_type_bool(m, obj ? &(*obj)->is_default : NULL, "is-default", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_int(m, obj ? &(*obj)->cpu_max : NULL, "cpu-max", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_MachineInfo(Visitor *m, MachineInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "MachineInfo", name, sizeof(MachineInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_MachineInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_MachineInfoList(Visitor *m, MachineInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                MachineInfoList *native_i = (MachineInfoList *)i;
+                visit_type_MachineInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_CpuDefinitionInfo_fields(Visitor *m, CpuDefinitionInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_CpuDefinitionInfo(Visitor *m, CpuDefinitionInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "CpuDefinitionInfo", name, sizeof(CpuDefinitionInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_CpuDefinitionInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_CpuDefinitionInfoList(Visitor *m, CpuDefinitionInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                CpuDefinitionInfoList *native_i = (CpuDefinitionInfoList *)i;
+                visit_type_CpuDefinitionInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_AddfdInfo_fields(Visitor *m, AddfdInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->fdset_id : NULL, "fdset-id", &err);
+    visit_type_int(m, obj ? &(*obj)->fd : NULL, "fd", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_AddfdInfo(Visitor *m, AddfdInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "AddfdInfo", name, sizeof(AddfdInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_AddfdInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_AddfdInfoList(Visitor *m, AddfdInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                AddfdInfoList *native_i = (AddfdInfoList *)i;
+                visit_type_AddfdInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_FdsetFdInfo_fields(Visitor *m, FdsetFdInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->fd : NULL, "fd", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_opaque : NULL, "opaque", &err);
+    if (obj && (*obj)->has_opaque) {
+        visit_type_str(m, obj ? &(*obj)->opaque : NULL, "opaque", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_FdsetFdInfo(Visitor *m, FdsetFdInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "FdsetFdInfo", name, sizeof(FdsetFdInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_FdsetFdInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_FdsetFdInfoList(Visitor *m, FdsetFdInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                FdsetFdInfoList *native_i = (FdsetFdInfoList *)i;
+                visit_type_FdsetFdInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_FdsetInfo_fields(Visitor *m, FdsetInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->fdset_id : NULL, "fdset-id", &err);
+    visit_type_FdsetFdInfoList(m, obj ? &(*obj)->fds : NULL, "fds", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_FdsetInfo(Visitor *m, FdsetInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "FdsetInfo", name, sizeof(FdsetInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_FdsetInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_FdsetInfoList(Visitor *m, FdsetInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                FdsetInfoList *native_i = (FdsetInfoList *)i;
+                visit_type_FdsetInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_TargetInfo_fields(Visitor *m, TargetInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->arch : NULL, "arch", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_TargetInfo(Visitor *m, TargetInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "TargetInfo", name, sizeof(TargetInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_TargetInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_TargetInfoList(Visitor *m, TargetInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                TargetInfoList *native_i = (TargetInfoList *)i;
+                visit_type_TargetInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_QKeyCodeList(Visitor *m, QKeyCodeList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                QKeyCodeList *native_i = (QKeyCodeList *)i;
+                visit_type_QKeyCode(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_QKeyCode(Visitor *m, QKeyCode * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, QKeyCode_lookup, "QKeyCode", name, errp);
+}
+
+void visit_type_KeyValueKind(Visitor *m, KeyValueKind * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, KeyValueKind_lookup, "KeyValueKind", name, errp);
+}
+
+void visit_type_KeyValue(Visitor *m, KeyValue ** obj, const char *name, Error **errp)
+{
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_struct(m, (void **)obj, "KeyValue", name, sizeof(KeyValue), &err);
+        if (!err) {
+            if (obj && *obj) {
+                visit_type_KeyValueKind(m, &(*obj)->kind, "type", &err);
+                if (!err) {
+                    switch ((*obj)->kind) {
+                    case KEY_VALUE_KIND_NUMBER:
+                        visit_type_int(m, &(*obj)->number, "data", &err);
+                        break;
+                    case KEY_VALUE_KIND_QCODE:
+                        visit_type_QKeyCode(m, &(*obj)->qcode, "data", &err);
+                        break;
+                    default:
+                        abort();
+                    }
+                }
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_KeyValueList(Visitor *m, KeyValueList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                KeyValueList *native_i = (KeyValueList *)i;
+                visit_type_KeyValue(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevFile_fields(Visitor *m, ChardevFile ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_in : NULL, "in", &err);
+    if (obj && (*obj)->has_in) {
+        visit_type_str(m, obj ? &(*obj)->in : NULL, "in", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_str(m, obj ? &(*obj)->out : NULL, "out", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevFile(Visitor *m, ChardevFile ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevFile", name, sizeof(ChardevFile), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevFile_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevFileList(Visitor *m, ChardevFileList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevFileList *native_i = (ChardevFileList *)i;
+                visit_type_ChardevFile(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevHostdev_fields(Visitor *m, ChardevHostdev ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->device : NULL, "device", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevHostdev(Visitor *m, ChardevHostdev ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevHostdev", name, sizeof(ChardevHostdev), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevHostdev_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevHostdevList(Visitor *m, ChardevHostdevList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevHostdevList *native_i = (ChardevHostdevList *)i;
+                visit_type_ChardevHostdev(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevSocket_fields(Visitor *m, ChardevSocket ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_SocketAddress(m, obj ? &(*obj)->addr : NULL, "addr", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_server : NULL, "server", &err);
+    if (obj && (*obj)->has_server) {
+        visit_type_bool(m, obj ? &(*obj)->server : NULL, "server", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_wait : NULL, "wait", &err);
+    if (obj && (*obj)->has_wait) {
+        visit_type_bool(m, obj ? &(*obj)->wait : NULL, "wait", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_nodelay : NULL, "nodelay", &err);
+    if (obj && (*obj)->has_nodelay) {
+        visit_type_bool(m, obj ? &(*obj)->nodelay : NULL, "nodelay", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_telnet : NULL, "telnet", &err);
+    if (obj && (*obj)->has_telnet) {
+        visit_type_bool(m, obj ? &(*obj)->telnet : NULL, "telnet", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevSocket(Visitor *m, ChardevSocket ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevSocket", name, sizeof(ChardevSocket), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevSocket_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevSocketList(Visitor *m, ChardevSocketList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevSocketList *native_i = (ChardevSocketList *)i;
+                visit_type_ChardevSocket(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevUdp_fields(Visitor *m, ChardevUdp ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_SocketAddress(m, obj ? &(*obj)->remote : NULL, "remote", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_local : NULL, "local", &err);
+    if (obj && (*obj)->has_local) {
+        visit_type_SocketAddress(m, obj ? &(*obj)->local : NULL, "local", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevUdp(Visitor *m, ChardevUdp ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevUdp", name, sizeof(ChardevUdp), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevUdp_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevUdpList(Visitor *m, ChardevUdpList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevUdpList *native_i = (ChardevUdpList *)i;
+                visit_type_ChardevUdp(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevMux_fields(Visitor *m, ChardevMux ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->chardev : NULL, "chardev", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevMux(Visitor *m, ChardevMux ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevMux", name, sizeof(ChardevMux), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevMux_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevMuxList(Visitor *m, ChardevMuxList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevMuxList *native_i = (ChardevMuxList *)i;
+                visit_type_ChardevMux(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevStdio_fields(Visitor *m, ChardevStdio ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_signal : NULL, "signal", &err);
+    if (obj && (*obj)->has_signal) {
+        visit_type_bool(m, obj ? &(*obj)->signal : NULL, "signal", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevStdio(Visitor *m, ChardevStdio ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevStdio", name, sizeof(ChardevStdio), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevStdio_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevStdioList(Visitor *m, ChardevStdioList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevStdioList *native_i = (ChardevStdioList *)i;
+                visit_type_ChardevStdio(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevSpiceChannel_fields(Visitor *m, ChardevSpiceChannel ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->type : NULL, "type", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevSpiceChannel(Visitor *m, ChardevSpiceChannel ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevSpiceChannel", name, sizeof(ChardevSpiceChannel), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevSpiceChannel_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevSpiceChannelList(Visitor *m, ChardevSpiceChannelList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevSpiceChannelList *native_i = (ChardevSpiceChannelList *)i;
+                visit_type_ChardevSpiceChannel(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevSpicePort_fields(Visitor *m, ChardevSpicePort ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->fqdn : NULL, "fqdn", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevSpicePort(Visitor *m, ChardevSpicePort ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevSpicePort", name, sizeof(ChardevSpicePort), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevSpicePort_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevSpicePortList(Visitor *m, ChardevSpicePortList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevSpicePortList *native_i = (ChardevSpicePortList *)i;
+                visit_type_ChardevSpicePort(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevVC_fields(Visitor *m, ChardevVC ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_width : NULL, "width", &err);
+    if (obj && (*obj)->has_width) {
+        visit_type_int(m, obj ? &(*obj)->width : NULL, "width", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_height : NULL, "height", &err);
+    if (obj && (*obj)->has_height) {
+        visit_type_int(m, obj ? &(*obj)->height : NULL, "height", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_cols : NULL, "cols", &err);
+    if (obj && (*obj)->has_cols) {
+        visit_type_int(m, obj ? &(*obj)->cols : NULL, "cols", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_rows : NULL, "rows", &err);
+    if (obj && (*obj)->has_rows) {
+        visit_type_int(m, obj ? &(*obj)->rows : NULL, "rows", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevVC(Visitor *m, ChardevVC ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevVC", name, sizeof(ChardevVC), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevVC_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevVCList(Visitor *m, ChardevVCList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevVCList *native_i = (ChardevVCList *)i;
+                visit_type_ChardevVC(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevRingbuf_fields(Visitor *m, ChardevRingbuf ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_size : NULL, "size", &err);
+    if (obj && (*obj)->has_size) {
+        visit_type_int(m, obj ? &(*obj)->size : NULL, "size", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevRingbuf(Visitor *m, ChardevRingbuf ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevRingbuf", name, sizeof(ChardevRingbuf), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevRingbuf_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevRingbufList(Visitor *m, ChardevRingbufList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevRingbufList *native_i = (ChardevRingbufList *)i;
+                visit_type_ChardevRingbuf(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevDummy_fields(Visitor *m, ChardevDummy ** obj, Error **errp)
+{
+    Error *err = NULL;
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevDummy(Visitor *m, ChardevDummy ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevDummy", name, sizeof(ChardevDummy), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevDummy_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevDummyList(Visitor *m, ChardevDummyList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevDummyList *native_i = (ChardevDummyList *)i;
+                visit_type_ChardevDummy(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevBackendKind(Visitor *m, ChardevBackendKind * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, ChardevBackendKind_lookup, "ChardevBackendKind", name, errp);
+}
+
+void visit_type_ChardevBackend(Visitor *m, ChardevBackend ** obj, const char *name, Error **errp)
+{
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_struct(m, (void **)obj, "ChardevBackend", name, sizeof(ChardevBackend), &err);
+        if (!err) {
+            if (obj && *obj) {
+                visit_type_ChardevBackendKind(m, &(*obj)->kind, "type", &err);
+                if (!err) {
+                    switch ((*obj)->kind) {
+                    case CHARDEV_BACKEND_KIND_FILE:
+                        visit_type_ChardevFile(m, &(*obj)->file, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_SERIAL:
+                        visit_type_ChardevHostdev(m, &(*obj)->serial, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_PARALLEL:
+                        visit_type_ChardevHostdev(m, &(*obj)->parallel, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_PIPE:
+                        visit_type_ChardevHostdev(m, &(*obj)->pipe, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_SOCKET:
+                        visit_type_ChardevSocket(m, &(*obj)->socket, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_UDP:
+                        visit_type_ChardevUdp(m, &(*obj)->udp, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_PTY:
+                        visit_type_ChardevDummy(m, &(*obj)->pty, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_NULL:
+                        visit_type_ChardevDummy(m, &(*obj)->null, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_MUX:
+                        visit_type_ChardevMux(m, &(*obj)->mux, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_MSMOUSE:
+                        visit_type_ChardevDummy(m, &(*obj)->msmouse, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_BRAILLE:
+                        visit_type_ChardevDummy(m, &(*obj)->braille, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_STDIO:
+                        visit_type_ChardevStdio(m, &(*obj)->stdio, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_CONSOLE:
+                        visit_type_ChardevDummy(m, &(*obj)->console, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_SPICEVMC:
+                        visit_type_ChardevSpiceChannel(m, &(*obj)->spicevmc, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_SPICEPORT:
+                        visit_type_ChardevSpicePort(m, &(*obj)->spiceport, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_VC:
+                        visit_type_ChardevVC(m, &(*obj)->vc, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_RINGBUF:
+                        visit_type_ChardevRingbuf(m, &(*obj)->ringbuf, "data", &err);
+                        break;
+                    case CHARDEV_BACKEND_KIND_MEMORY:
+                        visit_type_ChardevRingbuf(m, &(*obj)->memory, "data", &err);
+                        break;
+                    default:
+                        abort();
+                    }
+                }
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevBackendList(Visitor *m, ChardevBackendList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevBackendList *native_i = (ChardevBackendList *)i;
+                visit_type_ChardevBackend(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_ChardevReturn_fields(Visitor *m, ChardevReturn ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_pty : NULL, "pty", &err);
+    if (obj && (*obj)->has_pty) {
+        visit_type_str(m, obj ? &(*obj)->pty : NULL, "pty", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_ChardevReturn(Visitor *m, ChardevReturn ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "ChardevReturn", name, sizeof(ChardevReturn), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_ChardevReturn_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_ChardevReturnList(Visitor *m, ChardevReturnList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                ChardevReturnList *native_i = (ChardevReturnList *)i;
+                visit_type_ChardevReturn(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_TpmModelList(Visitor *m, TpmModelList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                TpmModelList *native_i = (TpmModelList *)i;
+                visit_type_TpmModel(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_TpmModel(Visitor *m, TpmModel * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, TpmModel_lookup, "TpmModel", name, errp);
+}
+
+void visit_type_TpmTypeList(Visitor *m, TpmTypeList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                TpmTypeList *native_i = (TpmTypeList *)i;
+                visit_type_TpmType(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_TpmType(Visitor *m, TpmType * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, TpmType_lookup, "TpmType", name, errp);
+}
+
+static void visit_type_TPMPassthroughOptions_fields(Visitor *m, TPMPassthroughOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_path : NULL, "path", &err);
+    if (obj && (*obj)->has_path) {
+        visit_type_str(m, obj ? &(*obj)->path : NULL, "path", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_cancel_path : NULL, "cancel-path", &err);
+    if (obj && (*obj)->has_cancel_path) {
+        visit_type_str(m, obj ? &(*obj)->cancel_path : NULL, "cancel-path", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_TPMPassthroughOptions(Visitor *m, TPMPassthroughOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "TPMPassthroughOptions", name, sizeof(TPMPassthroughOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_TPMPassthroughOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_TPMPassthroughOptionsList(Visitor *m, TPMPassthroughOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                TPMPassthroughOptionsList *native_i = (TPMPassthroughOptionsList *)i;
+                visit_type_TPMPassthroughOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_TpmTypeOptionsKind(Visitor *m, TpmTypeOptionsKind * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, TpmTypeOptionsKind_lookup, "TpmTypeOptionsKind", name, errp);
+}
+
+void visit_type_TpmTypeOptions(Visitor *m, TpmTypeOptions ** obj, const char *name, Error **errp)
+{
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_struct(m, (void **)obj, "TpmTypeOptions", name, sizeof(TpmTypeOptions), &err);
+        if (!err) {
+            if (obj && *obj) {
+                visit_type_TpmTypeOptionsKind(m, &(*obj)->kind, "type", &err);
+                if (!err) {
+                    switch ((*obj)->kind) {
+                    case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH:
+                        visit_type_TPMPassthroughOptions(m, &(*obj)->passthrough, "data", &err);
+                        break;
+                    default:
+                        abort();
+                    }
+                }
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_TpmTypeOptionsList(Visitor *m, TpmTypeOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                TpmTypeOptionsList *native_i = (TpmTypeOptionsList *)i;
+                visit_type_TpmTypeOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_TPMInfo_fields(Visitor *m, TPMInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->id : NULL, "id", &err);
+    visit_type_TpmModel(m, obj ? &(*obj)->model : NULL, "model", &err);
+    visit_type_TpmTypeOptions(m, obj ? &(*obj)->options : NULL, "options", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_TPMInfo(Visitor *m, TPMInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "TPMInfo", name, sizeof(TPMInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_TPMInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_TPMInfoList(Visitor *m, TPMInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                TPMInfoList *native_i = (TPMInfoList *)i;
+                visit_type_TPMInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_AcpiTableOptions_fields(Visitor *m, AcpiTableOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_sig : NULL, "sig", &err);
+    if (obj && (*obj)->has_sig) {
+        visit_type_str(m, obj ? &(*obj)->sig : NULL, "sig", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_rev : NULL, "rev", &err);
+    if (obj && (*obj)->has_rev) {
+        visit_type_uint8(m, obj ? &(*obj)->rev : NULL, "rev", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_oem_id : NULL, "oem_id", &err);
+    if (obj && (*obj)->has_oem_id) {
+        visit_type_str(m, obj ? &(*obj)->oem_id : NULL, "oem_id", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_oem_table_id : NULL, "oem_table_id", &err);
+    if (obj && (*obj)->has_oem_table_id) {
+        visit_type_str(m, obj ? &(*obj)->oem_table_id : NULL, "oem_table_id", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_oem_rev : NULL, "oem_rev", &err);
+    if (obj && (*obj)->has_oem_rev) {
+        visit_type_uint32(m, obj ? &(*obj)->oem_rev : NULL, "oem_rev", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_asl_compiler_id : NULL, "asl_compiler_id", &err);
+    if (obj && (*obj)->has_asl_compiler_id) {
+        visit_type_str(m, obj ? &(*obj)->asl_compiler_id : NULL, "asl_compiler_id", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_asl_compiler_rev : NULL, "asl_compiler_rev", &err);
+    if (obj && (*obj)->has_asl_compiler_rev) {
+        visit_type_uint32(m, obj ? &(*obj)->asl_compiler_rev : NULL, "asl_compiler_rev", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_file : NULL, "file", &err);
+    if (obj && (*obj)->has_file) {
+        visit_type_str(m, obj ? &(*obj)->file : NULL, "file", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_data : NULL, "data", &err);
+    if (obj && (*obj)->has_data) {
+        visit_type_str(m, obj ? &(*obj)->data : NULL, "data", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_AcpiTableOptions(Visitor *m, AcpiTableOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "AcpiTableOptions", name, sizeof(AcpiTableOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_AcpiTableOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_AcpiTableOptionsList(Visitor *m, AcpiTableOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                AcpiTableOptionsList *native_i = (AcpiTableOptionsList *)i;
+                visit_type_AcpiTableOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_CommandLineParameterTypeList(Visitor *m, CommandLineParameterTypeList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                CommandLineParameterTypeList *native_i = (CommandLineParameterTypeList *)i;
+                visit_type_CommandLineParameterType(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_CommandLineParameterType(Visitor *m, CommandLineParameterType * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, CommandLineParameterType_lookup, "CommandLineParameterType", name, errp);
+}
+
+static void visit_type_CommandLineParameterInfo_fields(Visitor *m, CommandLineParameterInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+    visit_type_CommandLineParameterType(m, obj ? &(*obj)->type : NULL, "type", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_help : NULL, "help", &err);
+    if (obj && (*obj)->has_help) {
+        visit_type_str(m, obj ? &(*obj)->help : NULL, "help", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_CommandLineParameterInfo(Visitor *m, CommandLineParameterInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "CommandLineParameterInfo", name, sizeof(CommandLineParameterInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_CommandLineParameterInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_CommandLineParameterInfoList(Visitor *m, CommandLineParameterInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                CommandLineParameterInfoList *native_i = (CommandLineParameterInfoList *)i;
+                visit_type_CommandLineParameterInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_CommandLineOptionInfo_fields(Visitor *m, CommandLineOptionInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->option : NULL, "option", &err);
+    visit_type_CommandLineParameterInfoList(m, obj ? &(*obj)->parameters : NULL, "parameters", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_CommandLineOptionInfo(Visitor *m, CommandLineOptionInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "CommandLineOptionInfo", name, sizeof(CommandLineOptionInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_CommandLineOptionInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_CommandLineOptionInfoList(Visitor *m, CommandLineOptionInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                CommandLineOptionInfoList *native_i = (CommandLineOptionInfoList *)i;
+                visit_type_CommandLineOptionInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_X86CPURegister32List(Visitor *m, X86CPURegister32List ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                X86CPURegister32List *native_i = (X86CPURegister32List *)i;
+                visit_type_X86CPURegister32(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_X86CPURegister32(Visitor *m, X86CPURegister32 * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, X86CPURegister32_lookup, "X86CPURegister32", name, errp);
+}
+
+static void visit_type_X86CPUFeatureWordInfo_fields(Visitor *m, X86CPUFeatureWordInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_int(m, obj ? &(*obj)->cpuid_input_eax : NULL, "cpuid-input-eax", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_cpuid_input_ecx : NULL, "cpuid-input-ecx", &err);
+    if (obj && (*obj)->has_cpuid_input_ecx) {
+        visit_type_int(m, obj ? &(*obj)->cpuid_input_ecx : NULL, "cpuid-input-ecx", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_type_X86CPURegister32(m, obj ? &(*obj)->cpuid_register : NULL, "cpuid-register", &err);
+    visit_type_int(m, obj ? &(*obj)->features : NULL, "features", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_X86CPUFeatureWordInfo(Visitor *m, X86CPUFeatureWordInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "X86CPUFeatureWordInfo", name, sizeof(X86CPUFeatureWordInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_X86CPUFeatureWordInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_X86CPUFeatureWordInfoList(Visitor *m, X86CPUFeatureWordInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                X86CPUFeatureWordInfoList *native_i = (X86CPUFeatureWordInfoList *)i;
+                visit_type_X86CPUFeatureWordInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_RxStateList(Visitor *m, RxStateList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                RxStateList *native_i = (RxStateList *)i;
+                visit_type_RxState(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_RxState(Visitor *m, RxState * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, RxState_lookup, "RxState", name, errp);
+}
+
+static void visit_type_RxFilterInfo_fields(Visitor *m, RxFilterInfo ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->name : NULL, "name", &err);
+    visit_type_bool(m, obj ? &(*obj)->promiscuous : NULL, "promiscuous", &err);
+    visit_type_RxState(m, obj ? &(*obj)->multicast : NULL, "multicast", &err);
+    visit_type_RxState(m, obj ? &(*obj)->unicast : NULL, "unicast", &err);
+    visit_type_bool(m, obj ? &(*obj)->broadcast_allowed : NULL, "broadcast-allowed", &err);
+    visit_type_bool(m, obj ? &(*obj)->multicast_overflow : NULL, "multicast-overflow", &err);
+    visit_type_bool(m, obj ? &(*obj)->unicast_overflow : NULL, "unicast-overflow", &err);
+    visit_type_str(m, obj ? &(*obj)->main_mac : NULL, "main-mac", &err);
+    visit_type_intList(m, obj ? &(*obj)->vlan_table : NULL, "vlan-table", &err);
+    visit_type_strList(m, obj ? &(*obj)->unicast_table : NULL, "unicast-table", &err);
+    visit_type_strList(m, obj ? &(*obj)->multicast_table : NULL, "multicast-table", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_RxFilterInfo(Visitor *m, RxFilterInfo ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "RxFilterInfo", name, sizeof(RxFilterInfo), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_RxFilterInfo_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_RxFilterInfoList(Visitor *m, RxFilterInfoList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                RxFilterInfoList *native_i = (RxFilterInfoList *)i;
+                visit_type_RxFilterInfo(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevDiscardOptionsList(Visitor *m, BlockdevDiscardOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevDiscardOptionsList *native_i = (BlockdevDiscardOptionsList *)i;
+                visit_type_BlockdevDiscardOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevDiscardOptions(Visitor *m, BlockdevDiscardOptions * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, BlockdevDiscardOptions_lookup, "BlockdevDiscardOptions", name, errp);
+}
+
+void visit_type_BlockdevAioOptionsList(Visitor *m, BlockdevAioOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevAioOptionsList *native_i = (BlockdevAioOptionsList *)i;
+                visit_type_BlockdevAioOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevAioOptions(Visitor *m, BlockdevAioOptions * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, BlockdevAioOptions_lookup, "BlockdevAioOptions", name, errp);
+}
+
+static void visit_type_BlockdevCacheOptions_fields(Visitor *m, BlockdevCacheOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_writeback : NULL, "writeback", &err);
+    if (obj && (*obj)->has_writeback) {
+        visit_type_bool(m, obj ? &(*obj)->writeback : NULL, "writeback", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_direct : NULL, "direct", &err);
+    if (obj && (*obj)->has_direct) {
+        visit_type_bool(m, obj ? &(*obj)->direct : NULL, "direct", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_no_flush : NULL, "no-flush", &err);
+    if (obj && (*obj)->has_no_flush) {
+        visit_type_bool(m, obj ? &(*obj)->no_flush : NULL, "no-flush", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockdevCacheOptions(Visitor *m, BlockdevCacheOptions ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockdevCacheOptions", name, sizeof(BlockdevCacheOptions), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockdevCacheOptions_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevCacheOptionsList(Visitor *m, BlockdevCacheOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevCacheOptionsList *native_i = (BlockdevCacheOptionsList *)i;
+                visit_type_BlockdevCacheOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockdevOptionsBase_fields(Visitor *m, BlockdevOptionsBase ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->driver : NULL, "driver", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_id : NULL, "id", &err);
+    if (obj && (*obj)->has_id) {
+        visit_type_str(m, obj ? &(*obj)->id : NULL, "id", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_discard : NULL, "discard", &err);
+    if (obj && (*obj)->has_discard) {
+        visit_type_BlockdevDiscardOptions(m, obj ? &(*obj)->discard : NULL, "discard", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_cache : NULL, "cache", &err);
+    if (obj && (*obj)->has_cache) {
+        visit_type_BlockdevCacheOptions(m, obj ? &(*obj)->cache : NULL, "cache", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_aio : NULL, "aio", &err);
+    if (obj && (*obj)->has_aio) {
+        visit_type_BlockdevAioOptions(m, obj ? &(*obj)->aio : NULL, "aio", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_rerror : NULL, "rerror", &err);
+    if (obj && (*obj)->has_rerror) {
+        visit_type_BlockdevOnError(m, obj ? &(*obj)->rerror : NULL, "rerror", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_werror : NULL, "werror", &err);
+    if (obj && (*obj)->has_werror) {
+        visit_type_BlockdevOnError(m, obj ? &(*obj)->werror : NULL, "werror", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_read_only : NULL, "read-only", &err);
+    if (obj && (*obj)->has_read_only) {
+        visit_type_bool(m, obj ? &(*obj)->read_only : NULL, "read-only", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockdevOptionsBase(Visitor *m, BlockdevOptionsBase ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockdevOptionsBase", name, sizeof(BlockdevOptionsBase), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockdevOptionsBase_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevOptionsBaseList(Visitor *m, BlockdevOptionsBaseList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevOptionsBaseList *native_i = (BlockdevOptionsBaseList *)i;
+                visit_type_BlockdevOptionsBase(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockdevOptionsFile_fields(Visitor *m, BlockdevOptionsFile ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->filename : NULL, "filename", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockdevOptionsFile(Visitor *m, BlockdevOptionsFile ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockdevOptionsFile", name, sizeof(BlockdevOptionsFile), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockdevOptionsFile_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevOptionsFileList(Visitor *m, BlockdevOptionsFileList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevOptionsFileList *native_i = (BlockdevOptionsFileList *)i;
+                visit_type_BlockdevOptionsFile(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockdevOptionsVVFAT_fields(Visitor *m, BlockdevOptionsVVFAT ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_str(m, obj ? &(*obj)->dir : NULL, "dir", &err);
+    visit_start_optional(m, obj ? &(*obj)->has_fat_type : NULL, "fat-type", &err);
+    if (obj && (*obj)->has_fat_type) {
+        visit_type_int(m, obj ? &(*obj)->fat_type : NULL, "fat-type", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_floppy : NULL, "floppy", &err);
+    if (obj && (*obj)->has_floppy) {
+        visit_type_bool(m, obj ? &(*obj)->floppy : NULL, "floppy", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_rw : NULL, "rw", &err);
+    if (obj && (*obj)->has_rw) {
+        visit_type_bool(m, obj ? &(*obj)->rw : NULL, "rw", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockdevOptionsVVFAT(Visitor *m, BlockdevOptionsVVFAT ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockdevOptionsVVFAT", name, sizeof(BlockdevOptionsVVFAT), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockdevOptionsVVFAT_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevOptionsVVFATList(Visitor *m, BlockdevOptionsVVFATList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevOptionsVVFATList *native_i = (BlockdevOptionsVVFATList *)i;
+                visit_type_BlockdevOptionsVVFAT(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockdevOptionsGenericFormat_fields(Visitor *m, BlockdevOptionsGenericFormat ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_type_BlockdevRef(m, obj ? &(*obj)->file : NULL, "file", &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockdevOptionsGenericFormat(Visitor *m, BlockdevOptionsGenericFormat ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockdevOptionsGenericFormat", name, sizeof(BlockdevOptionsGenericFormat), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockdevOptionsGenericFormat_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevOptionsGenericFormatList(Visitor *m, BlockdevOptionsGenericFormatList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevOptionsGenericFormatList *native_i = (BlockdevOptionsGenericFormatList *)i;
+                visit_type_BlockdevOptionsGenericFormat(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockdevOptionsGenericCOWFormat_fields(Visitor *m, BlockdevOptionsGenericCOWFormat ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_implicit_struct(m, obj ? (void**) &(*obj)->base : NULL, sizeof(BlockdevOptionsGenericFormat), &err);
+    if (!err) {
+        visit_type_BlockdevOptionsGenericFormat_fields(m, obj ? &(*obj)->base : NULL, &err);
+        error_propagate(errp, err);
+        err = NULL;
+        visit_end_implicit_struct(m, &err);
+    }
+    visit_start_optional(m, obj ? &(*obj)->has_backing : NULL, "backing", &err);
+    if (obj && (*obj)->has_backing) {
+        visit_type_BlockdevRef(m, obj ? &(*obj)->backing : NULL, "backing", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockdevOptionsGenericCOWFormat(Visitor *m, BlockdevOptionsGenericCOWFormat ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockdevOptionsGenericCOWFormat", name, sizeof(BlockdevOptionsGenericCOWFormat), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockdevOptionsGenericCOWFormat_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevOptionsGenericCOWFormatList(Visitor *m, BlockdevOptionsGenericCOWFormatList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevOptionsGenericCOWFormatList *native_i = (BlockdevOptionsGenericCOWFormatList *)i;
+                visit_type_BlockdevOptionsGenericCOWFormat(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+static void visit_type_BlockdevOptionsQcow2_fields(Visitor *m, BlockdevOptionsQcow2 ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_implicit_struct(m, obj ? (void**) &(*obj)->base : NULL, sizeof(BlockdevOptionsGenericCOWFormat), &err);
+    if (!err) {
+        visit_type_BlockdevOptionsGenericCOWFormat_fields(m, obj ? &(*obj)->base : NULL, &err);
+        error_propagate(errp, err);
+        err = NULL;
+        visit_end_implicit_struct(m, &err);
+    }
+    visit_start_optional(m, obj ? &(*obj)->has_lazy_refcounts : NULL, "lazy-refcounts", &err);
+    if (obj && (*obj)->has_lazy_refcounts) {
+        visit_type_bool(m, obj ? &(*obj)->lazy_refcounts : NULL, "lazy-refcounts", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_pass_discard_request : NULL, "pass-discard-request", &err);
+    if (obj && (*obj)->has_pass_discard_request) {
+        visit_type_bool(m, obj ? &(*obj)->pass_discard_request : NULL, "pass-discard-request", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_pass_discard_snapshot : NULL, "pass-discard-snapshot", &err);
+    if (obj && (*obj)->has_pass_discard_snapshot) {
+        visit_type_bool(m, obj ? &(*obj)->pass_discard_snapshot : NULL, "pass-discard-snapshot", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_pass_discard_other : NULL, "pass-discard-other", &err);
+    if (obj && (*obj)->has_pass_discard_other) {
+        visit_type_bool(m, obj ? &(*obj)->pass_discard_other : NULL, "pass-discard-other", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockdevOptionsQcow2(Visitor *m, BlockdevOptionsQcow2 ** obj, const char *name, Error **errp)
+{
+    if (!error_is_set(errp)) {
+        Error *err = NULL;
+        visit_start_struct(m, (void **)obj, "BlockdevOptionsQcow2", name, sizeof(BlockdevOptionsQcow2), &err);
+        if (!err) {
+            if (!obj || *obj) {
+                visit_type_BlockdevOptionsQcow2_fields(m, obj, &err);
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevOptionsQcow2List(Visitor *m, BlockdevOptionsQcow2List ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevOptionsQcow2List *native_i = (BlockdevOptionsQcow2List *)i;
+                visit_type_BlockdevOptionsQcow2(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevOptionsKind(Visitor *m, BlockdevOptionsKind * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, BlockdevOptionsKind_lookup, "BlockdevOptionsKind", name, errp);
+}
+
+static void visit_type_BlockdevOptions_fields(Visitor *m, BlockdevOptions ** obj, Error **errp)
+{
+    Error *err = NULL;
+    visit_start_optional(m, obj ? &(*obj)->has_id : NULL, "id", &err);
+    if (obj && (*obj)->has_id) {
+        visit_type_str(m, obj ? &(*obj)->id : NULL, "id", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_discard : NULL, "discard", &err);
+    if (obj && (*obj)->has_discard) {
+        visit_type_BlockdevDiscardOptions(m, obj ? &(*obj)->discard : NULL, "discard", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_cache : NULL, "cache", &err);
+    if (obj && (*obj)->has_cache) {
+        visit_type_BlockdevCacheOptions(m, obj ? &(*obj)->cache : NULL, "cache", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_aio : NULL, "aio", &err);
+    if (obj && (*obj)->has_aio) {
+        visit_type_BlockdevAioOptions(m, obj ? &(*obj)->aio : NULL, "aio", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_rerror : NULL, "rerror", &err);
+    if (obj && (*obj)->has_rerror) {
+        visit_type_BlockdevOnError(m, obj ? &(*obj)->rerror : NULL, "rerror", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_werror : NULL, "werror", &err);
+    if (obj && (*obj)->has_werror) {
+        visit_type_BlockdevOnError(m, obj ? &(*obj)->werror : NULL, "werror", &err);
+    }
+    visit_end_optional(m, &err);
+    visit_start_optional(m, obj ? &(*obj)->has_read_only : NULL, "read-only", &err);
+    if (obj && (*obj)->has_read_only) {
+        visit_type_bool(m, obj ? &(*obj)->read_only : NULL, "read-only", &err);
+    }
+    visit_end_optional(m, &err);
+
+    error_propagate(errp, err);
+}
+
+void visit_type_BlockdevOptions(Visitor *m, BlockdevOptions ** obj, const char *name, Error **errp)
+{
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_struct(m, (void **)obj, "BlockdevOptions", name, sizeof(BlockdevOptions), &err);
+        if (!err) {
+            if (obj && *obj) {
+                visit_type_BlockdevOptions_fields(m, obj, &err);
+                visit_type_BlockdevOptionsKind(m, &(*obj)->kind, "driver", &err);
+                if (!err) {
+                    switch ((*obj)->kind) {
+                    case BLOCKDEV_OPTIONS_KIND_FILE:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->file, sizeof(BlockdevOptionsFile), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsFile_fields(m, &(*obj)->file, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_HTTP:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->http, sizeof(BlockdevOptionsFile), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsFile_fields(m, &(*obj)->http, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_HTTPS:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->https, sizeof(BlockdevOptionsFile), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsFile_fields(m, &(*obj)->https, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_FTP:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->ftp, sizeof(BlockdevOptionsFile), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsFile_fields(m, &(*obj)->ftp, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_FTPS:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->ftps, sizeof(BlockdevOptionsFile), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsFile_fields(m, &(*obj)->ftps, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_TFTP:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->tftp, sizeof(BlockdevOptionsFile), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsFile_fields(m, &(*obj)->tftp, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_VVFAT:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->vvfat, sizeof(BlockdevOptionsVVFAT), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsVVFAT_fields(m, &(*obj)->vvfat, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_BOCHS:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->bochs, sizeof(BlockdevOptionsGenericFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericFormat_fields(m, &(*obj)->bochs, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_CLOOP:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->cloop, sizeof(BlockdevOptionsGenericFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericFormat_fields(m, &(*obj)->cloop, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_COW:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->cow, sizeof(BlockdevOptionsGenericCOWFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericCOWFormat_fields(m, &(*obj)->cow, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_DMG:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->dmg, sizeof(BlockdevOptionsGenericFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericFormat_fields(m, &(*obj)->dmg, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_PARALLELS:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->parallels, sizeof(BlockdevOptionsGenericFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericFormat_fields(m, &(*obj)->parallels, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_QCOW:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->qcow, sizeof(BlockdevOptionsGenericCOWFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericCOWFormat_fields(m, &(*obj)->qcow, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_QCOW2:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->qcow2, sizeof(BlockdevOptionsQcow2), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsQcow2_fields(m, &(*obj)->qcow2, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_QED:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->qed, sizeof(BlockdevOptionsGenericCOWFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericCOWFormat_fields(m, &(*obj)->qed, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_RAW:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->raw, sizeof(BlockdevOptionsGenericFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericFormat_fields(m, &(*obj)->raw, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_VDI:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->vdi, sizeof(BlockdevOptionsGenericFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericFormat_fields(m, &(*obj)->vdi, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_VHDX:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->vhdx, sizeof(BlockdevOptionsGenericFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericFormat_fields(m, &(*obj)->vhdx, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_VMDK:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->vmdk, sizeof(BlockdevOptionsGenericCOWFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericCOWFormat_fields(m, &(*obj)->vmdk, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    case BLOCKDEV_OPTIONS_KIND_VPC:
+                        visit_start_implicit_struct(m, (void**) &(*obj)->vpc, sizeof(BlockdevOptionsGenericFormat), &err);
+                        if (!err) {
+                            visit_type_BlockdevOptionsGenericFormat_fields(m, &(*obj)->vpc, &err);
+                            error_propagate(errp, err);
+                            err = NULL;
+                            visit_end_implicit_struct(m, &err);
+                        }
+                        break;
+                    default:
+                        abort();
+                    }
+                }
+                error_propagate(errp, err);
+                err = NULL;
+            }
+            /* Always call end_struct if start_struct succeeded.  */
+            visit_end_struct(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevOptionsList(Visitor *m, BlockdevOptionsList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevOptionsList *native_i = (BlockdevOptionsList *)i;
+                visit_type_BlockdevOptions(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+
+void visit_type_BlockdevRef(Visitor *m, BlockdevRef ** obj, const char *name, Error **errp)
+{
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_implicit_struct(m, (void**) obj, sizeof(BlockdevRef), &err);
+        visit_get_next_type(m, (int*) &(*obj)->kind, BlockdevRef_qtypes, name, &err);
+        switch ((*obj)->kind) {
+        case BLOCKDEV_REF_KIND_DEFINITION:
+            visit_type_BlockdevOptions(m, &(*obj)->definition, name, &err);
+            break;
+        case BLOCKDEV_REF_KIND_REFERENCE:
+            visit_type_str(m, &(*obj)->reference, name, &err);
+            break;
+        default:
+            abort();
+        }
+        error_propagate(errp, err);
+        err = NULL;
+        visit_end_implicit_struct(m, &err);
+    }
+}
+
+void visit_type_BlockdevRefList(Visitor *m, BlockdevRefList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                BlockdevRefList *native_i = (BlockdevRefList *)i;
+                visit_type_BlockdevRef(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
diff --git a/qapi-auto-generated/qapi-visit.h b/qapi-auto-generated/qapi-visit.h
new file mode 100644
index 0000000..1bad133
--- /dev/null
+++ b/qapi-auto-generated/qapi-visit.h
@@ -0,0 +1,411 @@
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QAPI visitor function
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QAPI_VISIT_H
+#define QAPI_VISIT_H
+
+#include "qapi/visitor.h"
+#include "qapi-types.h"
+
+
+#ifndef QAPI_VISIT_BUILTIN_VISITOR_DECL_H
+#define QAPI_VISIT_BUILTIN_VISITOR_DECL_H
+
+void visit_type_strList(Visitor *m, strList ** obj, const char *name, Error **errp);
+void visit_type_intList(Visitor *m, intList ** obj, const char *name, Error **errp);
+void visit_type_numberList(Visitor *m, numberList ** obj, const char *name, Error **errp);
+void visit_type_boolList(Visitor *m, boolList ** obj, const char *name, Error **errp);
+void visit_type_int8List(Visitor *m, int8List ** obj, const char *name, Error **errp);
+void visit_type_int16List(Visitor *m, int16List ** obj, const char *name, Error **errp);
+void visit_type_int32List(Visitor *m, int32List ** obj, const char *name, Error **errp);
+void visit_type_int64List(Visitor *m, int64List ** obj, const char *name, Error **errp);
+void visit_type_uint8List(Visitor *m, uint8List ** obj, const char *name, Error **errp);
+void visit_type_uint16List(Visitor *m, uint16List ** obj, const char *name, Error **errp);
+void visit_type_uint32List(Visitor *m, uint32List ** obj, const char *name, Error **errp);
+void visit_type_uint64List(Visitor *m, uint64List ** obj, const char *name, Error **errp);
+
+#endif /* QAPI_VISIT_BUILTIN_VISITOR_DECL_H */
+
+
+void visit_type_ErrorClass(Visitor *m, ErrorClass * obj, const char *name, Error **errp);
+void visit_type_ErrorClassList(Visitor *m, ErrorClassList ** obj, const char *name, Error **errp);
+
+void visit_type_NameInfo(Visitor *m, NameInfo ** obj, const char *name, Error **errp);
+void visit_type_NameInfoList(Visitor *m, NameInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_VersionInfo(Visitor *m, VersionInfo ** obj, const char *name, Error **errp);
+void visit_type_VersionInfoList(Visitor *m, VersionInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_KvmInfo(Visitor *m, KvmInfo ** obj, const char *name, Error **errp);
+void visit_type_KvmInfoList(Visitor *m, KvmInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_RunState(Visitor *m, RunState * obj, const char *name, Error **errp);
+void visit_type_RunStateList(Visitor *m, RunStateList ** obj, const char *name, Error **errp);
+
+void visit_type_SnapshotInfo(Visitor *m, SnapshotInfo ** obj, const char *name, Error **errp);
+void visit_type_SnapshotInfoList(Visitor *m, SnapshotInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_ImageInfoSpecificQCow2(Visitor *m, ImageInfoSpecificQCow2 ** obj, const char *name, Error **errp);
+void visit_type_ImageInfoSpecificQCow2List(Visitor *m, ImageInfoSpecificQCow2List ** obj, const char *name, Error **errp);
+
+void visit_type_ImageInfoSpecificVmdk(Visitor *m, ImageInfoSpecificVmdk ** obj, const char *name, Error **errp);
+void visit_type_ImageInfoSpecificVmdkList(Visitor *m, ImageInfoSpecificVmdkList ** obj, const char *name, Error **errp);
+
+void visit_type_ImageInfoSpecificKind(Visitor *m, ImageInfoSpecificKind * obj, const char *name, Error **errp);
+
+void visit_type_ImageInfoSpecific(Visitor *m, ImageInfoSpecific ** obj, const char *name, Error **errp);
+void visit_type_ImageInfoSpecificList(Visitor *m, ImageInfoSpecificList ** obj, const char *name, Error **errp);
+
+void visit_type_ImageInfo(Visitor *m, ImageInfo ** obj, const char *name, Error **errp);
+void visit_type_ImageInfoList(Visitor *m, ImageInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_ImageCheck(Visitor *m, ImageCheck ** obj, const char *name, Error **errp);
+void visit_type_ImageCheckList(Visitor *m, ImageCheckList ** obj, const char *name, Error **errp);
+
+void visit_type_StatusInfo(Visitor *m, StatusInfo ** obj, const char *name, Error **errp);
+void visit_type_StatusInfoList(Visitor *m, StatusInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_UuidInfo(Visitor *m, UuidInfo ** obj, const char *name, Error **errp);
+void visit_type_UuidInfoList(Visitor *m, UuidInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevInfo(Visitor *m, ChardevInfo ** obj, const char *name, Error **errp);
+void visit_type_ChardevInfoList(Visitor *m, ChardevInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_DataFormat(Visitor *m, DataFormat * obj, const char *name, Error **errp);
+void visit_type_DataFormatList(Visitor *m, DataFormatList ** obj, const char *name, Error **errp);
+
+void visit_type_CommandInfo(Visitor *m, CommandInfo ** obj, const char *name, Error **errp);
+void visit_type_CommandInfoList(Visitor *m, CommandInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_EventInfo(Visitor *m, EventInfo ** obj, const char *name, Error **errp);
+void visit_type_EventInfoList(Visitor *m, EventInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_MigrationStats(Visitor *m, MigrationStats ** obj, const char *name, Error **errp);
+void visit_type_MigrationStatsList(Visitor *m, MigrationStatsList ** obj, const char *name, Error **errp);
+
+void visit_type_XBZRLECacheStats(Visitor *m, XBZRLECacheStats ** obj, const char *name, Error **errp);
+void visit_type_XBZRLECacheStatsList(Visitor *m, XBZRLECacheStatsList ** obj, const char *name, Error **errp);
+
+void visit_type_MigrationInfo(Visitor *m, MigrationInfo ** obj, const char *name, Error **errp);
+void visit_type_MigrationInfoList(Visitor *m, MigrationInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_MigrationCapability(Visitor *m, MigrationCapability * obj, const char *name, Error **errp);
+void visit_type_MigrationCapabilityList(Visitor *m, MigrationCapabilityList ** obj, const char *name, Error **errp);
+
+void visit_type_MigrationCapabilityStatus(Visitor *m, MigrationCapabilityStatus ** obj, const char *name, Error **errp);
+void visit_type_MigrationCapabilityStatusList(Visitor *m, MigrationCapabilityStatusList ** obj, const char *name, Error **errp);
+
+void visit_type_MouseInfo(Visitor *m, MouseInfo ** obj, const char *name, Error **errp);
+void visit_type_MouseInfoList(Visitor *m, MouseInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_CpuInfo(Visitor *m, CpuInfo ** obj, const char *name, Error **errp);
+void visit_type_CpuInfoList(Visitor *m, CpuInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockDeviceInfo(Visitor *m, BlockDeviceInfo ** obj, const char *name, Error **errp);
+void visit_type_BlockDeviceInfoList(Visitor *m, BlockDeviceInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockDeviceIoStatus(Visitor *m, BlockDeviceIoStatus * obj, const char *name, Error **errp);
+void visit_type_BlockDeviceIoStatusList(Visitor *m, BlockDeviceIoStatusList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockDeviceMapEntry(Visitor *m, BlockDeviceMapEntry ** obj, const char *name, Error **errp);
+void visit_type_BlockDeviceMapEntryList(Visitor *m, BlockDeviceMapEntryList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockDirtyInfo(Visitor *m, BlockDirtyInfo ** obj, const char *name, Error **errp);
+void visit_type_BlockDirtyInfoList(Visitor *m, BlockDirtyInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockInfo(Visitor *m, BlockInfo ** obj, const char *name, Error **errp);
+void visit_type_BlockInfoList(Visitor *m, BlockInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockDeviceStats(Visitor *m, BlockDeviceStats ** obj, const char *name, Error **errp);
+void visit_type_BlockDeviceStatsList(Visitor *m, BlockDeviceStatsList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockStats(Visitor *m, BlockStats ** obj, const char *name, Error **errp);
+void visit_type_BlockStatsList(Visitor *m, BlockStatsList ** obj, const char *name, Error **errp);
+
+void visit_type_VncClientInfo(Visitor *m, VncClientInfo ** obj, const char *name, Error **errp);
+void visit_type_VncClientInfoList(Visitor *m, VncClientInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_VncInfo(Visitor *m, VncInfo ** obj, const char *name, Error **errp);
+void visit_type_VncInfoList(Visitor *m, VncInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_SpiceChannel(Visitor *m, SpiceChannel ** obj, const char *name, Error **errp);
+void visit_type_SpiceChannelList(Visitor *m, SpiceChannelList ** obj, const char *name, Error **errp);
+
+void visit_type_SpiceQueryMouseMode(Visitor *m, SpiceQueryMouseMode * obj, const char *name, Error **errp);
+void visit_type_SpiceQueryMouseModeList(Visitor *m, SpiceQueryMouseModeList ** obj, const char *name, Error **errp);
+
+void visit_type_SpiceInfo(Visitor *m, SpiceInfo ** obj, const char *name, Error **errp);
+void visit_type_SpiceInfoList(Visitor *m, SpiceInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_BalloonInfo(Visitor *m, BalloonInfo ** obj, const char *name, Error **errp);
+void visit_type_BalloonInfoList(Visitor *m, BalloonInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_PciMemoryRange(Visitor *m, PciMemoryRange ** obj, const char *name, Error **errp);
+void visit_type_PciMemoryRangeList(Visitor *m, PciMemoryRangeList ** obj, const char *name, Error **errp);
+
+void visit_type_PciMemoryRegion(Visitor *m, PciMemoryRegion ** obj, const char *name, Error **errp);
+void visit_type_PciMemoryRegionList(Visitor *m, PciMemoryRegionList ** obj, const char *name, Error **errp);
+
+void visit_type_PciBridgeInfo(Visitor *m, PciBridgeInfo ** obj, const char *name, Error **errp);
+void visit_type_PciBridgeInfoList(Visitor *m, PciBridgeInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_PciDeviceInfo(Visitor *m, PciDeviceInfo ** obj, const char *name, Error **errp);
+void visit_type_PciDeviceInfoList(Visitor *m, PciDeviceInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_PciInfo(Visitor *m, PciInfo ** obj, const char *name, Error **errp);
+void visit_type_PciInfoList(Visitor *m, PciInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevOnError(Visitor *m, BlockdevOnError * obj, const char *name, Error **errp);
+void visit_type_BlockdevOnErrorList(Visitor *m, BlockdevOnErrorList ** obj, const char *name, Error **errp);
+
+void visit_type_MirrorSyncMode(Visitor *m, MirrorSyncMode * obj, const char *name, Error **errp);
+void visit_type_MirrorSyncModeList(Visitor *m, MirrorSyncModeList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockJobType(Visitor *m, BlockJobType * obj, const char *name, Error **errp);
+void visit_type_BlockJobTypeList(Visitor *m, BlockJobTypeList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockJobInfo(Visitor *m, BlockJobInfo ** obj, const char *name, Error **errp);
+void visit_type_BlockJobInfoList(Visitor *m, BlockJobInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_NewImageMode(Visitor *m, NewImageMode * obj, const char *name, Error **errp);
+void visit_type_NewImageModeList(Visitor *m, NewImageModeList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevSnapshot(Visitor *m, BlockdevSnapshot ** obj, const char *name, Error **errp);
+void visit_type_BlockdevSnapshotList(Visitor *m, BlockdevSnapshotList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevSnapshotInternal(Visitor *m, BlockdevSnapshotInternal ** obj, const char *name, Error **errp);
+void visit_type_BlockdevSnapshotInternalList(Visitor *m, BlockdevSnapshotInternalList ** obj, const char *name, Error **errp);
+
+void visit_type_DriveBackup(Visitor *m, DriveBackup ** obj, const char *name, Error **errp);
+void visit_type_DriveBackupList(Visitor *m, DriveBackupList ** obj, const char *name, Error **errp);
+
+void visit_type_Abort(Visitor *m, Abort ** obj, const char *name, Error **errp);
+void visit_type_AbortList(Visitor *m, AbortList ** obj, const char *name, Error **errp);
+
+void visit_type_TransactionActionKind(Visitor *m, TransactionActionKind * obj, const char *name, Error **errp);
+
+void visit_type_TransactionAction(Visitor *m, TransactionAction ** obj, const char *name, Error **errp);
+void visit_type_TransactionActionList(Visitor *m, TransactionActionList ** obj, const char *name, Error **errp);
+
+void visit_type_ObjectPropertyInfo(Visitor *m, ObjectPropertyInfo ** obj, const char *name, Error **errp);
+void visit_type_ObjectPropertyInfoList(Visitor *m, ObjectPropertyInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_ObjectTypeInfo(Visitor *m, ObjectTypeInfo ** obj, const char *name, Error **errp);
+void visit_type_ObjectTypeInfoList(Visitor *m, ObjectTypeInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_DevicePropertyInfo(Visitor *m, DevicePropertyInfo ** obj, const char *name, Error **errp);
+void visit_type_DevicePropertyInfoList(Visitor *m, DevicePropertyInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_NetdevNoneOptions(Visitor *m, NetdevNoneOptions ** obj, const char *name, Error **errp);
+void visit_type_NetdevNoneOptionsList(Visitor *m, NetdevNoneOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_NetLegacyNicOptions(Visitor *m, NetLegacyNicOptions ** obj, const char *name, Error **errp);
+void visit_type_NetLegacyNicOptionsList(Visitor *m, NetLegacyNicOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_String(Visitor *m, String ** obj, const char *name, Error **errp);
+void visit_type_StringList(Visitor *m, StringList ** obj, const char *name, Error **errp);
+
+void visit_type_NetdevUserOptions(Visitor *m, NetdevUserOptions ** obj, const char *name, Error **errp);
+void visit_type_NetdevUserOptionsList(Visitor *m, NetdevUserOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_NetdevTapOptions(Visitor *m, NetdevTapOptions ** obj, const char *name, Error **errp);
+void visit_type_NetdevTapOptionsList(Visitor *m, NetdevTapOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_NetdevSocketOptions(Visitor *m, NetdevSocketOptions ** obj, const char *name, Error **errp);
+void visit_type_NetdevSocketOptionsList(Visitor *m, NetdevSocketOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_NetdevVdeOptions(Visitor *m, NetdevVdeOptions ** obj, const char *name, Error **errp);
+void visit_type_NetdevVdeOptionsList(Visitor *m, NetdevVdeOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_NetdevDumpOptions(Visitor *m, NetdevDumpOptions ** obj, const char *name, Error **errp);
+void visit_type_NetdevDumpOptionsList(Visitor *m, NetdevDumpOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_NetdevBridgeOptions(Visitor *m, NetdevBridgeOptions ** obj, const char *name, Error **errp);
+void visit_type_NetdevBridgeOptionsList(Visitor *m, NetdevBridgeOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_NetdevHubPortOptions(Visitor *m, NetdevHubPortOptions ** obj, const char *name, Error **errp);
+void visit_type_NetdevHubPortOptionsList(Visitor *m, NetdevHubPortOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_NetdevNetmapOptions(Visitor *m, NetdevNetmapOptions ** obj, const char *name, Error **errp);
+void visit_type_NetdevNetmapOptionsList(Visitor *m, NetdevNetmapOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_NetClientOptionsKind(Visitor *m, NetClientOptionsKind * obj, const char *name, Error **errp);
+
+void visit_type_NetClientOptions(Visitor *m, NetClientOptions ** obj, const char *name, Error **errp);
+void visit_type_NetClientOptionsList(Visitor *m, NetClientOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_NetLegacy(Visitor *m, NetLegacy ** obj, const char *name, Error **errp);
+void visit_type_NetLegacyList(Visitor *m, NetLegacyList ** obj, const char *name, Error **errp);
+
+void visit_type_Netdev(Visitor *m, Netdev ** obj, const char *name, Error **errp);
+void visit_type_NetdevList(Visitor *m, NetdevList ** obj, const char *name, Error **errp);
+
+void visit_type_InetSocketAddress(Visitor *m, InetSocketAddress ** obj, const char *name, Error **errp);
+void visit_type_InetSocketAddressList(Visitor *m, InetSocketAddressList ** obj, const char *name, Error **errp);
+
+void visit_type_UnixSocketAddress(Visitor *m, UnixSocketAddress ** obj, const char *name, Error **errp);
+void visit_type_UnixSocketAddressList(Visitor *m, UnixSocketAddressList ** obj, const char *name, Error **errp);
+
+void visit_type_SocketAddressKind(Visitor *m, SocketAddressKind * obj, const char *name, Error **errp);
+
+void visit_type_SocketAddress(Visitor *m, SocketAddress ** obj, const char *name, Error **errp);
+void visit_type_SocketAddressList(Visitor *m, SocketAddressList ** obj, const char *name, Error **errp);
+
+void visit_type_MachineInfo(Visitor *m, MachineInfo ** obj, const char *name, Error **errp);
+void visit_type_MachineInfoList(Visitor *m, MachineInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_CpuDefinitionInfo(Visitor *m, CpuDefinitionInfo ** obj, const char *name, Error **errp);
+void visit_type_CpuDefinitionInfoList(Visitor *m, CpuDefinitionInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_AddfdInfo(Visitor *m, AddfdInfo ** obj, const char *name, Error **errp);
+void visit_type_AddfdInfoList(Visitor *m, AddfdInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_FdsetFdInfo(Visitor *m, FdsetFdInfo ** obj, const char *name, Error **errp);
+void visit_type_FdsetFdInfoList(Visitor *m, FdsetFdInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_FdsetInfo(Visitor *m, FdsetInfo ** obj, const char *name, Error **errp);
+void visit_type_FdsetInfoList(Visitor *m, FdsetInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_TargetInfo(Visitor *m, TargetInfo ** obj, const char *name, Error **errp);
+void visit_type_TargetInfoList(Visitor *m, TargetInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_QKeyCode(Visitor *m, QKeyCode * obj, const char *name, Error **errp);
+void visit_type_QKeyCodeList(Visitor *m, QKeyCodeList ** obj, const char *name, Error **errp);
+
+void visit_type_KeyValueKind(Visitor *m, KeyValueKind * obj, const char *name, Error **errp);
+
+void visit_type_KeyValue(Visitor *m, KeyValue ** obj, const char *name, Error **errp);
+void visit_type_KeyValueList(Visitor *m, KeyValueList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevFile(Visitor *m, ChardevFile ** obj, const char *name, Error **errp);
+void visit_type_ChardevFileList(Visitor *m, ChardevFileList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevHostdev(Visitor *m, ChardevHostdev ** obj, const char *name, Error **errp);
+void visit_type_ChardevHostdevList(Visitor *m, ChardevHostdevList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevSocket(Visitor *m, ChardevSocket ** obj, const char *name, Error **errp);
+void visit_type_ChardevSocketList(Visitor *m, ChardevSocketList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevUdp(Visitor *m, ChardevUdp ** obj, const char *name, Error **errp);
+void visit_type_ChardevUdpList(Visitor *m, ChardevUdpList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevMux(Visitor *m, ChardevMux ** obj, const char *name, Error **errp);
+void visit_type_ChardevMuxList(Visitor *m, ChardevMuxList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevStdio(Visitor *m, ChardevStdio ** obj, const char *name, Error **errp);
+void visit_type_ChardevStdioList(Visitor *m, ChardevStdioList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevSpiceChannel(Visitor *m, ChardevSpiceChannel ** obj, const char *name, Error **errp);
+void visit_type_ChardevSpiceChannelList(Visitor *m, ChardevSpiceChannelList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevSpicePort(Visitor *m, ChardevSpicePort ** obj, const char *name, Error **errp);
+void visit_type_ChardevSpicePortList(Visitor *m, ChardevSpicePortList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevVC(Visitor *m, ChardevVC ** obj, const char *name, Error **errp);
+void visit_type_ChardevVCList(Visitor *m, ChardevVCList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevRingbuf(Visitor *m, ChardevRingbuf ** obj, const char *name, Error **errp);
+void visit_type_ChardevRingbufList(Visitor *m, ChardevRingbufList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevDummy(Visitor *m, ChardevDummy ** obj, const char *name, Error **errp);
+void visit_type_ChardevDummyList(Visitor *m, ChardevDummyList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevBackendKind(Visitor *m, ChardevBackendKind * obj, const char *name, Error **errp);
+
+void visit_type_ChardevBackend(Visitor *m, ChardevBackend ** obj, const char *name, Error **errp);
+void visit_type_ChardevBackendList(Visitor *m, ChardevBackendList ** obj, const char *name, Error **errp);
+
+void visit_type_ChardevReturn(Visitor *m, ChardevReturn ** obj, const char *name, Error **errp);
+void visit_type_ChardevReturnList(Visitor *m, ChardevReturnList ** obj, const char *name, Error **errp);
+
+void visit_type_TpmModel(Visitor *m, TpmModel * obj, const char *name, Error **errp);
+void visit_type_TpmModelList(Visitor *m, TpmModelList ** obj, const char *name, Error **errp);
+
+void visit_type_TpmType(Visitor *m, TpmType * obj, const char *name, Error **errp);
+void visit_type_TpmTypeList(Visitor *m, TpmTypeList ** obj, const char *name, Error **errp);
+
+void visit_type_TPMPassthroughOptions(Visitor *m, TPMPassthroughOptions ** obj, const char *name, Error **errp);
+void visit_type_TPMPassthroughOptionsList(Visitor *m, TPMPassthroughOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_TpmTypeOptionsKind(Visitor *m, TpmTypeOptionsKind * obj, const char *name, Error **errp);
+
+void visit_type_TpmTypeOptions(Visitor *m, TpmTypeOptions ** obj, const char *name, Error **errp);
+void visit_type_TpmTypeOptionsList(Visitor *m, TpmTypeOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_TPMInfo(Visitor *m, TPMInfo ** obj, const char *name, Error **errp);
+void visit_type_TPMInfoList(Visitor *m, TPMInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_AcpiTableOptions(Visitor *m, AcpiTableOptions ** obj, const char *name, Error **errp);
+void visit_type_AcpiTableOptionsList(Visitor *m, AcpiTableOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_CommandLineParameterType(Visitor *m, CommandLineParameterType * obj, const char *name, Error **errp);
+void visit_type_CommandLineParameterTypeList(Visitor *m, CommandLineParameterTypeList ** obj, const char *name, Error **errp);
+
+void visit_type_CommandLineParameterInfo(Visitor *m, CommandLineParameterInfo ** obj, const char *name, Error **errp);
+void visit_type_CommandLineParameterInfoList(Visitor *m, CommandLineParameterInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_CommandLineOptionInfo(Visitor *m, CommandLineOptionInfo ** obj, const char *name, Error **errp);
+void visit_type_CommandLineOptionInfoList(Visitor *m, CommandLineOptionInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_X86CPURegister32(Visitor *m, X86CPURegister32 * obj, const char *name, Error **errp);
+void visit_type_X86CPURegister32List(Visitor *m, X86CPURegister32List ** obj, const char *name, Error **errp);
+
+void visit_type_X86CPUFeatureWordInfo(Visitor *m, X86CPUFeatureWordInfo ** obj, const char *name, Error **errp);
+void visit_type_X86CPUFeatureWordInfoList(Visitor *m, X86CPUFeatureWordInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_RxState(Visitor *m, RxState * obj, const char *name, Error **errp);
+void visit_type_RxStateList(Visitor *m, RxStateList ** obj, const char *name, Error **errp);
+
+void visit_type_RxFilterInfo(Visitor *m, RxFilterInfo ** obj, const char *name, Error **errp);
+void visit_type_RxFilterInfoList(Visitor *m, RxFilterInfoList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevDiscardOptions(Visitor *m, BlockdevDiscardOptions * obj, const char *name, Error **errp);
+void visit_type_BlockdevDiscardOptionsList(Visitor *m, BlockdevDiscardOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevAioOptions(Visitor *m, BlockdevAioOptions * obj, const char *name, Error **errp);
+void visit_type_BlockdevAioOptionsList(Visitor *m, BlockdevAioOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevCacheOptions(Visitor *m, BlockdevCacheOptions ** obj, const char *name, Error **errp);
+void visit_type_BlockdevCacheOptionsList(Visitor *m, BlockdevCacheOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevOptionsBase(Visitor *m, BlockdevOptionsBase ** obj, const char *name, Error **errp);
+void visit_type_BlockdevOptionsBaseList(Visitor *m, BlockdevOptionsBaseList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevOptionsFile(Visitor *m, BlockdevOptionsFile ** obj, const char *name, Error **errp);
+void visit_type_BlockdevOptionsFileList(Visitor *m, BlockdevOptionsFileList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevOptionsVVFAT(Visitor *m, BlockdevOptionsVVFAT ** obj, const char *name, Error **errp);
+void visit_type_BlockdevOptionsVVFATList(Visitor *m, BlockdevOptionsVVFATList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevOptionsGenericFormat(Visitor *m, BlockdevOptionsGenericFormat ** obj, const char *name, Error **errp);
+void visit_type_BlockdevOptionsGenericFormatList(Visitor *m, BlockdevOptionsGenericFormatList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevOptionsGenericCOWFormat(Visitor *m, BlockdevOptionsGenericCOWFormat ** obj, const char *name, Error **errp);
+void visit_type_BlockdevOptionsGenericCOWFormatList(Visitor *m, BlockdevOptionsGenericCOWFormatList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevOptionsQcow2(Visitor *m, BlockdevOptionsQcow2 ** obj, const char *name, Error **errp);
+void visit_type_BlockdevOptionsQcow2List(Visitor *m, BlockdevOptionsQcow2List ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevOptionsKind(Visitor *m, BlockdevOptionsKind * obj, const char *name, Error **errp);
+
+void visit_type_BlockdevOptions(Visitor *m, BlockdevOptions ** obj, const char *name, Error **errp);
+void visit_type_BlockdevOptionsList(Visitor *m, BlockdevOptionsList ** obj, const char *name, Error **errp);
+
+void visit_type_BlockdevRefKind(Visitor *m, BlockdevRefKind * obj, const char *name, Error **errp);
+
+void visit_type_BlockdevRef(Visitor *m, BlockdevRef ** obj, const char *name, Error **errp);
+void visit_type_BlockdevRefList(Visitor *m, BlockdevRefList ** obj, const char *name, Error **errp);
+
+#endif
diff --git a/qapi-auto-generated/qmp-commands.h b/qapi-auto-generated/qmp-commands.h
new file mode 100644
index 0000000..0b2f190
--- /dev/null
+++ b/qapi-auto-generated/qmp-commands.h
@@ -0,0 +1,210 @@
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QAPI function prototypes
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QMP_COMMANDS_H
+#define QMP_COMMANDS_H
+
+#include "qapi-types.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/error.h"
+
+void qmp_add_client(const char * protocol, const char * fdname, bool has_skipauth, bool skipauth, bool has_tls, bool tls, Error **errp);
+int qmp_marshal_input_add_client(Monitor *mon, const QDict *qdict, QObject **ret);
+NameInfo * qmp_query_name(Error **errp);
+int qmp_marshal_input_query_name(Monitor *mon, const QDict *qdict, QObject **ret);
+VersionInfo * qmp_query_version(Error **errp);
+int qmp_marshal_input_query_version(Monitor *mon, const QDict *qdict, QObject **ret);
+KvmInfo * qmp_query_kvm(Error **errp);
+int qmp_marshal_input_query_kvm(Monitor *mon, const QDict *qdict, QObject **ret);
+StatusInfo * qmp_query_status(Error **errp);
+int qmp_marshal_input_query_status(Monitor *mon, const QDict *qdict, QObject **ret);
+UuidInfo * qmp_query_uuid(Error **errp);
+int qmp_marshal_input_query_uuid(Monitor *mon, const QDict *qdict, QObject **ret);
+ChardevInfoList * qmp_query_chardev(Error **errp);
+int qmp_marshal_input_query_chardev(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_ringbuf_write(const char * device, const char * data, bool has_format, DataFormat format, Error **errp);
+int qmp_marshal_input_ringbuf_write(Monitor *mon, const QDict *qdict, QObject **ret);
+char * qmp_ringbuf_read(const char * device, int64_t size, bool has_format, DataFormat format, Error **errp);
+int qmp_marshal_input_ringbuf_read(Monitor *mon, const QDict *qdict, QObject **ret);
+CommandInfoList * qmp_query_commands(Error **errp);
+int qmp_marshal_input_query_commands(Monitor *mon, const QDict *qdict, QObject **ret);
+EventInfoList * qmp_query_events(Error **errp);
+int qmp_marshal_input_query_events(Monitor *mon, const QDict *qdict, QObject **ret);
+MigrationInfo * qmp_query_migrate(Error **errp);
+int qmp_marshal_input_query_migrate(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_migrate_set_capabilities(MigrationCapabilityStatusList * capabilities, Error **errp);
+int qmp_marshal_input_migrate_set_capabilities(Monitor *mon, const QDict *qdict, QObject **ret);
+MigrationCapabilityStatusList * qmp_query_migrate_capabilities(Error **errp);
+int qmp_marshal_input_query_migrate_capabilities(Monitor *mon, const QDict *qdict, QObject **ret);
+MouseInfoList * qmp_query_mice(Error **errp);
+int qmp_marshal_input_query_mice(Monitor *mon, const QDict *qdict, QObject **ret);
+CpuInfoList * qmp_query_cpus(Error **errp);
+int qmp_marshal_input_query_cpus(Monitor *mon, const QDict *qdict, QObject **ret);
+BlockInfoList * qmp_query_block(Error **errp);
+int qmp_marshal_input_query_block(Monitor *mon, const QDict *qdict, QObject **ret);
+BlockStatsList * qmp_query_blockstats(Error **errp);
+int qmp_marshal_input_query_blockstats(Monitor *mon, const QDict *qdict, QObject **ret);
+VncInfo * qmp_query_vnc(Error **errp);
+int qmp_marshal_input_query_vnc(Monitor *mon, const QDict *qdict, QObject **ret);
+SpiceInfo * qmp_query_spice(Error **errp);
+int qmp_marshal_input_query_spice(Monitor *mon, const QDict *qdict, QObject **ret);
+BalloonInfo * qmp_query_balloon(Error **errp);
+int qmp_marshal_input_query_balloon(Monitor *mon, const QDict *qdict, QObject **ret);
+PciInfoList * qmp_query_pci(Error **errp);
+int qmp_marshal_input_query_pci(Monitor *mon, const QDict *qdict, QObject **ret);
+BlockJobInfoList * qmp_query_block_jobs(Error **errp);
+int qmp_marshal_input_query_block_jobs(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_quit(Error **errp);
+int qmp_marshal_input_quit(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_stop(Error **errp);
+int qmp_marshal_input_stop(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_system_reset(Error **errp);
+int qmp_marshal_input_system_reset(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_system_powerdown(Error **errp);
+int qmp_marshal_input_system_powerdown(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_cpu(int64_t index, Error **errp);
+int qmp_marshal_input_cpu(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_cpu_add(int64_t id, Error **errp);
+int qmp_marshal_input_cpu_add(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_memsave(int64_t val, int64_t size, const char * filename, bool has_cpu_index, int64_t cpu_index, Error **errp);
+int qmp_marshal_input_memsave(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_pmemsave(int64_t val, int64_t size, const char * filename, Error **errp);
+int qmp_marshal_input_pmemsave(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_cont(Error **errp);
+int qmp_marshal_input_cont(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_system_wakeup(Error **errp);
+int qmp_marshal_input_system_wakeup(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_inject_nmi(Error **errp);
+int qmp_marshal_input_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_set_link(const char * name, bool up, Error **errp);
+int qmp_marshal_input_set_link(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_block_passwd(const char * device, const char * password, Error **errp);
+int qmp_marshal_input_block_passwd(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_balloon(int64_t value, Error **errp);
+int qmp_marshal_input_balloon(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_block_resize(const char * device, int64_t size, Error **errp);
+int qmp_marshal_input_block_resize(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_transaction(TransactionActionList * actions, Error **errp);
+int qmp_marshal_input_transaction(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_blockdev_snapshot_sync(const char * device, const char * snapshot_file, bool has_format, const char * format, bool has_mode, NewImageMode mode, Error **errp);
+int qmp_marshal_input_blockdev_snapshot_sync(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_blockdev_snapshot_internal_sync(const char * device, const char * name, Error **errp);
+int qmp_marshal_input_blockdev_snapshot_internal_sync(Monitor *mon, const QDict *qdict, QObject **ret);
+SnapshotInfo * qmp_blockdev_snapshot_delete_internal_sync(const char * device, bool has_id, const char * id, bool has_name, const char * name, Error **errp);
+int qmp_marshal_input_blockdev_snapshot_delete_internal_sync(Monitor *mon, const QDict *qdict, QObject **ret);
+char * qmp_human_monitor_command(const char * command_line, bool has_cpu_index, int64_t cpu_index, Error **errp);
+int qmp_marshal_input_human_monitor_command(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_block_commit(const char * device, bool has_base, const char * base, const char * top, bool has_speed, int64_t speed, Error **errp);
+int qmp_marshal_input_block_commit(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_drive_backup(const char * device, const char * target, bool has_format, const char * format, MirrorSyncMode sync, bool has_mode, NewImageMode mode, bool has_speed, int64_t speed, bool has_on_source_error, BlockdevOnError on_source_error, bool has_on_target_error, BlockdevOnError on_target_error, Error **errp);
+int qmp_marshal_input_drive_backup(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_drive_mirror(const char * device, const char * target, bool has_format, const char * format, MirrorSyncMode sync, bool has_mode, NewImageMode mode, bool has_speed, int64_t speed, bool has_granularity, uint32_t granularity, bool has_buf_size, int64_t buf_size, bool has_on_source_error, BlockdevOnError on_source_error, bool has_on_target_error, BlockdevOnError on_target_error, Error **errp);
+int qmp_marshal_input_drive_mirror(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_migrate_cancel(Error **errp);
+int qmp_marshal_input_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_migrate_set_downtime(double value, Error **errp);
+int qmp_marshal_input_migrate_set_downtime(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_migrate_set_speed(int64_t value, Error **errp);
+int qmp_marshal_input_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_migrate_set_cache_size(int64_t value, Error **errp);
+int qmp_marshal_input_migrate_set_cache_size(Monitor *mon, const QDict *qdict, QObject **ret);
+int64_t qmp_query_migrate_cache_size(Error **errp);
+int qmp_marshal_input_query_migrate_cache_size(Monitor *mon, const QDict *qdict, QObject **ret);
+ObjectPropertyInfoList * qmp_qom_list(const char * path, Error **errp);
+int qmp_marshal_input_qom_list(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_set_password(const char * protocol, const char * password, bool has_connected, const char * connected, Error **errp);
+int qmp_marshal_input_set_password(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_expire_password(const char * protocol, const char * time, Error **errp);
+int qmp_marshal_input_expire_password(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_eject(const char * device, bool has_force, bool force, Error **errp);
+int qmp_marshal_input_eject(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_change_vnc_password(const char * password, Error **errp);
+int qmp_marshal_input_change_vnc_password(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_change(const char * device, const char * target, bool has_arg, const char * arg, Error **errp);
+int qmp_marshal_input_change(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_block_set_io_throttle(const char * device, int64_t bps, int64_t bps_rd, int64_t bps_wr, int64_t iops, int64_t iops_rd, int64_t iops_wr, bool has_bps_max, int64_t bps_max, bool has_bps_rd_max, int64_t bps_rd_max, bool has_bps_wr_max, int64_t bps_wr_max, bool has_iops_max, int64_t iops_max, bool has_iops_rd_max, int64_t iops_rd_max, bool has_iops_wr_max, int64_t iops_wr_max, bool has_iops_size, int64_t iops_size, Error **errp);
+int qmp_marshal_input_block_set_io_throttle(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_block_stream(const char * device, bool has_base, const char * base, bool has_speed, int64_t speed, bool has_on_error, BlockdevOnError on_error, Error **errp);
+int qmp_marshal_input_block_stream(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_block_job_set_speed(const char * device, int64_t speed, Error **errp);
+int qmp_marshal_input_block_job_set_speed(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_block_job_cancel(const char * device, bool has_force, bool force, Error **errp);
+int qmp_marshal_input_block_job_cancel(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_block_job_pause(const char * device, Error **errp);
+int qmp_marshal_input_block_job_pause(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_block_job_resume(const char * device, Error **errp);
+int qmp_marshal_input_block_job_resume(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_block_job_complete(const char * device, Error **errp);
+int qmp_marshal_input_block_job_complete(Monitor *mon, const QDict *qdict, QObject **ret);
+ObjectTypeInfoList * qmp_qom_list_types(bool has_implements, const char * implements, bool has_abstract, bool abstract, Error **errp);
+int qmp_marshal_input_qom_list_types(Monitor *mon, const QDict *qdict, QObject **ret);
+DevicePropertyInfoList * qmp_device_list_properties(const char * q_typename, Error **errp);
+int qmp_marshal_input_device_list_properties(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_migrate(const char * uri, bool has_blk, bool blk, bool has_inc, bool inc, bool has_detach, bool detach, Error **errp);
+int qmp_marshal_input_migrate(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_xen_save_devices_state(const char * filename, Error **errp);
+int qmp_marshal_input_xen_save_devices_state(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_xen_set_global_dirty_log(bool enable, Error **errp);
+int qmp_marshal_input_xen_set_global_dirty_log(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_device_del(const char * id, Error **errp);
+int qmp_marshal_input_device_del(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_dump_guest_memory(bool paging, const char * protocol, bool has_begin, int64_t begin, bool has_length, int64_t length, Error **errp);
+int qmp_marshal_input_dump_guest_memory(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_netdev_del(const char * id, Error **errp);
+int qmp_marshal_input_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_getfd(const char * fdname, Error **errp);
+int qmp_marshal_input_getfd(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_closefd(const char * fdname, Error **errp);
+int qmp_marshal_input_closefd(Monitor *mon, const QDict *qdict, QObject **ret);
+MachineInfoList * qmp_query_machines(Error **errp);
+int qmp_marshal_input_query_machines(Monitor *mon, const QDict *qdict, QObject **ret);
+CpuDefinitionInfoList * qmp_query_cpu_definitions(Error **errp);
+int qmp_marshal_input_query_cpu_definitions(Monitor *mon, const QDict *qdict, QObject **ret);
+AddfdInfo * qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque, const char * opaque, Error **errp);
+int qmp_marshal_input_add_fd(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp);
+int qmp_marshal_input_remove_fd(Monitor *mon, const QDict *qdict, QObject **ret);
+FdsetInfoList * qmp_query_fdsets(Error **errp);
+int qmp_marshal_input_query_fdsets(Monitor *mon, const QDict *qdict, QObject **ret);
+TargetInfo * qmp_query_target(Error **errp);
+int qmp_marshal_input_query_target(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_send_key(KeyValueList * keys, bool has_hold_time, int64_t hold_time, Error **errp);
+int qmp_marshal_input_send_key(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_screendump(const char * filename, Error **errp);
+int qmp_marshal_input_screendump(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_nbd_server_start(SocketAddress * addr, Error **errp);
+int qmp_marshal_input_nbd_server_start(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_nbd_server_add(const char * device, bool has_writable, bool writable, Error **errp);
+int qmp_marshal_input_nbd_server_add(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_nbd_server_stop(Error **errp);
+int qmp_marshal_input_nbd_server_stop(Monitor *mon, const QDict *qdict, QObject **ret);
+ChardevReturn * qmp_chardev_add(const char * id, ChardevBackend * backend, Error **errp);
+int qmp_marshal_input_chardev_add(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_chardev_remove(const char * id, Error **errp);
+int qmp_marshal_input_chardev_remove(Monitor *mon, const QDict *qdict, QObject **ret);
+TpmModelList * qmp_query_tpm_models(Error **errp);
+int qmp_marshal_input_query_tpm_models(Monitor *mon, const QDict *qdict, QObject **ret);
+TpmTypeList * qmp_query_tpm_types(Error **errp);
+int qmp_marshal_input_query_tpm_types(Monitor *mon, const QDict *qdict, QObject **ret);
+TPMInfoList * qmp_query_tpm(Error **errp);
+int qmp_marshal_input_query_tpm(Monitor *mon, const QDict *qdict, QObject **ret);
+CommandLineOptionInfoList * qmp_query_command_line_options(bool has_option, const char * option, Error **errp);
+int qmp_marshal_input_query_command_line_options(Monitor *mon, const QDict *qdict, QObject **ret);
+RxFilterInfoList * qmp_query_rx_filter(bool has_name, const char * name, Error **errp);
+int qmp_marshal_input_query_rx_filter(Monitor *mon, const QDict *qdict, QObject **ret);
+void qmp_blockdev_add(BlockdevOptions * options, Error **errp);
+int qmp_marshal_input_blockdev_add(Monitor *mon, const QDict *qdict, QObject **ret);
+
+#endif
diff --git a/qapi-auto-generated/qmp-marshal.c b/qapi-auto-generated/qmp-marshal.c
new file mode 100644
index 0000000..8acee1a
--- /dev/null
+++ b/qapi-auto-generated/qmp-marshal.c
@@ -0,0 +1,4235 @@
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QMP->QAPI command dispatch
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "qemu/module.h"
+#include "qapi/qmp/qerror.h"
+#include "qapi/qmp/types.h"
+#include "qapi/qmp/dispatch.h"
+#include "qapi/visitor.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/dealloc-visitor.h"
+#include "qapi-types.h"
+#include "qapi-visit.h"
+
+#include "qmp-commands.h"
+
+int qmp_marshal_input_add_client(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * protocol = NULL;
+    char * fdname = NULL;
+    bool has_skipauth = false;
+    bool skipauth;
+    bool has_tls = false;
+    bool tls;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &protocol, "protocol", errp);
+    visit_type_str(v, &fdname, "fdname", errp);
+    visit_start_optional(v, &has_skipauth, "skipauth", errp);
+    if (has_skipauth) {
+        visit_type_bool(v, &skipauth, "skipauth", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_tls, "tls", errp);
+    if (has_tls) {
+        visit_type_bool(v, &tls, "tls", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_add_client(protocol, fdname, has_skipauth, skipauth, has_tls, tls, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &protocol, "protocol", NULL);
+    visit_type_str(v, &fdname, "fdname", NULL);
+    visit_start_optional(v, &has_skipauth, "skipauth", NULL);
+    if (has_skipauth) {
+        visit_type_bool(v, &skipauth, "skipauth", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_tls, "tls", NULL);
+    if (has_tls) {
+        visit_type_bool(v, &tls, "tls", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_name(NameInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_NameInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_NameInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_name(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    NameInfo * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_name(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_name(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_version(VersionInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_VersionInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_VersionInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_version(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    VersionInfo * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_version(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_version(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_kvm(KvmInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_KvmInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_KvmInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_kvm(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    KvmInfo * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_kvm(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_kvm(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_status(StatusInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_StatusInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_StatusInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_status(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    StatusInfo * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_status(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_status(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_uuid(UuidInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_UuidInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_UuidInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_uuid(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    UuidInfo * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_uuid(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_uuid(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_chardev(ChardevInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_ChardevInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_chardev(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    ChardevInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_chardev(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_chardev(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_ringbuf_write(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    char * data = NULL;
+    bool has_format = false;
+    DataFormat format;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_type_str(v, &data, "data", errp);
+    visit_start_optional(v, &has_format, "format", errp);
+    if (has_format) {
+        visit_type_DataFormat(v, &format, "format", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_ringbuf_write(device, data, has_format, format, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_type_str(v, &data, "data", NULL);
+    visit_start_optional(v, &has_format, "format", NULL);
+    if (has_format) {
+        visit_type_DataFormat(v, &format, "format", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_ringbuf_read(char * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_str(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_ringbuf_read(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    char * retval = NULL;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    int64_t size;
+    bool has_format = false;
+    DataFormat format;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_type_int(v, &size, "size", errp);
+    visit_start_optional(v, &has_format, "format", errp);
+    if (has_format) {
+        visit_type_DataFormat(v, &format, "format", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_ringbuf_read(device, size, has_format, format, errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_ringbuf_read(retval, ret, errp);
+    }
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_type_int(v, &size, "size", NULL);
+    visit_start_optional(v, &has_format, "format", NULL);
+    if (has_format) {
+        visit_type_DataFormat(v, &format, "format", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_commands(CommandInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_CommandInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CommandInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_commands(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    CommandInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_commands(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_commands(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_events(EventInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_EventInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_EventInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_events(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    EventInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_events(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_events(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_migrate(MigrationInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_MigrationInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MigrationInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_migrate(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    MigrationInfo * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_migrate(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_migrate(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_migrate_set_capabilities(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    MigrationCapabilityStatusList * capabilities = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_MigrationCapabilityStatusList(v, &capabilities, "capabilities", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_migrate_set_capabilities(capabilities, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MigrationCapabilityStatusList(v, &capabilities, "capabilities", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_migrate_capabilities(MigrationCapabilityStatusList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_MigrationCapabilityStatusList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MigrationCapabilityStatusList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_migrate_capabilities(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    MigrationCapabilityStatusList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_migrate_capabilities(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_migrate_capabilities(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_mice(MouseInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_MouseInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MouseInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_mice(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    MouseInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_mice(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_mice(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_cpus(CpuInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_CpuInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CpuInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_cpus(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    CpuInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_cpus(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_cpus(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_block(BlockInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_BlockInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_block(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    BlockInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_block(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_block(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_blockstats(BlockStatsList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_BlockStatsList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockStatsList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_blockstats(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    BlockStatsList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_blockstats(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_blockstats(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_vnc(VncInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_VncInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_VncInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_vnc(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    VncInfo * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_vnc(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_vnc(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_spice(SpiceInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_SpiceInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SpiceInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_spice(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    SpiceInfo * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_spice(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_spice(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_balloon(BalloonInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_BalloonInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BalloonInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_balloon(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    BalloonInfo * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_balloon(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_balloon(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_pci(PciInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_PciInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_PciInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_pci(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    PciInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_pci(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_pci(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_block_jobs(BlockJobInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_BlockJobInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockJobInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_block_jobs(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    BlockJobInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_block_jobs(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_block_jobs(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_quit(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_quit(errp);
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_stop(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_stop(errp);
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_system_reset(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_system_reset(errp);
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_system_powerdown(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_system_powerdown(errp);
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_cpu(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    int64_t index;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_int(v, &index, "index", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_cpu(index, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int(v, &index, "index", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_cpu_add(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    int64_t id;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_int(v, &id, "id", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_cpu_add(id, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int(v, &id, "id", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_memsave(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    int64_t val;
+    int64_t size;
+    char * filename = NULL;
+    bool has_cpu_index = false;
+    int64_t cpu_index;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_int(v, &val, "val", errp);
+    visit_type_int(v, &size, "size", errp);
+    visit_type_str(v, &filename, "filename", errp);
+    visit_start_optional(v, &has_cpu_index, "cpu-index", errp);
+    if (has_cpu_index) {
+        visit_type_int(v, &cpu_index, "cpu-index", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_memsave(val, size, filename, has_cpu_index, cpu_index, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int(v, &val, "val", NULL);
+    visit_type_int(v, &size, "size", NULL);
+    visit_type_str(v, &filename, "filename", NULL);
+    visit_start_optional(v, &has_cpu_index, "cpu-index", NULL);
+    if (has_cpu_index) {
+        visit_type_int(v, &cpu_index, "cpu-index", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_pmemsave(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    int64_t val;
+    int64_t size;
+    char * filename = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_int(v, &val, "val", errp);
+    visit_type_int(v, &size, "size", errp);
+    visit_type_str(v, &filename, "filename", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_pmemsave(val, size, filename, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int(v, &val, "val", NULL);
+    visit_type_int(v, &size, "size", NULL);
+    visit_type_str(v, &filename, "filename", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_cont(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_cont(errp);
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_system_wakeup(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_system_wakeup(errp);
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_inject_nmi(errp);
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_set_link(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * name = NULL;
+    bool up;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &name, "name", errp);
+    visit_type_bool(v, &up, "up", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_set_link(name, up, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &name, "name", NULL);
+    visit_type_bool(v, &up, "up", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_block_passwd(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    char * password = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_type_str(v, &password, "password", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_block_passwd(device, password, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_type_str(v, &password, "password", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_balloon(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    int64_t value;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_int(v, &value, "value", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_balloon(value, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int(v, &value, "value", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_block_resize(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    int64_t size;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_type_int(v, &size, "size", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_block_resize(device, size, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_type_int(v, &size, "size", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_transaction(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    TransactionActionList * actions = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_TransactionActionList(v, &actions, "actions", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_transaction(actions, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TransactionActionList(v, &actions, "actions", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_blockdev_snapshot_sync(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    char * snapshot_file = NULL;
+    bool has_format = false;
+    char * format = NULL;
+    bool has_mode = false;
+    NewImageMode mode;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_type_str(v, &snapshot_file, "snapshot-file", errp);
+    visit_start_optional(v, &has_format, "format", errp);
+    if (has_format) {
+        visit_type_str(v, &format, "format", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_mode, "mode", errp);
+    if (has_mode) {
+        visit_type_NewImageMode(v, &mode, "mode", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_blockdev_snapshot_sync(device, snapshot_file, has_format, format, has_mode, mode, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_type_str(v, &snapshot_file, "snapshot-file", NULL);
+    visit_start_optional(v, &has_format, "format", NULL);
+    if (has_format) {
+        visit_type_str(v, &format, "format", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_mode, "mode", NULL);
+    if (has_mode) {
+        visit_type_NewImageMode(v, &mode, "mode", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_blockdev_snapshot_internal_sync(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    char * name = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_type_str(v, &name, "name", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_blockdev_snapshot_internal_sync(device, name, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_type_str(v, &name, "name", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_blockdev_snapshot_delete_internal_sync(SnapshotInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_SnapshotInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SnapshotInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_blockdev_snapshot_delete_internal_sync(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    SnapshotInfo * retval = NULL;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    bool has_id = false;
+    char * id = NULL;
+    bool has_name = false;
+    char * name = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_start_optional(v, &has_id, "id", errp);
+    if (has_id) {
+        visit_type_str(v, &id, "id", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_name, "name", errp);
+    if (has_name) {
+        visit_type_str(v, &name, "name", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_blockdev_snapshot_delete_internal_sync(device, has_id, id, has_name, name, errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_blockdev_snapshot_delete_internal_sync(retval, ret, errp);
+    }
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_start_optional(v, &has_id, "id", NULL);
+    if (has_id) {
+        visit_type_str(v, &id, "id", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_name, "name", NULL);
+    if (has_name) {
+        visit_type_str(v, &name, "name", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_human_monitor_command(char * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_str(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_human_monitor_command(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    char * retval = NULL;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * command_line = NULL;
+    bool has_cpu_index = false;
+    int64_t cpu_index;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &command_line, "command-line", errp);
+    visit_start_optional(v, &has_cpu_index, "cpu-index", errp);
+    if (has_cpu_index) {
+        visit_type_int(v, &cpu_index, "cpu-index", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_human_monitor_command(command_line, has_cpu_index, cpu_index, errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_human_monitor_command(retval, ret, errp);
+    }
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &command_line, "command-line", NULL);
+    visit_start_optional(v, &has_cpu_index, "cpu-index", NULL);
+    if (has_cpu_index) {
+        visit_type_int(v, &cpu_index, "cpu-index", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_block_commit(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    bool has_base = false;
+    char * base = NULL;
+    char * top = NULL;
+    bool has_speed = false;
+    int64_t speed;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_start_optional(v, &has_base, "base", errp);
+    if (has_base) {
+        visit_type_str(v, &base, "base", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_type_str(v, &top, "top", errp);
+    visit_start_optional(v, &has_speed, "speed", errp);
+    if (has_speed) {
+        visit_type_int(v, &speed, "speed", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_block_commit(device, has_base, base, top, has_speed, speed, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_start_optional(v, &has_base, "base", NULL);
+    if (has_base) {
+        visit_type_str(v, &base, "base", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_type_str(v, &top, "top", NULL);
+    visit_start_optional(v, &has_speed, "speed", NULL);
+    if (has_speed) {
+        visit_type_int(v, &speed, "speed", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_drive_backup(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    char * target = NULL;
+    bool has_format = false;
+    char * format = NULL;
+    MirrorSyncMode sync;
+    bool has_mode = false;
+    NewImageMode mode;
+    bool has_speed = false;
+    int64_t speed;
+    bool has_on_source_error = false;
+    BlockdevOnError on_source_error;
+    bool has_on_target_error = false;
+    BlockdevOnError on_target_error;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_type_str(v, &target, "target", errp);
+    visit_start_optional(v, &has_format, "format", errp);
+    if (has_format) {
+        visit_type_str(v, &format, "format", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_type_MirrorSyncMode(v, &sync, "sync", errp);
+    visit_start_optional(v, &has_mode, "mode", errp);
+    if (has_mode) {
+        visit_type_NewImageMode(v, &mode, "mode", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_speed, "speed", errp);
+    if (has_speed) {
+        visit_type_int(v, &speed, "speed", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_on_source_error, "on-source-error", errp);
+    if (has_on_source_error) {
+        visit_type_BlockdevOnError(v, &on_source_error, "on-source-error", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_on_target_error, "on-target-error", errp);
+    if (has_on_target_error) {
+        visit_type_BlockdevOnError(v, &on_target_error, "on-target-error", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_drive_backup(device, target, has_format, format, sync, has_mode, mode, has_speed, speed, has_on_source_error, on_source_error, has_on_target_error, on_target_error, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_type_str(v, &target, "target", NULL);
+    visit_start_optional(v, &has_format, "format", NULL);
+    if (has_format) {
+        visit_type_str(v, &format, "format", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_type_MirrorSyncMode(v, &sync, "sync", NULL);
+    visit_start_optional(v, &has_mode, "mode", NULL);
+    if (has_mode) {
+        visit_type_NewImageMode(v, &mode, "mode", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_speed, "speed", NULL);
+    if (has_speed) {
+        visit_type_int(v, &speed, "speed", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_on_source_error, "on-source-error", NULL);
+    if (has_on_source_error) {
+        visit_type_BlockdevOnError(v, &on_source_error, "on-source-error", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_on_target_error, "on-target-error", NULL);
+    if (has_on_target_error) {
+        visit_type_BlockdevOnError(v, &on_target_error, "on-target-error", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_drive_mirror(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    char * target = NULL;
+    bool has_format = false;
+    char * format = NULL;
+    MirrorSyncMode sync;
+    bool has_mode = false;
+    NewImageMode mode;
+    bool has_speed = false;
+    int64_t speed;
+    bool has_granularity = false;
+    uint32_t granularity;
+    bool has_buf_size = false;
+    int64_t buf_size;
+    bool has_on_source_error = false;
+    BlockdevOnError on_source_error;
+    bool has_on_target_error = false;
+    BlockdevOnError on_target_error;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_type_str(v, &target, "target", errp);
+    visit_start_optional(v, &has_format, "format", errp);
+    if (has_format) {
+        visit_type_str(v, &format, "format", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_type_MirrorSyncMode(v, &sync, "sync", errp);
+    visit_start_optional(v, &has_mode, "mode", errp);
+    if (has_mode) {
+        visit_type_NewImageMode(v, &mode, "mode", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_speed, "speed", errp);
+    if (has_speed) {
+        visit_type_int(v, &speed, "speed", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_granularity, "granularity", errp);
+    if (has_granularity) {
+        visit_type_uint32(v, &granularity, "granularity", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_buf_size, "buf-size", errp);
+    if (has_buf_size) {
+        visit_type_int(v, &buf_size, "buf-size", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_on_source_error, "on-source-error", errp);
+    if (has_on_source_error) {
+        visit_type_BlockdevOnError(v, &on_source_error, "on-source-error", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_on_target_error, "on-target-error", errp);
+    if (has_on_target_error) {
+        visit_type_BlockdevOnError(v, &on_target_error, "on-target-error", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_drive_mirror(device, target, has_format, format, sync, has_mode, mode, has_speed, speed, has_granularity, granularity, has_buf_size, buf_size, has_on_source_error, on_source_error, has_on_target_error, on_target_error, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_type_str(v, &target, "target", NULL);
+    visit_start_optional(v, &has_format, "format", NULL);
+    if (has_format) {
+        visit_type_str(v, &format, "format", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_type_MirrorSyncMode(v, &sync, "sync", NULL);
+    visit_start_optional(v, &has_mode, "mode", NULL);
+    if (has_mode) {
+        visit_type_NewImageMode(v, &mode, "mode", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_speed, "speed", NULL);
+    if (has_speed) {
+        visit_type_int(v, &speed, "speed", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_granularity, "granularity", NULL);
+    if (has_granularity) {
+        visit_type_uint32(v, &granularity, "granularity", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_buf_size, "buf-size", NULL);
+    if (has_buf_size) {
+        visit_type_int(v, &buf_size, "buf-size", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_on_source_error, "on-source-error", NULL);
+    if (has_on_source_error) {
+        visit_type_BlockdevOnError(v, &on_source_error, "on-source-error", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_on_target_error, "on-target-error", NULL);
+    if (has_on_target_error) {
+        visit_type_BlockdevOnError(v, &on_target_error, "on-target-error", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_migrate_cancel(errp);
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_migrate_set_downtime(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    double value;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_number(v, &value, "value", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_migrate_set_downtime(value, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_number(v, &value, "value", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    int64_t value;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_int(v, &value, "value", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_migrate_set_speed(value, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int(v, &value, "value", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_migrate_set_cache_size(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    int64_t value;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_int(v, &value, "value", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_migrate_set_cache_size(value, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int(v, &value, "value", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_migrate_cache_size(int64_t ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_int(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_migrate_cache_size(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    int64_t retval;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_migrate_cache_size(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_migrate_cache_size(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_qom_list(ObjectPropertyInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_ObjectPropertyInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ObjectPropertyInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_qom_list(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    ObjectPropertyInfoList * retval = NULL;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * path = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &path, "path", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_qom_list(path, errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_qom_list(retval, ret, errp);
+    }
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &path, "path", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_set_password(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * protocol = NULL;
+    char * password = NULL;
+    bool has_connected = false;
+    char * connected = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &protocol, "protocol", errp);
+    visit_type_str(v, &password, "password", errp);
+    visit_start_optional(v, &has_connected, "connected", errp);
+    if (has_connected) {
+        visit_type_str(v, &connected, "connected", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_set_password(protocol, password, has_connected, connected, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &protocol, "protocol", NULL);
+    visit_type_str(v, &password, "password", NULL);
+    visit_start_optional(v, &has_connected, "connected", NULL);
+    if (has_connected) {
+        visit_type_str(v, &connected, "connected", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_expire_password(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * protocol = NULL;
+    char * time = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &protocol, "protocol", errp);
+    visit_type_str(v, &time, "time", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_expire_password(protocol, time, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &protocol, "protocol", NULL);
+    visit_type_str(v, &time, "time", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_eject(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    bool has_force = false;
+    bool force;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_start_optional(v, &has_force, "force", errp);
+    if (has_force) {
+        visit_type_bool(v, &force, "force", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_eject(device, has_force, force, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_start_optional(v, &has_force, "force", NULL);
+    if (has_force) {
+        visit_type_bool(v, &force, "force", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_change_vnc_password(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * password = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &password, "password", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_change_vnc_password(password, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &password, "password", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_change(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    char * target = NULL;
+    bool has_arg = false;
+    char * arg = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_type_str(v, &target, "target", errp);
+    visit_start_optional(v, &has_arg, "arg", errp);
+    if (has_arg) {
+        visit_type_str(v, &arg, "arg", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_change(device, target, has_arg, arg, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_type_str(v, &target, "target", NULL);
+    visit_start_optional(v, &has_arg, "arg", NULL);
+    if (has_arg) {
+        visit_type_str(v, &arg, "arg", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_block_set_io_throttle(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    int64_t bps;
+    int64_t bps_rd;
+    int64_t bps_wr;
+    int64_t iops;
+    int64_t iops_rd;
+    int64_t iops_wr;
+    bool has_bps_max = false;
+    int64_t bps_max;
+    bool has_bps_rd_max = false;
+    int64_t bps_rd_max;
+    bool has_bps_wr_max = false;
+    int64_t bps_wr_max;
+    bool has_iops_max = false;
+    int64_t iops_max;
+    bool has_iops_rd_max = false;
+    int64_t iops_rd_max;
+    bool has_iops_wr_max = false;
+    int64_t iops_wr_max;
+    bool has_iops_size = false;
+    int64_t iops_size;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_type_int(v, &bps, "bps", errp);
+    visit_type_int(v, &bps_rd, "bps_rd", errp);
+    visit_type_int(v, &bps_wr, "bps_wr", errp);
+    visit_type_int(v, &iops, "iops", errp);
+    visit_type_int(v, &iops_rd, "iops_rd", errp);
+    visit_type_int(v, &iops_wr, "iops_wr", errp);
+    visit_start_optional(v, &has_bps_max, "bps_max", errp);
+    if (has_bps_max) {
+        visit_type_int(v, &bps_max, "bps_max", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_bps_rd_max, "bps_rd_max", errp);
+    if (has_bps_rd_max) {
+        visit_type_int(v, &bps_rd_max, "bps_rd_max", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_bps_wr_max, "bps_wr_max", errp);
+    if (has_bps_wr_max) {
+        visit_type_int(v, &bps_wr_max, "bps_wr_max", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_iops_max, "iops_max", errp);
+    if (has_iops_max) {
+        visit_type_int(v, &iops_max, "iops_max", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_iops_rd_max, "iops_rd_max", errp);
+    if (has_iops_rd_max) {
+        visit_type_int(v, &iops_rd_max, "iops_rd_max", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_iops_wr_max, "iops_wr_max", errp);
+    if (has_iops_wr_max) {
+        visit_type_int(v, &iops_wr_max, "iops_wr_max", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_iops_size, "iops_size", errp);
+    if (has_iops_size) {
+        visit_type_int(v, &iops_size, "iops_size", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_block_set_io_throttle(device, bps, bps_rd, bps_wr, iops, iops_rd, iops_wr, has_bps_max, bps_max, has_bps_rd_max, bps_rd_max, has_bps_wr_max, bps_wr_max, has_iops_max, iops_max, has_iops_rd_max, iops_rd_max, has_iops_wr_max, iops_wr_max, has_iops_size, iops_size, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_type_int(v, &bps, "bps", NULL);
+    visit_type_int(v, &bps_rd, "bps_rd", NULL);
+    visit_type_int(v, &bps_wr, "bps_wr", NULL);
+    visit_type_int(v, &iops, "iops", NULL);
+    visit_type_int(v, &iops_rd, "iops_rd", NULL);
+    visit_type_int(v, &iops_wr, "iops_wr", NULL);
+    visit_start_optional(v, &has_bps_max, "bps_max", NULL);
+    if (has_bps_max) {
+        visit_type_int(v, &bps_max, "bps_max", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_bps_rd_max, "bps_rd_max", NULL);
+    if (has_bps_rd_max) {
+        visit_type_int(v, &bps_rd_max, "bps_rd_max", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_bps_wr_max, "bps_wr_max", NULL);
+    if (has_bps_wr_max) {
+        visit_type_int(v, &bps_wr_max, "bps_wr_max", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_iops_max, "iops_max", NULL);
+    if (has_iops_max) {
+        visit_type_int(v, &iops_max, "iops_max", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_iops_rd_max, "iops_rd_max", NULL);
+    if (has_iops_rd_max) {
+        visit_type_int(v, &iops_rd_max, "iops_rd_max", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_iops_wr_max, "iops_wr_max", NULL);
+    if (has_iops_wr_max) {
+        visit_type_int(v, &iops_wr_max, "iops_wr_max", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_iops_size, "iops_size", NULL);
+    if (has_iops_size) {
+        visit_type_int(v, &iops_size, "iops_size", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_block_stream(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    bool has_base = false;
+    char * base = NULL;
+    bool has_speed = false;
+    int64_t speed;
+    bool has_on_error = false;
+    BlockdevOnError on_error;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_start_optional(v, &has_base, "base", errp);
+    if (has_base) {
+        visit_type_str(v, &base, "base", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_speed, "speed", errp);
+    if (has_speed) {
+        visit_type_int(v, &speed, "speed", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_on_error, "on-error", errp);
+    if (has_on_error) {
+        visit_type_BlockdevOnError(v, &on_error, "on-error", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_block_stream(device, has_base, base, has_speed, speed, has_on_error, on_error, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_start_optional(v, &has_base, "base", NULL);
+    if (has_base) {
+        visit_type_str(v, &base, "base", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_speed, "speed", NULL);
+    if (has_speed) {
+        visit_type_int(v, &speed, "speed", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_on_error, "on-error", NULL);
+    if (has_on_error) {
+        visit_type_BlockdevOnError(v, &on_error, "on-error", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_block_job_set_speed(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    int64_t speed;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_type_int(v, &speed, "speed", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_block_job_set_speed(device, speed, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_type_int(v, &speed, "speed", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_block_job_cancel(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    bool has_force = false;
+    bool force;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_start_optional(v, &has_force, "force", errp);
+    if (has_force) {
+        visit_type_bool(v, &force, "force", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_block_job_cancel(device, has_force, force, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_start_optional(v, &has_force, "force", NULL);
+    if (has_force) {
+        visit_type_bool(v, &force, "force", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_block_job_pause(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_block_job_pause(device, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_block_job_resume(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_block_job_resume(device, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_block_job_complete(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_block_job_complete(device, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_qom_list_types(ObjectTypeInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_ObjectTypeInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ObjectTypeInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_qom_list_types(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    ObjectTypeInfoList * retval = NULL;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    bool has_implements = false;
+    char * implements = NULL;
+    bool has_abstract = false;
+    bool abstract;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_start_optional(v, &has_implements, "implements", errp);
+    if (has_implements) {
+        visit_type_str(v, &implements, "implements", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_abstract, "abstract", errp);
+    if (has_abstract) {
+        visit_type_bool(v, &abstract, "abstract", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_qom_list_types(has_implements, implements, has_abstract, abstract, errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_qom_list_types(retval, ret, errp);
+    }
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_start_optional(v, &has_implements, "implements", NULL);
+    if (has_implements) {
+        visit_type_str(v, &implements, "implements", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_abstract, "abstract", NULL);
+    if (has_abstract) {
+        visit_type_bool(v, &abstract, "abstract", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_device_list_properties(DevicePropertyInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_DevicePropertyInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_DevicePropertyInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_device_list_properties(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    DevicePropertyInfoList * retval = NULL;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * q_typename = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &q_typename, "typename", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_device_list_properties(q_typename, errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_device_list_properties(retval, ret, errp);
+    }
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &q_typename, "typename", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_migrate(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * uri = NULL;
+    bool has_blk = false;
+    bool blk;
+    bool has_inc = false;
+    bool inc;
+    bool has_detach = false;
+    bool detach;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &uri, "uri", errp);
+    visit_start_optional(v, &has_blk, "blk", errp);
+    if (has_blk) {
+        visit_type_bool(v, &blk, "blk", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_inc, "inc", errp);
+    if (has_inc) {
+        visit_type_bool(v, &inc, "inc", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_detach, "detach", errp);
+    if (has_detach) {
+        visit_type_bool(v, &detach, "detach", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_migrate(uri, has_blk, blk, has_inc, inc, has_detach, detach, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &uri, "uri", NULL);
+    visit_start_optional(v, &has_blk, "blk", NULL);
+    if (has_blk) {
+        visit_type_bool(v, &blk, "blk", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_inc, "inc", NULL);
+    if (has_inc) {
+        visit_type_bool(v, &inc, "inc", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_detach, "detach", NULL);
+    if (has_detach) {
+        visit_type_bool(v, &detach, "detach", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_xen_save_devices_state(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * filename = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &filename, "filename", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_xen_save_devices_state(filename, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &filename, "filename", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_xen_set_global_dirty_log(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    bool enable;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_bool(v, &enable, "enable", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_xen_set_global_dirty_log(enable, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_bool(v, &enable, "enable", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_device_del(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * id = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &id, "id", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_device_del(id, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &id, "id", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_dump_guest_memory(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    bool paging;
+    char * protocol = NULL;
+    bool has_begin = false;
+    int64_t begin;
+    bool has_length = false;
+    int64_t length;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_bool(v, &paging, "paging", errp);
+    visit_type_str(v, &protocol, "protocol", errp);
+    visit_start_optional(v, &has_begin, "begin", errp);
+    if (has_begin) {
+        visit_type_int(v, &begin, "begin", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_length, "length", errp);
+    if (has_length) {
+        visit_type_int(v, &length, "length", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_dump_guest_memory(paging, protocol, has_begin, begin, has_length, length, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_bool(v, &paging, "paging", NULL);
+    visit_type_str(v, &protocol, "protocol", NULL);
+    visit_start_optional(v, &has_begin, "begin", NULL);
+    if (has_begin) {
+        visit_type_int(v, &begin, "begin", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_length, "length", NULL);
+    if (has_length) {
+        visit_type_int(v, &length, "length", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * id = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &id, "id", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_netdev_del(id, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &id, "id", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_getfd(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * fdname = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &fdname, "fdname", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_getfd(fdname, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &fdname, "fdname", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_closefd(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * fdname = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &fdname, "fdname", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_closefd(fdname, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &fdname, "fdname", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_machines(MachineInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_MachineInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_MachineInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_machines(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    MachineInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_machines(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_machines(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_cpu_definitions(CpuDefinitionInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_CpuDefinitionInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CpuDefinitionInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_cpu_definitions(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    CpuDefinitionInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_cpu_definitions(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_cpu_definitions(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_add_fd(AddfdInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_AddfdInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_AddfdInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_add_fd(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    AddfdInfo * retval = NULL;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    bool has_fdset_id = false;
+    int64_t fdset_id;
+    bool has_opaque = false;
+    char * opaque = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_start_optional(v, &has_fdset_id, "fdset-id", errp);
+    if (has_fdset_id) {
+        visit_type_int(v, &fdset_id, "fdset-id", errp);
+    }
+    visit_end_optional(v, errp);
+    visit_start_optional(v, &has_opaque, "opaque", errp);
+    if (has_opaque) {
+        visit_type_str(v, &opaque, "opaque", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_add_fd(has_fdset_id, fdset_id, has_opaque, opaque, errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_add_fd(retval, ret, errp);
+    }
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_start_optional(v, &has_fdset_id, "fdset-id", NULL);
+    if (has_fdset_id) {
+        visit_type_int(v, &fdset_id, "fdset-id", NULL);
+    }
+    visit_end_optional(v, NULL);
+    visit_start_optional(v, &has_opaque, "opaque", NULL);
+    if (has_opaque) {
+        visit_type_str(v, &opaque, "opaque", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_remove_fd(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    int64_t fdset_id;
+    bool has_fd = false;
+    int64_t fd;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_int(v, &fdset_id, "fdset-id", errp);
+    visit_start_optional(v, &has_fd, "fd", errp);
+    if (has_fd) {
+        visit_type_int(v, &fd, "fd", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_remove_fd(fdset_id, has_fd, fd, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_int(v, &fdset_id, "fdset-id", NULL);
+    visit_start_optional(v, &has_fd, "fd", NULL);
+    if (has_fd) {
+        visit_type_int(v, &fd, "fd", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_fdsets(FdsetInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_FdsetInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_FdsetInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_fdsets(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    FdsetInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_fdsets(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_fdsets(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_target(TargetInfo * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_TargetInfo(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TargetInfo(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_target(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    TargetInfo * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_target(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_target(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_send_key(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    KeyValueList * keys = NULL;
+    bool has_hold_time = false;
+    int64_t hold_time;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_KeyValueList(v, &keys, "keys", errp);
+    visit_start_optional(v, &has_hold_time, "hold-time", errp);
+    if (has_hold_time) {
+        visit_type_int(v, &hold_time, "hold-time", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_send_key(keys, has_hold_time, hold_time, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_KeyValueList(v, &keys, "keys", NULL);
+    visit_start_optional(v, &has_hold_time, "hold-time", NULL);
+    if (has_hold_time) {
+        visit_type_int(v, &hold_time, "hold-time", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_screendump(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * filename = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &filename, "filename", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_screendump(filename, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &filename, "filename", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_nbd_server_start(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    SocketAddress * addr = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_SocketAddress(v, &addr, "addr", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_nbd_server_start(addr, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_SocketAddress(v, &addr, "addr", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_nbd_server_add(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * device = NULL;
+    bool has_writable = false;
+    bool writable;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &device, "device", errp);
+    visit_start_optional(v, &has_writable, "writable", errp);
+    if (has_writable) {
+        visit_type_bool(v, &writable, "writable", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_nbd_server_add(device, has_writable, writable, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &device, "device", NULL);
+    visit_start_optional(v, &has_writable, "writable", NULL);
+    if (has_writable) {
+        visit_type_bool(v, &writable, "writable", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_nbd_server_stop(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_nbd_server_stop(errp);
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_chardev_add(ChardevReturn * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_ChardevReturn(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_ChardevReturn(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_chardev_add(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    ChardevReturn * retval = NULL;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * id = NULL;
+    ChardevBackend * backend = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &id, "id", errp);
+    visit_type_ChardevBackend(v, &backend, "backend", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_chardev_add(id, backend, errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_chardev_add(retval, ret, errp);
+    }
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &id, "id", NULL);
+    visit_type_ChardevBackend(v, &backend, "backend", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_chardev_remove(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    char * id = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_str(v, &id, "id", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_chardev_remove(id, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_str(v, &id, "id", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_tpm_models(TpmModelList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_TpmModelList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TpmModelList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_tpm_models(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    TpmModelList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_tpm_models(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_tpm_models(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_tpm_types(TpmTypeList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_TpmTypeList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TpmTypeList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_tpm_types(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    TpmTypeList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_tpm_types(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_tpm_types(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_tpm(TPMInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_TPMInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_TPMInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_tpm(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    TPMInfoList * retval = NULL;
+    (void)args;
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_tpm(errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_tpm(retval, ret, errp);
+    }
+
+out:
+
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_command_line_options(CommandLineOptionInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_CommandLineOptionInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_CommandLineOptionInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_command_line_options(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    CommandLineOptionInfoList * retval = NULL;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    bool has_option = false;
+    char * option = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_start_optional(v, &has_option, "option", errp);
+    if (has_option) {
+        visit_type_str(v, &option, "option", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_command_line_options(has_option, option, errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_command_line_options(retval, ret, errp);
+    }
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_start_optional(v, &has_option, "option", NULL);
+    if (has_option) {
+        visit_type_str(v, &option, "option", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+static void qmp_marshal_output_query_rx_filter(RxFilterInfoList * ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    visit_type_RxFilterInfoList(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_RxFilterInfoList(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+
+int qmp_marshal_input_query_rx_filter(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    RxFilterInfoList * retval = NULL;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    bool has_name = false;
+    char * name = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_start_optional(v, &has_name, "name", errp);
+    if (has_name) {
+        visit_type_str(v, &name, "name", errp);
+    }
+    visit_end_optional(v, errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    retval = qmp_query_rx_filter(has_name, name, errp);
+    if (!error_is_set(errp)) {
+        qmp_marshal_output_query_rx_filter(retval, ret, errp);
+    }
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_start_optional(v, &has_name, "name", NULL);
+    if (has_name) {
+        visit_type_str(v, &name, "name", NULL);
+    }
+    visit_end_optional(v, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+int qmp_marshal_input_blockdev_add(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+    QmpInputVisitor *mi;
+    QapiDeallocVisitor *md;
+    Visitor *v;
+    BlockdevOptions * options = NULL;
+
+    mi = qmp_input_visitor_new_strict(QOBJECT(args));
+    v = qmp_input_get_visitor(mi);
+    visit_type_BlockdevOptions(v, &options, "options", errp);
+    qmp_input_visitor_cleanup(mi);
+
+    if (error_is_set(errp)) {
+        goto out;
+    }
+    qmp_blockdev_add(options, errp);
+
+out:
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_BlockdevOptions(v, &options, "options", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
diff --git a/qapi-schema.json b/qapi-schema.json
new file mode 100644
index 0000000..d6f8615
--- /dev/null
+++ b/qapi-schema.json
@@ -0,0 +1,4237 @@
+# -*- Mode: Python -*-
+#
+# QAPI Schema
+
+##
+# @ErrorClass
+#
+# QEMU error classes
+#
+# @GenericError: this is used for errors that don't require a specific error
+#                class. This should be the default case for most errors
+#
+# @CommandNotFound: the requested command has not been found
+#
+# @DeviceEncrypted: the requested operation can't be fulfilled because the
+#                   selected device is encrypted
+#
+# @DeviceNotActive: a device has failed to be become active
+#
+# @DeviceNotFound: the requested device has not been found
+#
+# @KVMMissingCap: the requested operation can't be fulfilled because a
+#                 required KVM capability is missing
+#
+# Since: 1.2
+##
+{ 'enum': 'ErrorClass',
+  'data': [ 'GenericError', 'CommandNotFound', 'DeviceEncrypted',
+            'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] }
+
+##
+# @add_client
+#
+# Allow client connections for VNC, Spice and socket based
+# character devices to be passed in to QEMU via SCM_RIGHTS.
+#
+# @protocol: protocol name. Valid names are "vnc", "spice" or the
+#            name of a character device (eg. from -chardev id=XXXX)
+#
+# @fdname: file descriptor name previously passed via 'getfd' command
+#
+# @skipauth: #optional whether to skip authentication. Only applies
+#            to "vnc" and "spice" protocols
+#
+# @tls: #optional whether to perform TLS. Only applies to the "spice"
+#       protocol
+#
+# Returns: nothing on success.
+#
+# Since: 0.14.0
+##
+{ 'command': 'add_client',
+  'data': { 'protocol': 'str', 'fdname': 'str', '*skipauth': 'bool',
+            '*tls': 'bool' } }
+
+##
+# @NameInfo:
+#
+# Guest name information.
+#
+# @name: #optional The name of the guest
+#
+# Since 0.14.0
+##
+{ 'type': 'NameInfo', 'data': {'*name': 'str'} }
+
+##
+# @query-name:
+#
+# Return the name information of a guest.
+#
+# Returns: @NameInfo of the guest
+#
+# Since 0.14.0
+##
+{ 'command': 'query-name', 'returns': 'NameInfo' }
+
+##
+# @VersionInfo:
+#
+# A description of QEMU's version.
+#
+# @qemu.major:  The major version of QEMU
+#
+# @qemu.minor:  The minor version of QEMU
+#
+# @qemu.micro:  The micro version of QEMU.  By current convention, a micro
+#               version of 50 signifies a development branch.  A micro version
+#               greater than or equal to 90 signifies a release candidate for
+#               the next minor version.  A micro version of less than 50
+#               signifies a stable release.
+#
+# @package:     QEMU will always set this field to an empty string.  Downstream
+#               versions of QEMU should set this to a non-empty string.  The
+#               exact format depends on the downstream however it highly
+#               recommended that a unique name is used.
+#
+# Since: 0.14.0
+##
+{ 'type': 'VersionInfo',
+  'data': {'qemu': {'major': 'int', 'minor': 'int', 'micro': 'int'},
+           'package': 'str'} }
+
+##
+# @query-version:
+#
+# Returns the current version of QEMU.
+#
+# Returns:  A @VersionInfo object describing the current version of QEMU.
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-version', 'returns': 'VersionInfo' }
+
+##
+# @KvmInfo:
+#
+# Information about support for KVM acceleration
+#
+# @enabled: true if KVM acceleration is active
+#
+# @present: true if KVM acceleration is built into this executable
+#
+# Since: 0.14.0
+##
+{ 'type': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool'} }
+
+##
+# @query-kvm:
+#
+# Returns information about KVM acceleration
+#
+# Returns: @KvmInfo
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-kvm', 'returns': 'KvmInfo' }
+
+##
+# @RunState
+#
+# An enumeration of VM run states.
+#
+# @debug: QEMU is running on a debugger
+#
+# @finish-migrate: guest is paused to finish the migration process
+#
+# @inmigrate: guest is paused waiting for an incoming migration.  Note
+# that this state does not tell whether the machine will start at the
+# end of the migration.  This depends on the command-line -S option and
+# any invocation of 'stop' or 'cont' that has happened since QEMU was
+# started.
+#
+# @internal-error: An internal error that prevents further guest execution
+# has occurred
+#
+# @io-error: the last IOP has failed and the device is configured to pause
+# on I/O errors
+#
+# @paused: guest has been paused via the 'stop' command
+#
+# @postmigrate: guest is paused following a successful 'migrate'
+#
+# @prelaunch: QEMU was started with -S and guest has not started
+#
+# @restore-vm: guest is paused to restore VM state
+#
+# @running: guest is actively running
+#
+# @save-vm: guest is paused to save the VM state
+#
+# @shutdown: guest is shut down (and -no-shutdown is in use)
+#
+# @suspended: guest is suspended (ACPI S3)
+#
+# @watchdog: the watchdog action is configured to pause and has been triggered
+#
+# @guest-panicked: guest has been panicked as a result of guest OS panic
+##
+{ 'enum': 'RunState',
+  'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
+            'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
+            'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
+            'guest-panicked' ] }
+
+##
+# @SnapshotInfo
+#
+# @id: unique snapshot id
+#
+# @name: user chosen name
+#
+# @vm-state-size: size of the VM state
+#
+# @date-sec: UTC date of the snapshot in seconds
+#
+# @date-nsec: fractional part in nano seconds to be used with date-sec
+#
+# @vm-clock-sec: VM clock relative to boot in seconds
+#
+# @vm-clock-nsec: fractional part in nano seconds to be used with vm-clock-sec
+#
+# Since: 1.3
+#
+##
+
+{ 'type': 'SnapshotInfo',
+  'data': { 'id': 'str', 'name': 'str', 'vm-state-size': 'int',
+            'date-sec': 'int', 'date-nsec': 'int',
+            'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } }
+
+##
+# @ImageInfoSpecificQCow2:
+#
+# @compat: compatibility level
+#
+# @lazy-refcounts: #optional on or off; only valid for compat >= 1.1
+#
+# Since: 1.7
+##
+{ 'type': 'ImageInfoSpecificQCow2',
+  'data': {
+      'compat': 'str',
+      '*lazy-refcounts': 'bool'
+  } }
+
+##
+# @ImageInfoSpecificVmdk:
+#
+# @create-type: The create type of VMDK image
+#
+# @cid: Content id of image
+#
+# @parent-cid: Parent VMDK image's cid
+#
+# @extents: List of extent files
+#
+# Since: 1.7
+##
+{ 'type': 'ImageInfoSpecificVmdk',
+  'data': {
+      'create-type': 'str',
+      'cid': 'int',
+      'parent-cid': 'int',
+      'extents': ['ImageInfo']
+  } }
+
+##
+# @ImageInfoSpecific:
+#
+# A discriminated record of image format specific information structures.
+#
+# Since: 1.7
+##
+
+{ 'union': 'ImageInfoSpecific',
+  'data': {
+      'qcow2': 'ImageInfoSpecificQCow2',
+      'vmdk': 'ImageInfoSpecificVmdk'
+  } }
+
+##
+# @ImageInfo:
+#
+# Information about a QEMU image file
+#
+# @filename: name of the image file
+#
+# @format: format of the image file
+#
+# @virtual-size: maximum capacity in bytes of the image
+#
+# @actual-size: #optional actual size on disk in bytes of the image
+#
+# @dirty-flag: #optional true if image is not cleanly closed
+#
+# @cluster-size: #optional size of a cluster in bytes
+#
+# @encrypted: #optional true if the image is encrypted
+#
+# @compressed: #optional true if the image is compressed (Since 1.7)
+#
+# @backing-filename: #optional name of the backing file
+#
+# @full-backing-filename: #optional full path of the backing file
+#
+# @backing-filename-format: #optional the format of the backing file
+#
+# @snapshots: #optional list of VM snapshots
+#
+# @backing-image: #optional info of the backing image (since 1.6)
+#
+# @format-specific: #optional structure supplying additional format-specific
+# information (since 1.7)
+#
+# Since: 1.3
+#
+##
+
+{ 'type': 'ImageInfo',
+  'data': {'filename': 'str', 'format': 'str', '*dirty-flag': 'bool',
+           '*actual-size': 'int', 'virtual-size': 'int',
+           '*cluster-size': 'int', '*encrypted': 'bool', '*compressed': 'bool',
+           '*backing-filename': 'str', '*full-backing-filename': 'str',
+           '*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'],
+           '*backing-image': 'ImageInfo',
+           '*format-specific': 'ImageInfoSpecific' } }
+
+##
+# @ImageCheck:
+#
+# Information about a QEMU image file check
+#
+# @filename: name of the image file checked
+#
+# @format: format of the image file checked
+#
+# @check-errors: number of unexpected errors occurred during check
+#
+# @image-end-offset: #optional offset (in bytes) where the image ends, this
+#                    field is present if the driver for the image format
+#                    supports it
+#
+# @corruptions: #optional number of corruptions found during the check if any
+#
+# @leaks: #optional number of leaks found during the check if any
+#
+# @corruptions-fixed: #optional number of corruptions fixed during the check
+#                     if any
+#
+# @leaks-fixed: #optional number of leaks fixed during the check if any
+#
+# @total-clusters: #optional total number of clusters, this field is present
+#                  if the driver for the image format supports it
+#
+# @allocated-clusters: #optional total number of allocated clusters, this
+#                      field is present if the driver for the image format
+#                      supports it
+#
+# @fragmented-clusters: #optional total number of fragmented clusters, this
+#                       field is present if the driver for the image format
+#                       supports it
+#
+# @compressed-clusters: #optional total number of compressed clusters, this
+#                       field is present if the driver for the image format
+#                       supports it
+#
+# Since: 1.4
+#
+##
+
+{ 'type': 'ImageCheck',
+  'data': {'filename': 'str', 'format': 'str', 'check-errors': 'int',
+           '*image-end-offset': 'int', '*corruptions': 'int', '*leaks': 'int',
+           '*corruptions-fixed': 'int', '*leaks-fixed': 'int',
+           '*total-clusters': 'int', '*allocated-clusters': 'int',
+           '*fragmented-clusters': 'int', '*compressed-clusters': 'int' } }
+
+##
+# @StatusInfo:
+#
+# Information about VCPU run state
+#
+# @running: true if all VCPUs are runnable, false if not runnable
+#
+# @singlestep: true if VCPUs are in single-step mode
+#
+# @status: the virtual machine @RunState
+#
+# Since:  0.14.0
+#
+# Notes: @singlestep is enabled through the GDB stub
+##
+{ 'type': 'StatusInfo',
+  'data': {'running': 'bool', 'singlestep': 'bool', 'status': 'RunState'} }
+
+##
+# @query-status:
+#
+# Query the run status of all VCPUs
+#
+# Returns: @StatusInfo reflecting all VCPUs
+#
+# Since:  0.14.0
+##
+{ 'command': 'query-status', 'returns': 'StatusInfo' }
+
+##
+# @UuidInfo:
+#
+# Guest UUID information.
+#
+# @UUID: the UUID of the guest
+#
+# Since: 0.14.0
+#
+# Notes: If no UUID was specified for the guest, a null UUID is returned.
+##
+{ 'type': 'UuidInfo', 'data': {'UUID': 'str'} }
+
+##
+# @query-uuid:
+#
+# Query the guest UUID information.
+#
+# Returns: The @UuidInfo for the guest
+#
+# Since 0.14.0
+##
+{ 'command': 'query-uuid', 'returns': 'UuidInfo' }
+
+##
+# @ChardevInfo:
+#
+# Information about a character device.
+#
+# @label: the label of the character device
+#
+# @filename: the filename of the character device
+#
+# Notes: @filename is encoded using the QEMU command line character device
+#        encoding.  See the QEMU man page for details.
+#
+# Since: 0.14.0
+##
+{ 'type': 'ChardevInfo', 'data': {'label': 'str', 'filename': 'str'} }
+
+##
+# @query-chardev:
+#
+# Returns information about current character devices.
+#
+# Returns: a list of @ChardevInfo
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-chardev', 'returns': ['ChardevInfo'] }
+
+##
+# @DataFormat:
+#
+# An enumeration of data format.
+#
+# @utf8: Data is a UTF-8 string (RFC 3629)
+#
+# @base64: Data is Base64 encoded binary (RFC 3548)
+#
+# Since: 1.4
+##
+{ 'enum': 'DataFormat',
+  'data': [ 'utf8', 'base64' ] }
+
+##
+# @ringbuf-write:
+#
+# Write to a ring buffer character device.
+#
+# @device: the ring buffer character device name
+#
+# @data: data to write
+#
+# @format: #optional data encoding (default 'utf8').
+#          - base64: data must be base64 encoded text.  Its binary
+#            decoding gets written.
+#            Bug: invalid base64 is currently not rejected.
+#            Whitespace *is* invalid.
+#          - utf8: data's UTF-8 encoding is written
+#          - data itself is always Unicode regardless of format, like
+#            any other string.
+#
+# Returns: Nothing on success
+#
+# Since: 1.4
+##
+{ 'command': 'ringbuf-write',
+  'data': {'device': 'str', 'data': 'str',
+           '*format': 'DataFormat'} }
+
+##
+# @ringbuf-read:
+#
+# Read from a ring buffer character device.
+#
+# @device: the ring buffer character device name
+#
+# @size: how many bytes to read at most
+#
+# @format: #optional data encoding (default 'utf8').
+#          - base64: the data read is returned in base64 encoding.
+#          - utf8: the data read is interpreted as UTF-8.
+#            Bug: can screw up when the buffer contains invalid UTF-8
+#            sequences, NUL characters, after the ring buffer lost
+#            data, and when reading stops because the size limit is
+#            reached.
+#          - The return value is always Unicode regardless of format,
+#            like any other string.
+#
+# Returns: data read from the device
+#
+# Since: 1.4
+##
+{ 'command': 'ringbuf-read',
+  'data': {'device': 'str', 'size': 'int', '*format': 'DataFormat'},
+  'returns': 'str' }
+
+##
+# @CommandInfo:
+#
+# Information about a QMP command
+#
+# @name: The command name
+#
+# Since: 0.14.0
+##
+{ 'type': 'CommandInfo', 'data': {'name': 'str'} }
+
+##
+# @query-commands:
+#
+# Return a list of supported QMP commands by this server
+#
+# Returns: A list of @CommandInfo for all supported commands
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-commands', 'returns': ['CommandInfo'] }
+
+##
+# @EventInfo:
+#
+# Information about a QMP event
+#
+# @name: The event name
+#
+# Since: 1.2.0
+##
+{ 'type': 'EventInfo', 'data': {'name': 'str'} }
+
+##
+# @query-events:
+#
+# Return a list of supported QMP events by this server
+#
+# Returns: A list of @EventInfo for all supported events
+#
+# Since: 1.2.0
+##
+{ 'command': 'query-events', 'returns': ['EventInfo'] }
+
+##
+# @MigrationStats
+#
+# Detailed migration status.
+#
+# @transferred: amount of bytes already transferred to the target VM
+#
+# @remaining: amount of bytes remaining to be transferred to the target VM
+#
+# @total: total amount of bytes involved in the migration process
+#
+# @duplicate: number of duplicate (zero) pages (since 1.2)
+#
+# @skipped: number of skipped zero pages (since 1.5)
+#
+# @normal : number of normal pages (since 1.2)
+#
+# @normal-bytes: number of normal bytes sent (since 1.2)
+#
+# @dirty-pages-rate: number of pages dirtied by second by the
+#        guest (since 1.3)
+#
+# @mbps: throughput in megabits/sec. (since 1.6)
+#
+# Since: 0.14.0
+##
+{ 'type': 'MigrationStats',
+  'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,
+           'duplicate': 'int', 'skipped': 'int', 'normal': 'int',
+           'normal-bytes': 'int', 'dirty-pages-rate' : 'int',
+           'mbps' : 'number' } }
+
+##
+# @XBZRLECacheStats
+#
+# Detailed XBZRLE migration cache statistics
+#
+# @cache-size: XBZRLE cache size
+#
+# @bytes: amount of bytes already transferred to the target VM
+#
+# @pages: amount of pages transferred to the target VM
+#
+# @cache-miss: number of cache miss
+#
+# @overflow: number of overflows
+#
+# Since: 1.2
+##
+{ 'type': 'XBZRLECacheStats',
+  'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int',
+           'cache-miss': 'int', 'overflow': 'int' } }
+
+##
+# @MigrationInfo
+#
+# Information about current migration process.
+#
+# @status: #optional string describing the current migration status.
+#          As of 0.14.0 this can be 'active', 'completed', 'failed' or
+#          'cancelled'. If this field is not returned, no migration process
+#          has been initiated
+#
+# @ram: #optional @MigrationStats containing detailed migration
+#       status, only returned if status is 'active' or
+#       'completed'. 'comppleted' (since 1.2)
+#
+# @disk: #optional @MigrationStats containing detailed disk migration
+#        status, only returned if status is 'active' and it is a block
+#        migration
+#
+# @xbzrle-cache: #optional @XBZRLECacheStats containing detailed XBZRLE
+#                migration statistics, only returned if XBZRLE feature is on and
+#                status is 'active' or 'completed' (since 1.2)
+#
+# @total-time: #optional total amount of milliseconds since migration started.
+#        If migration has ended, it returns the total migration
+#        time. (since 1.2)
+#
+# @downtime: #optional only present when migration finishes correctly
+#        total downtime in milliseconds for the guest.
+#        (since 1.3)
+#
+# @expected-downtime: #optional only present while migration is active
+#        expected downtime in milliseconds for the guest in last walk
+#        of the dirty bitmap. (since 1.3)
+#
+# @setup-time: #optional amount of setup time in milliseconds _before_ the
+#        iterations begin but _after_ the QMP command is issued. This is designed
+#        to provide an accounting of any activities (such as RDMA pinning) which
+#        may be expensive, but do not actually occur during the iterative
+#        migration rounds themselves. (since 1.6)
+#
+# Since: 0.14.0
+##
+{ 'type': 'MigrationInfo',
+  'data': {'*status': 'str', '*ram': 'MigrationStats',
+           '*disk': 'MigrationStats',
+           '*xbzrle-cache': 'XBZRLECacheStats',
+           '*total-time': 'int',
+           '*expected-downtime': 'int',
+           '*downtime': 'int',
+           '*setup-time': 'int'} }
+
+##
+# @query-migrate
+#
+# Returns information about current migration process.
+#
+# Returns: @MigrationInfo
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-migrate', 'returns': 'MigrationInfo' }
+
+##
+# @MigrationCapability
+#
+# Migration capabilities enumeration
+#
+# @xbzrle: Migration supports xbzrle (Xor Based Zero Run Length Encoding).
+#          This feature allows us to minimize migration traffic for certain work
+#          loads, by sending compressed difference of the pages
+#
+# @x-rdma-pin-all: Controls whether or not the entire VM memory footprint is
+#          mlock()'d on demand or all at once. Refer to docs/rdma.txt for usage.
+#          Disabled by default. Experimental: may (or may not) be renamed after
+#          further testing is complete. (since 1.6)
+#
+# @zero-blocks: During storage migration encode blocks of zeroes efficiently. This
+#          essentially saves 1MB of zeroes per block on the wire. Enabling requires
+#          source and target VM to support this feature. To enable it is sufficient
+#          to enable the capability on the source VM. The feature is disabled by
+#          default. (since 1.6)
+#
+# @auto-converge: If enabled, QEMU will automatically throttle down the guest
+#          to speed up convergence of RAM migration. (since 1.6)
+#
+# Since: 1.2
+##
+{ 'enum': 'MigrationCapability',
+  'data': ['xbzrle', 'x-rdma-pin-all', 'auto-converge', 'zero-blocks'] }
+
+##
+# @MigrationCapabilityStatus
+#
+# Migration capability information
+#
+# @capability: capability enum
+#
+# @state: capability state bool
+#
+# Since: 1.2
+##
+{ 'type': 'MigrationCapabilityStatus',
+  'data': { 'capability' : 'MigrationCapability', 'state' : 'bool' } }
+
+##
+# @migrate-set-capabilities
+#
+# Enable/Disable the following migration capabilities (like xbzrle)
+#
+# @capabilities: json array of capability modifications to make
+#
+# Since: 1.2
+##
+{ 'command': 'migrate-set-capabilities',
+  'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
+
+##
+# @query-migrate-capabilities
+#
+# Returns information about the current migration capabilities status
+#
+# Returns: @MigrationCapabilitiesStatus
+#
+# Since: 1.2
+##
+{ 'command': 'query-migrate-capabilities', 'returns':   ['MigrationCapabilityStatus']}
+
+##
+# @MouseInfo:
+#
+# Information about a mouse device.
+#
+# @name: the name of the mouse device
+#
+# @index: the index of the mouse device
+#
+# @current: true if this device is currently receiving mouse events
+#
+# @absolute: true if this device supports absolute coordinates as input
+#
+# Since: 0.14.0
+##
+{ 'type': 'MouseInfo',
+  'data': {'name': 'str', 'index': 'int', 'current': 'bool',
+           'absolute': 'bool'} }
+
+##
+# @query-mice:
+#
+# Returns information about each active mouse device
+#
+# Returns: a list of @MouseInfo for each device
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-mice', 'returns': ['MouseInfo'] }
+
+##
+# @CpuInfo:
+#
+# Information about a virtual CPU
+#
+# @CPU: the index of the virtual CPU
+#
+# @current: this only exists for backwards compatible and should be ignored
+#
+# @halted: true if the virtual CPU is in the halt state.  Halt usually refers
+#          to a processor specific low power mode.
+#
+# @pc: #optional If the target is i386 or x86_64, this is the 64-bit instruction
+#                pointer.
+#                If the target is Sparc, this is the PC component of the
+#                instruction pointer.
+#
+# @nip: #optional If the target is PPC, the instruction pointer
+#
+# @npc: #optional If the target is Sparc, the NPC component of the instruction
+#                 pointer
+#
+# @PC: #optional If the target is MIPS, the instruction pointer
+#
+# @thread_id: ID of the underlying host thread
+#
+# Since: 0.14.0
+#
+# Notes: @halted is a transient state that changes frequently.  By the time the
+#        data is sent to the client, the guest may no longer be halted.
+##
+{ 'type': 'CpuInfo',
+  'data': {'CPU': 'int', 'current': 'bool', 'halted': 'bool', '*pc': 'int',
+           '*nip': 'int', '*npc': 'int', '*PC': 'int', 'thread_id': 'int'} }
+
+##
+# @query-cpus:
+#
+# Returns a list of information about each virtual CPU.
+#
+# Returns: a list of @CpuInfo for each virtual CPU
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-cpus', 'returns': ['CpuInfo'] }
+
+##
+# @BlockDeviceInfo:
+#
+# Information about the backing device for a block device.
+#
+# @file: the filename of the backing device
+#
+# @ro: true if the backing device was open read-only
+#
+# @drv: the name of the block format used to open the backing device. As of
+#       0.14.0 this can be: 'blkdebug', 'bochs', 'cloop', 'cow', 'dmg',
+#       'file', 'file', 'ftp', 'ftps', 'host_cdrom', 'host_device',
+#       'host_floppy', 'http', 'https', 'nbd', 'parallels', 'qcow',
+#       'qcow2', 'raw', 'tftp', 'vdi', 'vmdk', 'vpc', 'vvfat'
+#
+# @backing_file: #optional the name of the backing file (for copy-on-write)
+#
+# @backing_file_depth: number of files in the backing file chain (since: 1.2)
+#
+# @encrypted: true if the backing device is encrypted
+#
+# @encryption_key_missing: true if the backing device is encrypted but an
+#                          valid encryption key is missing
+#
+# @bps: total throughput limit in bytes per second is specified
+#
+# @bps_rd: read throughput limit in bytes per second is specified
+#
+# @bps_wr: write throughput limit in bytes per second is specified
+#
+# @iops: total I/O operations per second is specified
+#
+# @iops_rd: read I/O operations per second is specified
+#
+# @iops_wr: write I/O operations per second is specified
+#
+# @image: the info of image used (since: 1.6)
+#
+# @bps_max: #optional total max in bytes (Since 1.7)
+#
+# @bps_rd_max: #optional read max in bytes (Since 1.7)
+#
+# @bps_wr_max: #optional write max in bytes (Since 1.7)
+#
+# @iops_max: #optional total I/O operations max (Since 1.7)
+#
+# @iops_rd_max: #optional read I/O operations max (Since 1.7)
+#
+# @iops_wr_max: #optional write I/O operations max (Since 1.7)
+#
+# @iops_size: #optional an I/O size in bytes (Since 1.7)
+#
+# Since: 0.14.0
+#
+# Notes: This interface is only found in @BlockInfo.
+##
+{ 'type': 'BlockDeviceInfo',
+  'data': { 'file': 'str', 'ro': 'bool', 'drv': 'str',
+            '*backing_file': 'str', 'backing_file_depth': 'int',
+            'encrypted': 'bool', 'encryption_key_missing': 'bool',
+            'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
+            'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
+            'image': 'ImageInfo',
+            '*bps_max': 'int', '*bps_rd_max': 'int',
+            '*bps_wr_max': 'int', '*iops_max': 'int',
+            '*iops_rd_max': 'int', '*iops_wr_max': 'int',
+            '*iops_size': 'int' } }
+
+##
+# @BlockDeviceIoStatus:
+#
+# An enumeration of block device I/O status.
+#
+# @ok: The last I/O operation has succeeded
+#
+# @failed: The last I/O operation has failed
+#
+# @nospace: The last I/O operation has failed due to a no-space condition
+#
+# Since: 1.0
+##
+{ 'enum': 'BlockDeviceIoStatus', 'data': [ 'ok', 'failed', 'nospace' ] }
+
+##
+# @BlockDeviceMapEntry:
+#
+# Entry in the metadata map of the device (returned by "qemu-img map")
+#
+# @start: Offset in the image of the first byte described by this entry
+#         (in bytes)
+#
+# @length: Length of the range described by this entry (in bytes)
+#
+# @depth: Number of layers (0 = top image, 1 = top image's backing file, etc.)
+#         before reaching one for which the range is allocated.  The value is
+#         in the range 0 to the depth of the image chain - 1.
+#
+# @zero: the sectors in this range read as zeros
+#
+# @data: reading the image will actually read data from a file (in particular,
+#        if @offset is present this means that the sectors are not simply
+#        preallocated, but contain actual data in raw format)
+#
+# @offset: if present, the image file stores the data for this range in
+#          raw format at the given offset.
+#
+# Since 1.7
+##
+{ 'type': 'BlockDeviceMapEntry',
+  'data': { 'start': 'int', 'length': 'int', 'depth': 'int', 'zero': 'bool',
+            'data': 'bool', '*offset': 'int' } }
+
+##
+# @BlockDirtyInfo:
+#
+# Block dirty bitmap information.
+#
+# @count: number of dirty bytes according to the dirty bitmap
+#
+# @granularity: granularity of the dirty bitmap in bytes (since 1.4)
+#
+# Since: 1.3
+##
+{ 'type': 'BlockDirtyInfo',
+  'data': {'count': 'int', 'granularity': 'int'} }
+
+##
+# @BlockInfo:
+#
+# Block device information.  This structure describes a virtual device and
+# the backing device associated with it.
+#
+# @device: The device name associated with the virtual device.
+#
+# @type: This field is returned only for compatibility reasons, it should
+#        not be used (always returns 'unknown')
+#
+# @removable: True if the device supports removable media.
+#
+# @locked: True if the guest has locked this device from having its media
+#          removed
+#
+# @tray_open: #optional True if the device has a tray and it is open
+#             (only present if removable is true)
+#
+# @dirty-bitmaps: #optional dirty bitmaps information (only present if the
+#                 driver has one or more dirty bitmaps) (Since 1.8)
+#
+# @io-status: #optional @BlockDeviceIoStatus. Only present if the device
+#             supports it and the VM is configured to stop on errors
+#
+# @inserted: #optional @BlockDeviceInfo describing the device if media is
+#            present
+#
+# Since:  0.14.0
+##
+{ 'type': 'BlockInfo',
+  'data': {'device': 'str', 'type': 'str', 'removable': 'bool',
+           'locked': 'bool', '*inserted': 'BlockDeviceInfo',
+           '*tray_open': 'bool', '*io-status': 'BlockDeviceIoStatus',
+           '*dirty-bitmaps': ['BlockDirtyInfo'] } }
+
+##
+# @query-block:
+#
+# Get a list of BlockInfo for all virtual block devices.
+#
+# Returns: a list of @BlockInfo describing each virtual block device
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-block', 'returns': ['BlockInfo'] }
+
+##
+# @BlockDeviceStats:
+#
+# Statistics of a virtual block device or a block backing device.
+#
+# @rd_bytes:      The number of bytes read by the device.
+#
+# @wr_bytes:      The number of bytes written by the device.
+#
+# @rd_operations: The number of read operations performed by the device.
+#
+# @wr_operations: The number of write operations performed by the device.
+#
+# @flush_operations: The number of cache flush operations performed by the
+#                    device (since 0.15.0)
+#
+# @flush_total_time_ns: Total time spend on cache flushes in nano-seconds
+#                       (since 0.15.0).
+#
+# @wr_total_time_ns: Total time spend on writes in nano-seconds (since 0.15.0).
+#
+# @rd_total_time_ns: Total_time_spend on reads in nano-seconds (since 0.15.0).
+#
+# @wr_highest_offset: The offset after the greatest byte written to the
+#                     device.  The intended use of this information is for
+#                     growable sparse files (like qcow2) that are used on top
+#                     of a physical device.
+#
+# Since: 0.14.0
+##
+{ 'type': 'BlockDeviceStats',
+  'data': {'rd_bytes': 'int', 'wr_bytes': 'int', 'rd_operations': 'int',
+           'wr_operations': 'int', 'flush_operations': 'int',
+           'flush_total_time_ns': 'int', 'wr_total_time_ns': 'int',
+           'rd_total_time_ns': 'int', 'wr_highest_offset': 'int' } }
+
+##
+# @BlockStats:
+#
+# Statistics of a virtual block device or a block backing device.
+#
+# @device: #optional If the stats are for a virtual block device, the name
+#          corresponding to the virtual block device.
+#
+# @stats:  A @BlockDeviceStats for the device.
+#
+# @parent: #optional This may point to the backing block device if this is a
+#          a virtual block device.  If it's a backing block, this will point
+#          to the backing file is one is present.
+#
+# Since: 0.14.0
+##
+{ 'type': 'BlockStats',
+  'data': {'*device': 'str', 'stats': 'BlockDeviceStats',
+           '*parent': 'BlockStats'} }
+
+##
+# @query-blockstats:
+#
+# Query the @BlockStats for all virtual block devices.
+#
+# Returns: A list of @BlockStats for each virtual block devices.
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-blockstats', 'returns': ['BlockStats'] }
+
+##
+# @VncClientInfo:
+#
+# Information about a connected VNC client.
+#
+# @host: The host name of the client.  QEMU tries to resolve this to a DNS name
+#        when possible.
+#
+# @family: 'ipv6' if the client is connected via IPv6 and TCP
+#          'ipv4' if the client is connected via IPv4 and TCP
+#          'unix' if the client is connected via a unix domain socket
+#          'unknown' otherwise
+#
+# @service: The service name of the client's port.  This may depends on the
+#           host system's service database so symbolic names should not be
+#           relied on.
+#
+# @x509_dname: #optional If x509 authentication is in use, the Distinguished
+#              Name of the client.
+#
+# @sasl_username: #optional If SASL authentication is in use, the SASL username
+#                 used for authentication.
+#
+# Since: 0.14.0
+##
+{ 'type': 'VncClientInfo',
+  'data': {'host': 'str', 'family': 'str', 'service': 'str',
+           '*x509_dname': 'str', '*sasl_username': 'str'} }
+
+##
+# @VncInfo:
+#
+# Information about the VNC session.
+#
+# @enabled: true if the VNC server is enabled, false otherwise
+#
+# @host: #optional The hostname the VNC server is bound to.  This depends on
+#        the name resolution on the host and may be an IP address.
+#
+# @family: #optional 'ipv6' if the host is listening for IPv6 connections
+#                    'ipv4' if the host is listening for IPv4 connections
+#                    'unix' if the host is listening on a unix domain socket
+#                    'unknown' otherwise
+#
+# @service: #optional The service name of the server's port.  This may depends
+#           on the host system's service database so symbolic names should not
+#           be relied on.
+#
+# @auth: #optional the current authentication type used by the server
+#        'none' if no authentication is being used
+#        'vnc' if VNC authentication is being used
+#        'vencrypt+plain' if VEncrypt is used with plain text authentication
+#        'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication
+#        'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication
+#        'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth
+#        'vencrypt+x509+none' if VEncrypt is used with x509 and no auth
+#        'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth
+#        'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth
+#        'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth
+#        'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth
+#
+# @clients: a list of @VncClientInfo of all currently connected clients
+#
+# Since: 0.14.0
+##
+{ 'type': 'VncInfo',
+  'data': {'enabled': 'bool', '*host': 'str', '*family': 'str',
+           '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }
+
+##
+# @query-vnc:
+#
+# Returns information about the current VNC server
+#
+# Returns: @VncInfo
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-vnc', 'returns': 'VncInfo' }
+
+##
+# @SpiceChannel
+#
+# Information about a SPICE client channel.
+#
+# @host: The host name of the client.  QEMU tries to resolve this to a DNS name
+#        when possible.
+#
+# @family: 'ipv6' if the client is connected via IPv6 and TCP
+#          'ipv4' if the client is connected via IPv4 and TCP
+#          'unix' if the client is connected via a unix domain socket
+#          'unknown' otherwise
+#
+# @port: The client's port number.
+#
+# @connection-id: SPICE connection id number.  All channels with the same id
+#                 belong to the same SPICE session.
+#
+# @connection-type: SPICE channel type number.  "1" is the main control
+#                   channel, filter for this one if you want to track spice
+#                   sessions only
+#
+# @channel-id: SPICE channel ID number.  Usually "0", might be different when
+#              multiple channels of the same type exist, such as multiple
+#              display channels in a multihead setup
+#
+# @tls: true if the channel is encrypted, false otherwise.
+#
+# Since: 0.14.0
+##
+{ 'type': 'SpiceChannel',
+  'data': {'host': 'str', 'family': 'str', 'port': 'str',
+           'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int',
+           'tls': 'bool'} }
+
+##
+# @SpiceQueryMouseMode
+#
+# An enumeration of Spice mouse states.
+#
+# @client: Mouse cursor position is determined by the client.
+#
+# @server: Mouse cursor position is determined by the server.
+#
+# @unknown: No information is available about mouse mode used by
+#           the spice server.
+#
+# Note: spice/enums.h has a SpiceMouseMode already, hence the name.
+#
+# Since: 1.1
+##
+{ 'enum': 'SpiceQueryMouseMode',
+  'data': [ 'client', 'server', 'unknown' ] }
+
+##
+# @SpiceInfo
+#
+# Information about the SPICE session.
+#
+# @enabled: true if the SPICE server is enabled, false otherwise
+#
+# @migrated: true if the last guest migration completed and spice
+#            migration had completed as well. false otherwise.
+#
+# @host: #optional The hostname the SPICE server is bound to.  This depends on
+#        the name resolution on the host and may be an IP address.
+#
+# @port: #optional The SPICE server's port number.
+#
+# @compiled-version: #optional SPICE server version.
+#
+# @tls-port: #optional The SPICE server's TLS port number.
+#
+# @auth: #optional the current authentication type used by the server
+#        'none'  if no authentication is being used
+#        'spice' uses SASL or direct TLS authentication, depending on command
+#                line options
+#
+# @mouse-mode: The mode in which the mouse cursor is displayed currently. Can
+#              be determined by the client or the server, or unknown if spice
+#              server doesn't provide this information.
+#
+#              Since: 1.1
+#
+# @channels: a list of @SpiceChannel for each active spice channel
+#
+# Since: 0.14.0
+##
+{ 'type': 'SpiceInfo',
+  'data': {'enabled': 'bool', 'migrated': 'bool', '*host': 'str', '*port': 'int',
+           '*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str',
+           'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']} }
+
+##
+# @query-spice
+#
+# Returns information about the current SPICE server
+#
+# Returns: @SpiceInfo
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-spice', 'returns': 'SpiceInfo' }
+
+##
+# @BalloonInfo:
+#
+# Information about the guest balloon device.
+#
+# @actual: the number of bytes the balloon currently contains
+#
+# Since: 0.14.0
+#
+##
+{ 'type': 'BalloonInfo', 'data': {'actual': 'int' } }
+
+##
+# @query-balloon:
+#
+# Return information about the balloon device.
+#
+# Returns: @BalloonInfo on success
+#          If the balloon driver is enabled but not functional because the KVM
+#          kernel module cannot support it, KvmMissingCap
+#          If no balloon device is present, DeviceNotActive
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-balloon', 'returns': 'BalloonInfo' }
+
+##
+# @PciMemoryRange:
+#
+# A PCI device memory region
+#
+# @base: the starting address (guest physical)
+#
+# @limit: the ending address (guest physical)
+#
+# Since: 0.14.0
+##
+{ 'type': 'PciMemoryRange', 'data': {'base': 'int', 'limit': 'int'} }
+
+##
+# @PciMemoryRegion
+#
+# Information about a PCI device I/O region.
+#
+# @bar: the index of the Base Address Register for this region
+#
+# @type: 'io' if the region is a PIO region
+#        'memory' if the region is a MMIO region
+#
+# @prefetch: #optional if @type is 'memory', true if the memory is prefetchable
+#
+# @mem_type_64: #optional if @type is 'memory', true if the BAR is 64-bit
+#
+# Since: 0.14.0
+##
+{ 'type': 'PciMemoryRegion',
+  'data': {'bar': 'int', 'type': 'str', 'address': 'int', 'size': 'int',
+           '*prefetch': 'bool', '*mem_type_64': 'bool' } }
+
+##
+# @PciBridgeInfo:
+#
+# Information about a PCI Bridge device
+#
+# @bus.number: primary bus interface number.  This should be the number of the
+#              bus the device resides on.
+#
+# @bus.secondary: secondary bus interface number.  This is the number of the
+#                 main bus for the bridge
+#
+# @bus.subordinate: This is the highest number bus that resides below the
+#                   bridge.
+#
+# @bus.io_range: The PIO range for all devices on this bridge
+#
+# @bus.memory_range: The MMIO range for all devices on this bridge
+#
+# @bus.prefetchable_range: The range of prefetchable MMIO for all devices on
+#                          this bridge
+#
+# @devices: a list of @PciDeviceInfo for each device on this bridge
+#
+# Since: 0.14.0
+##
+{ 'type': 'PciBridgeInfo',
+  'data': {'bus': { 'number': 'int', 'secondary': 'int', 'subordinate': 'int',
+                    'io_range': 'PciMemoryRange',
+                    'memory_range': 'PciMemoryRange',
+                    'prefetchable_range': 'PciMemoryRange' },
+           '*devices': ['PciDeviceInfo']} }
+
+##
+# @PciDeviceInfo:
+#
+# Information about a PCI device
+#
+# @bus: the bus number of the device
+#
+# @slot: the slot the device is located in
+#
+# @function: the function of the slot used by the device
+#
+# @class_info.desc: #optional a string description of the device's class
+#
+# @class_info.class: the class code of the device
+#
+# @id.device: the PCI device id
+#
+# @id.vendor: the PCI vendor id
+#
+# @irq: #optional if an IRQ is assigned to the device, the IRQ number
+#
+# @qdev_id: the device name of the PCI device
+#
+# @pci_bridge: if the device is a PCI bridge, the bridge information
+#
+# @regions: a list of the PCI I/O regions associated with the device
+#
+# Notes: the contents of @class_info.desc are not stable and should only be
+#        treated as informational.
+#
+# Since: 0.14.0
+##
+{ 'type': 'PciDeviceInfo',
+  'data': {'bus': 'int', 'slot': 'int', 'function': 'int',
+           'class_info': {'*desc': 'str', 'class': 'int'},
+           'id': {'device': 'int', 'vendor': 'int'},
+           '*irq': 'int', 'qdev_id': 'str', '*pci_bridge': 'PciBridgeInfo',
+           'regions': ['PciMemoryRegion']} }
+
+##
+# @PciInfo:
+#
+# Information about a PCI bus
+#
+# @bus: the bus index
+#
+# @devices: a list of devices on this bus
+#
+# Since: 0.14.0
+##
+{ 'type': 'PciInfo', 'data': {'bus': 'int', 'devices': ['PciDeviceInfo']} }
+
+##
+# @query-pci:
+#
+# Return information about the PCI bus topology of the guest.
+#
+# Returns: a list of @PciInfo for each PCI bus
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-pci', 'returns': ['PciInfo'] }
+
+##
+# @BlockdevOnError:
+#
+# An enumeration of possible behaviors for errors on I/O operations.
+# The exact meaning depends on whether the I/O was initiated by a guest
+# or by a block job
+#
+# @report: for guest operations, report the error to the guest;
+#          for jobs, cancel the job
+#
+# @ignore: ignore the error, only report a QMP event (BLOCK_IO_ERROR
+#          or BLOCK_JOB_ERROR)
+#
+# @enospc: same as @stop on ENOSPC, same as @report otherwise.
+#
+# @stop: for guest operations, stop the virtual machine;
+#        for jobs, pause the job
+#
+# Since: 1.3
+##
+{ 'enum': 'BlockdevOnError',
+  'data': ['report', 'ignore', 'enospc', 'stop'] }
+
+##
+# @MirrorSyncMode:
+#
+# An enumeration of possible behaviors for the initial synchronization
+# phase of storage mirroring.
+#
+# @top: copies data in the topmost image to the destination
+#
+# @full: copies data from all images to the destination
+#
+# @none: only copy data written from now on
+#
+# Since: 1.3
+##
+{ 'enum': 'MirrorSyncMode',
+  'data': ['top', 'full', 'none'] }
+
+##
+# @BlockJobType:
+#
+# Type of a block job.
+#
+# @commit: block commit job type, see "block-commit"
+#
+# @stream: block stream job type, see "block-stream"
+#
+# @mirror: drive mirror job type, see "drive-mirror"
+#
+# @backup: drive backup job type, see "drive-backup"
+#
+# Since: 1.7
+##
+{ 'enum': 'BlockJobType',
+  'data': ['commit', 'stream', 'mirror', 'backup'] }
+
+##
+# @BlockJobInfo:
+#
+# Information about a long-running block device operation.
+#
+# @type: the job type ('stream' for image streaming)
+#
+# @device: the block device name
+#
+# @len: the maximum progress value
+#
+# @busy: false if the job is known to be in a quiescent state, with
+#        no pending I/O.  Since 1.3.
+#
+# @paused: whether the job is paused or, if @busy is true, will
+#          pause itself as soon as possible.  Since 1.3.
+#
+# @offset: the current progress value
+#
+# @speed: the rate limit, bytes per second
+#
+# @io-status: the status of the job (since 1.3)
+#
+# Since: 1.1
+##
+{ 'type': 'BlockJobInfo',
+  'data': {'type': 'str', 'device': 'str', 'len': 'int',
+           'offset': 'int', 'busy': 'bool', 'paused': 'bool', 'speed': 'int',
+           'io-status': 'BlockDeviceIoStatus'} }
+
+##
+# @query-block-jobs:
+#
+# Return information about long-running block device operations.
+#
+# Returns: a list of @BlockJobInfo for each active block job
+#
+# Since: 1.1
+##
+{ 'command': 'query-block-jobs', 'returns': ['BlockJobInfo'] }
+
+##
+# @quit:
+#
+# This command will cause the QEMU process to exit gracefully.  While every
+# attempt is made to send the QMP response before terminating, this is not
+# guaranteed.  When using this interface, a premature EOF would not be
+# unexpected.
+#
+# Since: 0.14.0
+##
+{ 'command': 'quit' }
+
+##
+# @stop:
+#
+# Stop all guest VCPU execution.
+#
+# Since:  0.14.0
+#
+# Notes:  This function will succeed even if the guest is already in the stopped
+#         state.  In "inmigrate" state, it will ensure that the guest
+#         remains paused once migration finishes, as if the -S option was
+#         passed on the command line.
+##
+{ 'command': 'stop' }
+
+##
+# @system_reset:
+#
+# Performs a hard reset of a guest.
+#
+# Since: 0.14.0
+##
+{ 'command': 'system_reset' }
+
+##
+# @system_powerdown:
+#
+# Requests that a guest perform a powerdown operation.
+#
+# Since: 0.14.0
+#
+# Notes: A guest may or may not respond to this command.  This command
+#        returning does not indicate that a guest has accepted the request or
+#        that it has shut down.  Many guests will respond to this command by
+#        prompting the user in some way.
+##
+{ 'command': 'system_powerdown' }
+
+##
+# @cpu:
+#
+# This command is a nop that is only provided for the purposes of compatibility.
+#
+# Since: 0.14.0
+#
+# Notes: Do not use this command.
+##
+{ 'command': 'cpu', 'data': {'index': 'int'} }
+
+##
+# @cpu-add
+#
+# Adds CPU with specified ID
+#
+# @id: ID of CPU to be created, valid values [0..max_cpus)
+#
+# Returns: Nothing on success
+#
+# Since 1.5
+##
+{ 'command': 'cpu-add', 'data': {'id': 'int'} }
+
+##
+# @memsave:
+#
+# Save a portion of guest memory to a file.
+#
+# @val: the virtual address of the guest to start from
+#
+# @size: the size of memory region to save
+#
+# @filename: the file to save the memory to as binary data
+#
+# @cpu-index: #optional the index of the virtual CPU to use for translating the
+#                       virtual address (defaults to CPU 0)
+#
+# Returns: Nothing on success
+#
+# Since: 0.14.0
+#
+# Notes: Errors were not reliably returned until 1.1
+##
+{ 'command': 'memsave',
+  'data': {'val': 'int', 'size': 'int', 'filename': 'str', '*cpu-index': 'int'} }
+
+##
+# @pmemsave:
+#
+# Save a portion of guest physical memory to a file.
+#
+# @val: the physical address of the guest to start from
+#
+# @size: the size of memory region to save
+#
+# @filename: the file to save the memory to as binary data
+#
+# Returns: Nothing on success
+#
+# Since: 0.14.0
+#
+# Notes: Errors were not reliably returned until 1.1
+##
+{ 'command': 'pmemsave',
+  'data': {'val': 'int', 'size': 'int', 'filename': 'str'} }
+
+##
+# @cont:
+#
+# Resume guest VCPU execution.
+#
+# Since:  0.14.0
+#
+# Returns:  If successful, nothing
+#           If QEMU was started with an encrypted block device and a key has
+#              not yet been set, DeviceEncrypted.
+#
+# Notes:  This command will succeed if the guest is currently running.  It
+#         will also succeed if the guest is in the "inmigrate" state; in
+#         this case, the effect of the command is to make sure the guest
+#         starts once migration finishes, removing the effect of the -S
+#         command line option if it was passed.
+##
+{ 'command': 'cont' }
+
+##
+# @system_wakeup:
+#
+# Wakeup guest from suspend.  Does nothing in case the guest isn't suspended.
+#
+# Since:  1.1
+#
+# Returns:  nothing.
+##
+{ 'command': 'system_wakeup' }
+
+##
+# @inject-nmi:
+#
+# Injects an Non-Maskable Interrupt into all guest's VCPUs.
+#
+# Returns:  If successful, nothing
+#
+# Since:  0.14.0
+#
+# Notes: Only x86 Virtual Machines support this command.
+##
+{ 'command': 'inject-nmi' }
+
+##
+# @set_link:
+#
+# Sets the link status of a virtual network adapter.
+#
+# @name: the device name of the virtual network adapter
+#
+# @up: true to set the link status to be up
+#
+# Returns: Nothing on success
+#          If @name is not a valid network device, DeviceNotFound
+#
+# Since: 0.14.0
+#
+# Notes: Not all network adapters support setting link status.  This command
+#        will succeed even if the network adapter does not support link status
+#        notification.
+##
+{ 'command': 'set_link', 'data': {'name': 'str', 'up': 'bool'} }
+
+##
+# @block_passwd:
+#
+# This command sets the password of a block device that has not been open
+# with a password and requires one.
+#
+# The two cases where this can happen are a block device is created through
+# QEMU's initial command line or a block device is changed through the legacy
+# @change interface.
+#
+# In the event that the block device is created through the initial command
+# line, the VM will start in the stopped state regardless of whether '-S' is
+# used.  The intention is for a management tool to query the block devices to
+# determine which ones are encrypted, set the passwords with this command, and
+# then start the guest with the @cont command.
+#
+# @device:   the name of the device to set the password on
+#
+# @password: the password to use for the device
+#
+# Returns: nothing on success
+#          If @device is not a valid block device, DeviceNotFound
+#          If @device is not encrypted, DeviceNotEncrypted
+#
+# Notes:  Not all block formats support encryption and some that do are not
+#         able to validate that a password is correct.  Disk corruption may
+#         occur if an invalid password is specified.
+#
+# Since: 0.14.0
+##
+{ 'command': 'block_passwd', 'data': {'device': 'str', 'password': 'str'} }
+
+##
+# @balloon:
+#
+# Request the balloon driver to change its balloon size.
+#
+# @value: the target size of the balloon in bytes
+#
+# Returns: Nothing on success
+#          If the balloon driver is enabled but not functional because the KVM
+#            kernel module cannot support it, KvmMissingCap
+#          If no balloon device is present, DeviceNotActive
+#
+# Notes: This command just issues a request to the guest.  When it returns,
+#        the balloon size may not have changed.  A guest can change the balloon
+#        size independent of this command.
+#
+# Since: 0.14.0
+##
+{ 'command': 'balloon', 'data': {'value': 'int'} }
+
+##
+# @block_resize
+#
+# Resize a block image while a guest is running.
+#
+# @device:  the name of the device to get the image resized
+#
+# @size:  new image size in bytes
+#
+# Returns: nothing on success
+#          If @device is not a valid block device, DeviceNotFound
+#
+# Since: 0.14.0
+##
+{ 'command': 'block_resize', 'data': { 'device': 'str', 'size': 'int' }}
+
+##
+# @NewImageMode
+#
+# An enumeration that tells QEMU how to set the backing file path in
+# a new image file.
+#
+# @existing: QEMU should look for an existing image file.
+#
+# @absolute-paths: QEMU should create a new image with absolute paths
+# for the backing file. If there is no backing file available, the new
+# image will not be backed either.
+#
+# Since: 1.1
+##
+{ 'enum': 'NewImageMode',
+  'data': [ 'existing', 'absolute-paths' ] }
+
+##
+# @BlockdevSnapshot
+#
+# @device:  the name of the device to generate the snapshot from.
+#
+# @snapshot-file: the target of the new image. A new file will be created.
+#
+# @format: #optional the format of the snapshot image, default is 'qcow2'.
+#
+# @mode: #optional whether and how QEMU should create a new image, default is
+#        'absolute-paths'.
+##
+{ 'type': 'BlockdevSnapshot',
+  'data': { 'device': 'str', 'snapshot-file': 'str', '*format': 'str',
+            '*mode': 'NewImageMode' } }
+
+##
+# @BlockdevSnapshotInternal
+#
+# @device: the name of the device to generate the snapshot from
+#
+# @name: the name of the internal snapshot to be created
+#
+# Notes: In transaction, if @name is empty, or any snapshot matching @name
+#        exists, the operation will fail. Only some image formats support it,
+#        for example, qcow2, rbd, and sheepdog.
+#
+# Since: 1.7
+##
+{ 'type': 'BlockdevSnapshotInternal',
+  'data': { 'device': 'str', 'name': 'str' } }
+
+##
+# @DriveBackup
+#
+# @device: the name of the device which should be copied.
+#
+# @target: the target of the new image. If the file exists, or if it
+#          is a device, the existing file/device will be used as the new
+#          destination.  If it does not exist, a new file will be created.
+#
+# @format: #optional the format of the new destination, default is to
+#          probe if @mode is 'existing', else the format of the source
+#
+# @sync: what parts of the disk image should be copied to the destination
+#        (all the disk, only the sectors allocated in the topmost image, or
+#        only new I/O).
+#
+# @mode: #optional whether and how QEMU should create a new image, default is
+#        'absolute-paths'.
+#
+# @speed: #optional the maximum speed, in bytes per second
+#
+# @on-source-error: #optional the action to take on an error on the source,
+#                   default 'report'.  'stop' and 'enospc' can only be used
+#                   if the block device supports io-status (see BlockInfo).
+#
+# @on-target-error: #optional the action to take on an error on the target,
+#                   default 'report' (no limitations, since this applies to
+#                   a different block device than @device).
+#
+# Note that @on-source-error and @on-target-error only affect background I/O.
+# If an error occurs during a guest write request, the device's rerror/werror
+# actions will be used.
+#
+# Since: 1.6
+##
+{ 'type': 'DriveBackup',
+  'data': { 'device': 'str', 'target': 'str', '*format': 'str',
+            'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
+            '*speed': 'int',
+            '*on-source-error': 'BlockdevOnError',
+            '*on-target-error': 'BlockdevOnError' } }
+
+##
+# @Abort
+#
+# This action can be used to test transaction failure.
+#
+# Since: 1.6
+###
+{ 'type': 'Abort',
+  'data': { } }
+
+##
+# @TransactionAction
+#
+# A discriminated record of operations that can be performed with
+# @transaction.
+##
+{ 'union': 'TransactionAction',
+  'data': {
+       'blockdev-snapshot-sync': 'BlockdevSnapshot',
+       'drive-backup': 'DriveBackup',
+       'abort': 'Abort',
+       'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal'
+   } }
+
+##
+# @transaction
+#
+# Executes a number of transactionable QMP commands atomically. If any
+# operation fails, then the entire set of actions will be abandoned and the
+# appropriate error returned.
+#
+#  List of:
+#  @TransactionAction: information needed for the respective operation
+#
+# Returns: nothing on success
+#          Errors depend on the operations of the transaction
+#
+# Note: The transaction aborts on the first failure.  Therefore, there will be
+# information on only one failed operation returned in an error condition, and
+# subsequent actions will not have been attempted.
+#
+# Since 1.1
+##
+{ 'command': 'transaction',
+  'data': { 'actions': [ 'TransactionAction' ] } }
+
+##
+# @blockdev-snapshot-sync
+#
+# Generates a synchronous snapshot of a block device.
+#
+# For the arguments, see the documentation of BlockdevSnapshot.
+#
+# Returns: nothing on success
+#          If @device is not a valid block device, DeviceNotFound
+#
+# Since 0.14.0
+##
+{ 'command': 'blockdev-snapshot-sync',
+  'data': 'BlockdevSnapshot' }
+
+##
+# @blockdev-snapshot-internal-sync
+#
+# Synchronously take an internal snapshot of a block device, when the format
+# of the image used supports it.
+#
+# For the arguments, see the documentation of BlockdevSnapshotInternal.
+#
+# Returns: nothing on success
+#          If @device is not a valid block device, DeviceNotFound
+#          If any snapshot matching @name exists, or @name is empty,
+#          GenericError
+#          If the format of the image used does not support it,
+#          BlockFormatFeatureNotSupported
+#
+# Since 1.7
+##
+{ 'command': 'blockdev-snapshot-internal-sync',
+  'data': 'BlockdevSnapshotInternal' }
+
+##
+# @blockdev-snapshot-delete-internal-sync
+#
+# Synchronously delete an internal snapshot of a block device, when the format
+# of the image used support it. The snapshot is identified by name or id or
+# both. One of the name or id is required. Return SnapshotInfo for the
+# successfully deleted snapshot.
+#
+# @device: the name of the device to delete the snapshot from
+#
+# @id: optional the snapshot's ID to be deleted
+#
+# @name: optional the snapshot's name to be deleted
+#
+# Returns: SnapshotInfo on success
+#          If @device is not a valid block device, DeviceNotFound
+#          If snapshot not found, GenericError
+#          If the format of the image used does not support it,
+#          BlockFormatFeatureNotSupported
+#          If @id and @name are both not specified, GenericError
+#
+# Since 1.7
+##
+{ 'command': 'blockdev-snapshot-delete-internal-sync',
+  'data': { 'device': 'str', '*id': 'str', '*name': 'str'},
+  'returns': 'SnapshotInfo' }
+
+##
+# @human-monitor-command:
+#
+# Execute a command on the human monitor and return the output.
+#
+# @command-line: the command to execute in the human monitor
+#
+# @cpu-index: #optional The CPU to use for commands that require an implicit CPU
+#
+# Returns: the output of the command as a string
+#
+# Since: 0.14.0
+#
+# Notes: This command only exists as a stop-gap.  Its use is highly
+#        discouraged.  The semantics of this command are not guaranteed.
+#
+#        Known limitations:
+#
+#        o This command is stateless, this means that commands that depend
+#          on state information (such as getfd) might not work
+#
+#       o Commands that prompt the user for data (eg. 'cont' when the block
+#         device is encrypted) don't currently work
+##
+{ 'command': 'human-monitor-command',
+  'data': {'command-line': 'str', '*cpu-index': 'int'},
+  'returns': 'str' }
+
+##
+# @block-commit
+#
+# Live commit of data from overlay image nodes into backing nodes - i.e.,
+# writes data between 'top' and 'base' into 'base'.
+#
+# @device:  the name of the device
+#
+# @base:   #optional The file name of the backing image to write data into.
+#                    If not specified, this is the deepest backing image
+#
+# @top:              The file name of the backing image within the image chain,
+#                    which contains the topmost data to be committed down.
+#                    Note, the active layer as 'top' is currently unsupported.
+#
+#                    If top == base, that is an error.
+#
+#
+# @speed:  #optional the maximum speed, in bytes per second
+#
+# Returns: Nothing on success
+#          If commit or stream is already active on this device, DeviceInUse
+#          If @device does not exist, DeviceNotFound
+#          If image commit is not supported by this device, NotSupported
+#          If @base or @top is invalid, a generic error is returned
+#          If @top is the active layer, or omitted, a generic error is returned
+#          If @speed is invalid, InvalidParameter
+#
+# Since: 1.3
+#
+##
+{ 'command': 'block-commit',
+  'data': { 'device': 'str', '*base': 'str', 'top': 'str',
+            '*speed': 'int' } }
+
+##
+# @drive-backup
+#
+# Start a point-in-time copy of a block device to a new destination.  The
+# status of ongoing drive-backup operations can be checked with
+# query-block-jobs where the BlockJobInfo.type field has the value 'backup'.
+# The operation can be stopped before it has completed using the
+# block-job-cancel command.
+#
+# For the arguments, see the documentation of DriveBackup.
+#
+# Returns: nothing on success
+#          If @device is not a valid block device, DeviceNotFound
+#
+# Since 1.6
+##
+{ 'command': 'drive-backup', 'data': 'DriveBackup' }
+
+##
+# @drive-mirror
+#
+# Start mirroring a block device's writes to a new destination.
+#
+# @device:  the name of the device whose writes should be mirrored.
+#
+# @target: the target of the new image. If the file exists, or if it
+#          is a device, the existing file/device will be used as the new
+#          destination.  If it does not exist, a new file will be created.
+#
+# @format: #optional the format of the new destination, default is to
+#          probe if @mode is 'existing', else the format of the source
+#
+# @mode: #optional whether and how QEMU should create a new image, default is
+#        'absolute-paths'.
+#
+# @speed:  #optional the maximum speed, in bytes per second
+#
+# @sync: what parts of the disk image should be copied to the destination
+#        (all the disk, only the sectors allocated in the topmost image, or
+#        only new I/O).
+#
+# @granularity: #optional granularity of the dirty bitmap, default is 64K
+#               if the image format doesn't have clusters, 4K if the clusters
+#               are smaller than that, else the cluster size.  Must be a
+#               power of 2 between 512 and 64M (since 1.4).
+#
+# @buf-size: #optional maximum amount of data in flight from source to
+#            target (since 1.4).
+#
+# @on-source-error: #optional the action to take on an error on the source,
+#                   default 'report'.  'stop' and 'enospc' can only be used
+#                   if the block device supports io-status (see BlockInfo).
+#
+# @on-target-error: #optional the action to take on an error on the target,
+#                   default 'report' (no limitations, since this applies to
+#                   a different block device than @device).
+#
+# Returns: nothing on success
+#          If @device is not a valid block device, DeviceNotFound
+#
+# Since 1.3
+##
+{ 'command': 'drive-mirror',
+  'data': { 'device': 'str', 'target': 'str', '*format': 'str',
+            'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
+            '*speed': 'int', '*granularity': 'uint32',
+            '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
+            '*on-target-error': 'BlockdevOnError' } }
+
+##
+# @migrate_cancel
+#
+# Cancel the current executing migration process.
+#
+# Returns: nothing on success
+#
+# Notes: This command succeeds even if there is no migration process running.
+#
+# Since: 0.14.0
+##
+{ 'command': 'migrate_cancel' }
+
+##
+# @migrate_set_downtime
+#
+# Set maximum tolerated downtime for migration.
+#
+# @value: maximum downtime in seconds
+#
+# Returns: nothing on success
+#
+# Since: 0.14.0
+##
+{ 'command': 'migrate_set_downtime', 'data': {'value': 'number'} }
+
+##
+# @migrate_set_speed
+#
+# Set maximum speed for migration.
+#
+# @value: maximum speed in bytes.
+#
+# Returns: nothing on success
+#
+# Notes: A value lesser than zero will be automatically round up to zero.
+#
+# Since: 0.14.0
+##
+{ 'command': 'migrate_set_speed', 'data': {'value': 'int'} }
+
+##
+# @migrate-set-cache-size
+#
+# Set XBZRLE cache size
+#
+# @value: cache size in bytes
+#
+# The size will be rounded down to the nearest power of 2.
+# The cache size can be modified before and during ongoing migration
+#
+# Returns: nothing on success
+#
+# Since: 1.2
+##
+{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} }
+
+##
+# @query-migrate-cache-size
+#
+# query XBZRLE cache size
+#
+# Returns: XBZRLE cache size in bytes
+#
+# Since: 1.2
+##
+{ 'command': 'query-migrate-cache-size', 'returns': 'int' }
+
+##
+# @ObjectPropertyInfo:
+#
+# @name: the name of the property
+#
+# @type: the type of the property.  This will typically come in one of four
+#        forms:
+#
+#        1) A primitive type such as 'u8', 'u16', 'bool', 'str', or 'double'.
+#           These types are mapped to the appropriate JSON type.
+#
+#        2) A legacy type in the form 'legacy<subtype>' where subtype is the
+#           legacy qdev typename.  These types are always treated as strings.
+#
+#        3) A child type in the form 'child<subtype>' where subtype is a qdev
+#           device type name.  Child properties create the composition tree.
+#
+#        4) A link type in the form 'link<subtype>' where subtype is a qdev
+#           device type name.  Link properties form the device model graph.
+#
+# Since: 1.2
+##
+{ 'type': 'ObjectPropertyInfo',
+  'data': { 'name': 'str', 'type': 'str' } }
+
+##
+# @qom-list:
+#
+# This command will list any properties of a object given a path in the object
+# model.
+#
+# @path: the path within the object model.  See @qom-get for a description of
+#        this parameter.
+#
+# Returns: a list of @ObjectPropertyInfo that describe the properties of the
+#          object.
+#
+# Since: 1.2
+##
+{ 'command': 'qom-list',
+  'data': { 'path': 'str' },
+  'returns': [ 'ObjectPropertyInfo' ] }
+
+##
+# @qom-get:
+#
+# This command will get a property from a object model path and return the
+# value.
+#
+# @path: The path within the object model.  There are two forms of supported
+#        paths--absolute and partial paths.
+#
+#        Absolute paths are derived from the root object and can follow child<>
+#        or link<> properties.  Since they can follow link<> properties, they
+#        can be arbitrarily long.  Absolute paths look like absolute filenames
+#        and are prefixed  with a leading slash.
+#
+#        Partial paths look like relative filenames.  They do not begin
+#        with a prefix.  The matching rules for partial paths are subtle but
+#        designed to make specifying objects easy.  At each level of the
+#        composition tree, the partial path is matched as an absolute path.
+#        The first match is not returned.  At least two matches are searched
+#        for.  A successful result is only returned if only one match is
+#        found.  If more than one match is found, a flag is return to
+#        indicate that the match was ambiguous.
+#
+# @property: The property name to read
+#
+# Returns: The property value.  The type depends on the property type.  legacy<>
+#          properties are returned as #str.  child<> and link<> properties are
+#          returns as #str pathnames.  All integer property types (u8, u16, etc)
+#          are returned as #int.
+#
+# Since: 1.2
+##
+{ 'command': 'qom-get',
+  'data': { 'path': 'str', 'property': 'str' },
+  'returns': 'visitor',
+  'gen': 'no' }
+
+##
+# @qom-set:
+#
+# This command will set a property from a object model path.
+#
+# @path: see @qom-get for a description of this parameter
+#
+# @property: the property name to set
+#
+# @value: a value who's type is appropriate for the property type.  See @qom-get
+#         for a description of type mapping.
+#
+# Since: 1.2
+##
+{ 'command': 'qom-set',
+  'data': { 'path': 'str', 'property': 'str', 'value': 'visitor' },
+  'gen': 'no' }
+
+##
+# @set_password:
+#
+# Sets the password of a remote display session.
+#
+# @protocol: `vnc' to modify the VNC server password
+#            `spice' to modify the Spice server password
+#
+# @password: the new password
+#
+# @connected: #optional how to handle existing clients when changing the
+#                       password.  If nothing is specified, defaults to `keep'
+#                       `fail' to fail the command if clients are connected
+#                       `disconnect' to disconnect existing clients
+#                       `keep' to maintain existing clients
+#
+# Returns: Nothing on success
+#          If Spice is not enabled, DeviceNotFound
+#
+# Since: 0.14.0
+##
+{ 'command': 'set_password',
+  'data': {'protocol': 'str', 'password': 'str', '*connected': 'str'} }
+
+##
+# @expire_password:
+#
+# Expire the password of a remote display server.
+#
+# @protocol: the name of the remote display protocol `vnc' or `spice'
+#
+# @time: when to expire the password.
+#        `now' to expire the password immediately
+#        `never' to cancel password expiration
+#        `+INT' where INT is the number of seconds from now (integer)
+#        `INT' where INT is the absolute time in seconds
+#
+# Returns: Nothing on success
+#          If @protocol is `spice' and Spice is not active, DeviceNotFound
+#
+# Since: 0.14.0
+#
+# Notes: Time is relative to the server and currently there is no way to
+#        coordinate server time with client time.  It is not recommended to
+#        use the absolute time version of the @time parameter unless you're
+#        sure you are on the same machine as the QEMU instance.
+##
+{ 'command': 'expire_password', 'data': {'protocol': 'str', 'time': 'str'} }
+
+##
+# @eject:
+#
+# Ejects a device from a removable drive.
+#
+# @device:  The name of the device
+#
+# @force:   @optional If true, eject regardless of whether the drive is locked.
+#           If not specified, the default value is false.
+#
+# Returns:  Nothing on success
+#           If @device is not a valid block device, DeviceNotFound
+#
+# Notes:    Ejecting a device will no media results in success
+#
+# Since: 0.14.0
+##
+{ 'command': 'eject', 'data': {'device': 'str', '*force': 'bool'} }
+
+##
+# @change-vnc-password:
+#
+# Change the VNC server password.
+#
+# @target:  the new password to use with VNC authentication
+#
+# Since: 1.1
+#
+# Notes:  An empty password in this command will set the password to the empty
+#         string.  Existing clients are unaffected by executing this command.
+##
+{ 'command': 'change-vnc-password', 'data': {'password': 'str'} }
+
+##
+# @change:
+#
+# This command is multiple commands multiplexed together.
+#
+# @device: This is normally the name of a block device but it may also be 'vnc'.
+#          when it's 'vnc', then sub command depends on @target
+#
+# @target: If @device is a block device, then this is the new filename.
+#          If @device is 'vnc', then if the value 'password' selects the vnc
+#          change password command.   Otherwise, this specifies a new server URI
+#          address to listen to for VNC connections.
+#
+# @arg:    If @device is a block device, then this is an optional format to open
+#          the device with.
+#          If @device is 'vnc' and @target is 'password', this is the new VNC
+#          password to set.  If this argument is an empty string, then no future
+#          logins will be allowed.
+#
+# Returns: Nothing on success.
+#          If @device is not a valid block device, DeviceNotFound
+#          If the new block device is encrypted, DeviceEncrypted.  Note that
+#          if this error is returned, the device has been opened successfully
+#          and an additional call to @block_passwd is required to set the
+#          device's password.  The behavior of reads and writes to the block
+#          device between when these calls are executed is undefined.
+#
+# Notes:  It is strongly recommended that this interface is not used especially
+#         for changing block devices.
+#
+# Since: 0.14.0
+##
+{ 'command': 'change',
+  'data': {'device': 'str', 'target': 'str', '*arg': 'str'} }
+
+##
+# @block_set_io_throttle:
+#
+# Change I/O throttle limits for a block drive.
+#
+# @device: The name of the device
+#
+# @bps: total throughput limit in bytes per second
+#
+# @bps_rd: read throughput limit in bytes per second
+#
+# @bps_wr: write throughput limit in bytes per second
+#
+# @iops: total I/O operations per second
+#
+# @ops_rd: read I/O operations per second
+#
+# @iops_wr: write I/O operations per second
+#
+# @bps_max: #optional total max in bytes (Since 1.7)
+#
+# @bps_rd_max: #optional read max in bytes (Since 1.7)
+#
+# @bps_wr_max: #optional write max in bytes (Since 1.7)
+#
+# @iops_max: #optional total I/O operations max (Since 1.7)
+#
+# @iops_rd_max: #optional read I/O operations max (Since 1.7)
+#
+# @iops_wr_max: #optional write I/O operations max (Since 1.7)
+#
+# @iops_size: #optional an I/O size in bytes (Since 1.7)
+#
+# Returns: Nothing on success
+#          If @device is not a valid block device, DeviceNotFound
+#
+# Since: 1.1
+##
+{ 'command': 'block_set_io_throttle',
+  'data': { 'device': 'str', 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
+            'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
+            '*bps_max': 'int', '*bps_rd_max': 'int',
+            '*bps_wr_max': 'int', '*iops_max': 'int',
+            '*iops_rd_max': 'int', '*iops_wr_max': 'int',
+            '*iops_size': 'int' } }
+
+##
+# @block-stream:
+#
+# Copy data from a backing file into a block device.
+#
+# The block streaming operation is performed in the background until the entire
+# backing file has been copied.  This command returns immediately once streaming
+# has started.  The status of ongoing block streaming operations can be checked
+# with query-block-jobs.  The operation can be stopped before it has completed
+# using the block-job-cancel command.
+#
+# If a base file is specified then sectors are not copied from that base file and
+# its backing chain.  When streaming completes the image file will have the base
+# file as its backing file.  This can be used to stream a subset of the backing
+# file chain instead of flattening the entire image.
+#
+# On successful completion the image file is updated to drop the backing file
+# and the BLOCK_JOB_COMPLETED event is emitted.
+#
+# @device: the device name
+#
+# @base:   #optional the common backing file name
+#
+# @speed:  #optional the maximum speed, in bytes per second
+#
+# @on-error: #optional the action to take on an error (default report).
+#            'stop' and 'enospc' can only be used if the block device
+#            supports io-status (see BlockInfo).  Since 1.3.
+#
+# Returns: Nothing on success
+#          If @device does not exist, DeviceNotFound
+#
+# Since: 1.1
+##
+{ 'command': 'block-stream',
+  'data': { 'device': 'str', '*base': 'str', '*speed': 'int',
+            '*on-error': 'BlockdevOnError' } }
+
+##
+# @block-job-set-speed:
+#
+# Set maximum speed for a background block operation.
+#
+# This command can only be issued when there is an active block job.
+#
+# Throttling can be disabled by setting the speed to 0.
+#
+# @device: the device name
+#
+# @speed:  the maximum speed, in bytes per second, or 0 for unlimited.
+#          Defaults to 0.
+#
+# Returns: Nothing on success
+#          If no background operation is active on this device, DeviceNotActive
+#
+# Since: 1.1
+##
+{ 'command': 'block-job-set-speed',
+  'data': { 'device': 'str', 'speed': 'int' } }
+
+##
+# @block-job-cancel:
+#
+# Stop an active background block operation.
+#
+# This command returns immediately after marking the active background block
+# operation for cancellation.  It is an error to call this command if no
+# operation is in progress.
+#
+# The operation will cancel as soon as possible and then emit the
+# BLOCK_JOB_CANCELLED event.  Before that happens the job is still visible when
+# enumerated using query-block-jobs.
+#
+# For streaming, the image file retains its backing file unless the streaming
+# operation happens to complete just as it is being cancelled.  A new streaming
+# operation can be started at a later time to finish copying all data from the
+# backing file.
+#
+# @device: the device name
+#
+# @force: #optional whether to allow cancellation of a paused job (default
+#         false).  Since 1.3.
+#
+# Returns: Nothing on success
+#          If no background operation is active on this device, DeviceNotActive
+#
+# Since: 1.1
+##
+{ 'command': 'block-job-cancel', 'data': { 'device': 'str', '*force': 'bool' } }
+
+##
+# @block-job-pause:
+#
+# Pause an active background block operation.
+#
+# This command returns immediately after marking the active background block
+# operation for pausing.  It is an error to call this command if no
+# operation is in progress.  Pausing an already paused job has no cumulative
+# effect; a single block-job-resume command will resume the job.
+#
+# The operation will pause as soon as possible.  No event is emitted when
+# the operation is actually paused.  Cancelling a paused job automatically
+# resumes it.
+#
+# @device: the device name
+#
+# Returns: Nothing on success
+#          If no background operation is active on this device, DeviceNotActive
+#
+# Since: 1.3
+##
+{ 'command': 'block-job-pause', 'data': { 'device': 'str' } }
+
+##
+# @block-job-resume:
+#
+# Resume an active background block operation.
+#
+# This command returns immediately after resuming a paused background block
+# operation.  It is an error to call this command if no operation is in
+# progress.  Resuming an already running job is not an error.
+#
+# This command also clears the error status of the job.
+#
+# @device: the device name
+#
+# Returns: Nothing on success
+#          If no background operation is active on this device, DeviceNotActive
+#
+# Since: 1.3
+##
+{ 'command': 'block-job-resume', 'data': { 'device': 'str' } }
+
+##
+# @block-job-complete:
+#
+# Manually trigger completion of an active background block operation.  This
+# is supported for drive mirroring, where it also switches the device to
+# write to the target path only.  The ability to complete is signaled with
+# a BLOCK_JOB_READY event.
+#
+# This command completes an active background block operation synchronously.
+# The ordering of this command's return with the BLOCK_JOB_COMPLETED event
+# is not defined.  Note that if an I/O error occurs during the processing of
+# this command: 1) the command itself will fail; 2) the error will be processed
+# according to the rerror/werror arguments that were specified when starting
+# the operation.
+#
+# A cancelled or paused job cannot be completed.
+#
+# @device: the device name
+#
+# Returns: Nothing on success
+#          If no background operation is active on this device, DeviceNotActive
+#
+# Since: 1.3
+##
+{ 'command': 'block-job-complete', 'data': { 'device': 'str' } }
+
+##
+# @ObjectTypeInfo:
+#
+# This structure describes a search result from @qom-list-types
+#
+# @name: the type name found in the search
+#
+# Since: 1.1
+#
+# Notes: This command is experimental and may change syntax in future releases.
+##
+{ 'type': 'ObjectTypeInfo',
+  'data': { 'name': 'str' } }
+
+##
+# @qom-list-types:
+#
+# This command will return a list of types given search parameters
+#
+# @implements: if specified, only return types that implement this type name
+#
+# @abstract: if true, include abstract types in the results
+#
+# Returns: a list of @ObjectTypeInfo or an empty list if no results are found
+#
+# Since: 1.1
+##
+{ 'command': 'qom-list-types',
+  'data': { '*implements': 'str', '*abstract': 'bool' },
+  'returns': [ 'ObjectTypeInfo' ] }
+
+##
+# @DevicePropertyInfo:
+#
+# Information about device properties.
+#
+# @name: the name of the property
+# @type: the typename of the property
+#
+# Since: 1.2
+##
+{ 'type': 'DevicePropertyInfo',
+  'data': { 'name': 'str', 'type': 'str' } }
+
+##
+# @device-list-properties:
+#
+# List properties associated with a device.
+#
+# @typename: the type name of a device
+#
+# Returns: a list of DevicePropertyInfo describing a devices properties
+#
+# Since: 1.2
+##
+{ 'command': 'device-list-properties',
+  'data': { 'typename': 'str'},
+  'returns': [ 'DevicePropertyInfo' ] }
+
+##
+# @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
+#
+# Since: 1.1
+##
+{ 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} }
+
+##
+# @xen-set-global-dirty-log
+#
+# Enable or disable the global dirty log mode.
+#
+# @enable: true to enable, false to disable.
+#
+# Returns: nothing
+#
+# Since: 1.3
+##
+{ 'command': 'xen-set-global-dirty-log', 'data': { 'enable': 'bool' } }
+
+##
+# @device_del:
+#
+# Remove a device from a guest
+#
+# @id: the name of the device
+#
+# Returns: Nothing on success
+#          If @id is not a valid device, DeviceNotFound
+#
+# Notes: When this command completes, the device may not be removed from the
+#        guest.  Hot removal is an operation that requires guest cooperation.
+#        This command merely requests that the guest begin the hot removal
+#        process.  Completion of the device removal process is signaled with a
+#        DEVICE_DELETED event. Guest reset will automatically complete removal
+#        for all devices.
+#
+# Since: 0.14.0
+##
+{ 'command': 'device_del', 'data': {'id': 'str'} }
+
+##
+# @dump-guest-memory
+#
+# Dump guest's memory to vmcore. It is a synchronous operation that can take
+# very long depending on the amount of guest memory. This command is only
+# supported on i386 and x86_64.
+#
+# @paging: if true, do paging to get guest's memory mapping. This allows
+#          using gdb to process the core file.
+#
+#          IMPORTANT: this option can make QEMU allocate several gigabytes
+#                     of RAM. This can happen for a large guest, or a
+#                     malicious guest pretending to be large.
+#
+#          Also, paging=true has the following limitations:
+#
+#             1. The guest may be in a catastrophic state or can have corrupted
+#                memory, which cannot be trusted
+#             2. The guest can be in real-mode even if paging is enabled. For
+#                example, the guest uses ACPI to sleep, and ACPI sleep state
+#                goes in real-mode
+#
+# @protocol: the filename or file descriptor of the vmcore. The supported
+#            protocols are:
+#
+#            1. file: the protocol starts with "file:", and the following
+#               string is the file's path.
+#            2. fd: the protocol starts with "fd:", and the following string
+#               is the fd's name.
+#
+# @begin: #optional if specified, the starting physical address.
+#
+# @length: #optional if specified, the memory size, in bytes. If you don't
+#          want to dump all guest's memory, please specify the start @begin
+#          and @length
+#
+# Returns: nothing on success
+#
+# Since: 1.2
+##
+{ 'command': 'dump-guest-memory',
+  'data': { 'paging': 'bool', 'protocol': 'str', '*begin': 'int',
+            '*length': 'int' } }
+
+##
+# @netdev_add:
+#
+# Add a network backend.
+#
+# @type: the type of network backend.  Current valid values are 'user', 'tap',
+#        'vde', 'socket', 'dump' and 'bridge'
+#
+# @id: the name of the new network backend
+#
+# @props: #optional a list of properties to be passed to the backend in
+#         the format 'name=value', like 'ifname=tap0,script=no'
+#
+# Notes: The semantics of @props is not well defined.  Future commands will be
+#        introduced that provide stronger typing for backend creation.
+#
+# Since: 0.14.0
+#
+# Returns: Nothing on success
+#          If @type is not a valid network backend, DeviceNotFound
+##
+{ 'command': 'netdev_add',
+  'data': {'type': 'str', 'id': 'str', '*props': '**'},
+  'gen': 'no' }
+
+##
+# @netdev_del:
+#
+# Remove a network backend.
+#
+# @id: the name of the network backend to remove
+#
+# Returns: Nothing on success
+#          If @id is not a valid network backend, DeviceNotFound
+#
+# Since: 0.14.0
+##
+{ 'command': 'netdev_del', 'data': {'id': 'str'} }
+
+##
+# @NetdevNoneOptions
+#
+# Use it alone to have zero network devices.
+#
+# Since 1.2
+##
+{ 'type': 'NetdevNoneOptions',
+  'data': { } }
+
+##
+# @NetLegacyNicOptions
+#
+# Create a new Network Interface Card.
+#
+# @netdev: #optional id of -netdev to connect to
+#
+# @macaddr: #optional MAC address
+#
+# @model: #optional device model (e1000, rtl8139, virtio etc.)
+#
+# @addr: #optional PCI device address
+#
+# @vectors: #optional number of MSI-x vectors, 0 to disable MSI-X
+#
+# Since 1.2
+##
+{ 'type': 'NetLegacyNicOptions',
+  'data': {
+    '*netdev':  'str',
+    '*macaddr': 'str',
+    '*model':   'str',
+    '*addr':    'str',
+    '*vectors': 'uint32' } }
+
+##
+# @String
+#
+# A fat type wrapping 'str', to be embedded in lists.
+#
+# Since 1.2
+##
+{ 'type': 'String',
+  'data': {
+    'str': 'str' } }
+
+##
+# @NetdevUserOptions
+#
+# Use the user mode network stack which requires no administrator privilege to
+# run.
+#
+# @hostname: #optional client hostname reported by the builtin DHCP server
+#
+# @restrict: #optional isolate the guest from the host
+#
+# @ip: #optional legacy parameter, use net= instead
+#
+# @net: #optional IP address and optional netmask
+#
+# @host: #optional guest-visible address of the host
+#
+# @tftp: #optional root directory of the built-in TFTP server
+#
+# @bootfile: #optional BOOTP filename, for use with tftp=
+#
+# @dhcpstart: #optional the first of the 16 IPs the built-in DHCP server can
+#             assign
+#
+# @dns: #optional guest-visible address of the virtual nameserver
+#
+# @dnssearch: #optional list of DNS suffixes to search, passed as DHCP option
+#             to the guest
+#
+# @smb: #optional root directory of the built-in SMB server
+#
+# @smbserver: #optional IP address of the built-in SMB server
+#
+# @hostfwd: #optional redirect incoming TCP or UDP host connections to guest
+#           endpoints
+#
+# @guestfwd: #optional forward guest TCP connections
+#
+# Since 1.2
+##
+{ 'type': 'NetdevUserOptions',
+  'data': {
+    '*hostname':  'str',
+    '*restrict':  'bool',
+    '*ip':        'str',
+    '*net':       'str',
+    '*host':      'str',
+    '*tftp':      'str',
+    '*bootfile':  'str',
+    '*dhcpstart': 'str',
+    '*dns':       'str',
+    '*dnssearch': ['String'],
+    '*smb':       'str',
+    '*smbserver': 'str',
+    '*hostfwd':   ['String'],
+    '*guestfwd':  ['String'] } }
+
+##
+# @NetdevTapOptions
+#
+# Connect the host TAP network interface name to the VLAN.
+#
+# @ifname: #optional interface name
+#
+# @fd: #optional file descriptor of an already opened tap
+#
+# @fds: #optional multiple file descriptors of already opened multiqueue capable
+# tap
+#
+# @script: #optional script to initialize the interface
+#
+# @downscript: #optional script to shut down the interface
+#
+# @helper: #optional command to execute to configure bridge
+#
+# @sndbuf: #optional send buffer limit. Understands [TGMKkb] suffixes.
+#
+# @vnet_hdr: #optional enable the IFF_VNET_HDR flag on the tap interface
+#
+# @vhost: #optional enable vhost-net network accelerator
+#
+# @vhostfd: #optional file descriptor of an already opened vhost net device
+#
+# @vhostfds: #optional file descriptors of multiple already opened vhost net
+# devices
+#
+# @vhostforce: #optional vhost on for non-MSIX virtio guests
+#
+# @queues: #optional number of queues to be created for multiqueue capable tap
+#
+# Since 1.2
+##
+{ 'type': 'NetdevTapOptions',
+  'data': {
+    '*ifname':     'str',
+    '*fd':         'str',
+    '*fds':        'str',
+    '*script':     'str',
+    '*downscript': 'str',
+    '*helper':     'str',
+    '*sndbuf':     'size',
+    '*vnet_hdr':   'bool',
+    '*vhost':      'bool',
+    '*vhostfd':    'str',
+    '*vhostfds':   'str',
+    '*vhostforce': 'bool',
+    '*queues':     'uint32'} }
+
+##
+# @NetdevSocketOptions
+#
+# Connect the VLAN to a remote VLAN in another QEMU virtual machine using a TCP
+# socket connection.
+#
+# @fd: #optional file descriptor of an already opened socket
+#
+# @listen: #optional port number, and optional hostname, to listen on
+#
+# @connect: #optional port number, and optional hostname, to connect to
+#
+# @mcast: #optional UDP multicast address and port number
+#
+# @localaddr: #optional source address and port for multicast and udp packets
+#
+# @udp: #optional UDP unicast address and port number
+#
+# Since 1.2
+##
+{ 'type': 'NetdevSocketOptions',
+  'data': {
+    '*fd':        'str',
+    '*listen':    'str',
+    '*connect':   'str',
+    '*mcast':     'str',
+    '*localaddr': 'str',
+    '*udp':       'str' } }
+
+##
+# @NetdevVdeOptions
+#
+# Connect the VLAN to a vde switch running on the host.
+#
+# @sock: #optional socket path
+#
+# @port: #optional port number
+#
+# @group: #optional group owner of socket
+#
+# @mode: #optional permissions for socket
+#
+# Since 1.2
+##
+{ 'type': 'NetdevVdeOptions',
+  'data': {
+    '*sock':  'str',
+    '*port':  'uint16',
+    '*group': 'str',
+    '*mode':  'uint16' } }
+
+##
+# @NetdevDumpOptions
+#
+# Dump VLAN network traffic to a file.
+#
+# @len: #optional per-packet size limit (64k default). Understands [TGMKkb]
+# suffixes.
+#
+# @file: #optional dump file path (default is qemu-vlan0.pcap)
+#
+# Since 1.2
+##
+{ 'type': 'NetdevDumpOptions',
+  'data': {
+    '*len':  'size',
+    '*file': 'str' } }
+
+##
+# @NetdevBridgeOptions
+#
+# Connect a host TAP network interface to a host bridge device.
+#
+# @br: #optional bridge name
+#
+# @helper: #optional command to execute to configure bridge
+#
+# Since 1.2
+##
+{ 'type': 'NetdevBridgeOptions',
+  'data': {
+    '*br':     'str',
+    '*helper': 'str' } }
+
+##
+# @NetdevHubPortOptions
+#
+# Connect two or more net clients through a software hub.
+#
+# @hubid: hub identifier number
+#
+# Since 1.2
+##
+{ 'type': 'NetdevHubPortOptions',
+  'data': {
+    'hubid':     'int32' } }
+
+##
+# @NetdevNetmapOptions
+#
+# Connect a client to a netmap-enabled NIC or to a VALE switch port
+#
+# @ifname: Either the name of an existing network interface supported by
+#          netmap, or the name of a VALE port (created on the fly).
+#          A VALE port name is in the form 'valeXXX:YYY', where XXX and
+#          YYY are non-negative integers. XXX identifies a switch and
+#          YYY identifies a port of the switch. VALE ports having the
+#          same XXX are therefore connected to the same switch.
+#
+# @devname: #optional path of the netmap device (default: '/dev/netmap').
+#
+# Since 1.8
+##
+{ 'type': 'NetdevNetmapOptions',
+  'data': {
+    'ifname':     'str',
+    '*devname':    'str' } }
+
+##
+# @NetClientOptions
+#
+# A discriminated record of network device traits.
+#
+# Since 1.2
+##
+{ 'union': 'NetClientOptions',
+  'data': {
+    'none':     'NetdevNoneOptions',
+    'nic':      'NetLegacyNicOptions',
+    'user':     'NetdevUserOptions',
+    'tap':      'NetdevTapOptions',
+    'socket':   'NetdevSocketOptions',
+    'vde':      'NetdevVdeOptions',
+    'dump':     'NetdevDumpOptions',
+    'bridge':   'NetdevBridgeOptions',
+    'hubport':  'NetdevHubPortOptions',
+    'netmap':   'NetdevNetmapOptions' } }
+
+##
+# @NetLegacy
+#
+# Captures the configuration of a network device; legacy.
+#
+# @vlan: #optional vlan number
+#
+# @id: #optional identifier for monitor commands
+#
+# @name: #optional identifier for monitor commands, ignored if @id is present
+#
+# @opts: device type specific properties (legacy)
+#
+# Since 1.2
+##
+{ 'type': 'NetLegacy',
+  'data': {
+    '*vlan': 'int32',
+    '*id':   'str',
+    '*name': 'str',
+    'opts':  'NetClientOptions' } }
+
+##
+# @Netdev
+#
+# Captures the configuration of a network device.
+#
+# @id: identifier for monitor commands.
+#
+# @opts: device type specific properties
+#
+# Since 1.2
+##
+{ 'type': 'Netdev',
+  'data': {
+    'id':   'str',
+    'opts': 'NetClientOptions' } }
+
+##
+# @InetSocketAddress
+#
+# Captures a socket address or address range in the Internet namespace.
+#
+# @host: host part of the address
+#
+# @port: port part of the address, or lowest port if @to is present
+#
+# @to: highest port to try
+#
+# @ipv4: whether to accept IPv4 addresses, default try both IPv4 and IPv6
+#        #optional
+#
+# @ipv6: whether to accept IPv6 addresses, default try both IPv4 and IPv6
+#        #optional
+#
+# Since 1.3
+##
+{ 'type': 'InetSocketAddress',
+  'data': {
+    'host': 'str',
+    'port': 'str',
+    '*to': 'uint16',
+    '*ipv4': 'bool',
+    '*ipv6': 'bool' } }
+
+##
+# @UnixSocketAddress
+#
+# Captures a socket address in the local ("Unix socket") namespace.
+#
+# @path: filesystem path to use
+#
+# Since 1.3
+##
+{ 'type': 'UnixSocketAddress',
+  'data': {
+    'path': 'str' } }
+
+##
+# @SocketAddress
+#
+# Captures the address of a socket, which could also be a named file descriptor
+#
+# Since 1.3
+##
+{ 'union': 'SocketAddress',
+  'data': {
+    'inet': 'InetSocketAddress',
+    'unix': 'UnixSocketAddress',
+    'fd': 'String' } }
+
+##
+# @getfd:
+#
+# Receive a file descriptor via SCM rights and assign it a name
+#
+# @fdname: file descriptor name
+#
+# Returns: Nothing on success
+#
+# Since: 0.14.0
+#
+# Notes: If @fdname already exists, the file descriptor assigned to
+#        it will be closed and replaced by the received file
+#        descriptor.
+#        The 'closefd' command can be used to explicitly close the
+#        file descriptor when it is no longer needed.
+##
+{ 'command': 'getfd', 'data': {'fdname': 'str'} }
+
+##
+# @closefd:
+#
+# Close a file descriptor previously passed via SCM rights
+#
+# @fdname: file descriptor name
+#
+# Returns: Nothing on success
+#
+# Since: 0.14.0
+##
+{ 'command': 'closefd', 'data': {'fdname': 'str'} }
+
+##
+# @MachineInfo:
+#
+# Information describing a machine.
+#
+# @name: the name of the machine
+#
+# @alias: #optional an alias for the machine name
+#
+# @default: #optional whether the machine is default
+#
+# @cpu-max: maximum number of CPUs supported by the machine type
+#           (since 1.5.0)
+#
+# Since: 1.2.0
+##
+{ 'type': 'MachineInfo',
+  'data': { 'name': 'str', '*alias': 'str',
+            '*is-default': 'bool', 'cpu-max': 'int' } }
+
+##
+# @query-machines:
+#
+# Return a list of supported machines
+#
+# Returns: a list of MachineInfo
+#
+# Since: 1.2.0
+##
+{ 'command': 'query-machines', 'returns': ['MachineInfo'] }
+
+##
+# @CpuDefinitionInfo:
+#
+# Virtual CPU definition.
+#
+# @name: the name of the CPU definition
+#
+# Since: 1.2.0
+##
+{ 'type': 'CpuDefinitionInfo',
+  'data': { 'name': 'str' } }
+
+##
+# @query-cpu-definitions:
+#
+# Return a list of supported virtual CPU definitions
+#
+# Returns: a list of CpuDefInfo
+#
+# Since: 1.2.0
+##
+{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }
+
+# @AddfdInfo:
+#
+# Information about a file descriptor that was added to an fd set.
+#
+# @fdset-id: The ID of the fd set that @fd was added to.
+#
+# @fd: The file descriptor that was received via SCM rights and
+#      added to the fd set.
+#
+# Since: 1.2.0
+##
+{ 'type': 'AddfdInfo', 'data': {'fdset-id': 'int', 'fd': 'int'} }
+
+##
+# @add-fd:
+#
+# Add a file descriptor, that was passed via SCM rights, to an fd set.
+#
+# @fdset-id: #optional The ID of the fd set to add the file descriptor to.
+#
+# @opaque: #optional A free-form string that can be used to describe the fd.
+#
+# Returns: @AddfdInfo on success
+#          If file descriptor was not received, FdNotSupplied
+#          If @fdset-id is a negative value, InvalidParameterValue
+#
+# Notes: The list of fd sets is shared by all monitor connections.
+#
+#        If @fdset-id is not specified, a new fd set will be created.
+#
+# Since: 1.2.0
+##
+{ 'command': 'add-fd', 'data': {'*fdset-id': 'int', '*opaque': 'str'},
+  'returns': 'AddfdInfo' }
+
+##
+# @remove-fd:
+#
+# Remove a file descriptor from an fd set.
+#
+# @fdset-id: The ID of the fd set that the file descriptor belongs to.
+#
+# @fd: #optional The file descriptor that is to be removed.
+#
+# Returns: Nothing on success
+#          If @fdset-id or @fd is not found, FdNotFound
+#
+# Since: 1.2.0
+#
+# Notes: The list of fd sets is shared by all monitor connections.
+#
+#        If @fd is not specified, all file descriptors in @fdset-id
+#        will be removed.
+##
+{ 'command': 'remove-fd', 'data': {'fdset-id': 'int', '*fd': 'int'} }
+
+##
+# @FdsetFdInfo:
+#
+# Information about a file descriptor that belongs to an fd set.
+#
+# @fd: The file descriptor value.
+#
+# @opaque: #optional A free-form string that can be used to describe the fd.
+#
+# Since: 1.2.0
+##
+{ 'type': 'FdsetFdInfo',
+  'data': {'fd': 'int', '*opaque': 'str'} }
+
+##
+# @FdsetInfo:
+#
+# Information about an fd set.
+#
+# @fdset-id: The ID of the fd set.
+#
+# @fds: A list of file descriptors that belong to this fd set.
+#
+# Since: 1.2.0
+##
+{ 'type': 'FdsetInfo',
+  'data': {'fdset-id': 'int', 'fds': ['FdsetFdInfo']} }
+
+##
+# @query-fdsets:
+#
+# Return information describing all fd sets.
+#
+# Returns: A list of @FdsetInfo
+#
+# Since: 1.2.0
+#
+# Note: The list of fd sets is shared by all monitor connections.
+#
+##
+{ 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
+
+##
+# @TargetInfo:
+#
+# Information describing the QEMU target.
+#
+# @arch: the target architecture (eg "x86_64", "i386", etc)
+#
+# Since: 1.2.0
+##
+{ 'type': 'TargetInfo',
+  'data': { 'arch': 'str' } }
+
+##
+# @query-target:
+#
+# Return information about the target for this QEMU
+#
+# Returns: TargetInfo
+#
+# Since: 1.2.0
+##
+{ 'command': 'query-target', 'returns': 'TargetInfo' }
+
+##
+# @QKeyCode:
+#
+# An enumeration of key name.
+#
+# This is used by the send-key command.
+#
+# Since: 1.3.0
+##
+{ 'enum': 'QKeyCode',
+  'data': [ 'shift', 'shift_r', 'alt', 'alt_r', 'altgr', 'altgr_r', 'ctrl',
+            'ctrl_r', 'menu', 'esc', '1', '2', '3', '4', '5', '6', '7', '8',
+            '9', '0', 'minus', 'equal', 'backspace', 'tab', 'q', 'w', 'e',
+            'r', 't', 'y', 'u', 'i', 'o', 'p', 'bracket_left', 'bracket_right',
+            'ret', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'semicolon',
+            'apostrophe', 'grave_accent', 'backslash', 'z', 'x', 'c', 'v', 'b',
+            'n', 'm', 'comma', 'dot', 'slash', 'asterisk', 'spc', 'caps_lock',
+            'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10',
+            'num_lock', 'scroll_lock', 'kp_divide', 'kp_multiply',
+            'kp_subtract', 'kp_add', 'kp_enter', 'kp_decimal', 'sysrq', 'kp_0',
+            'kp_1', 'kp_2', 'kp_3', 'kp_4', 'kp_5', 'kp_6', 'kp_7', 'kp_8',
+            'kp_9', 'less', 'f11', 'f12', 'print', 'home', 'pgup', 'pgdn', 'end',
+            'left', 'up', 'down', 'right', 'insert', 'delete', 'stop', 'again',
+            'props', 'undo', 'front', 'copy', 'open', 'paste', 'find', 'cut',
+             'lf', 'help', 'meta_l', 'meta_r', 'compose' ] }
+
+##
+# @KeyValue
+#
+# Represents a keyboard key.
+#
+# Since: 1.3.0
+##
+{ 'union': 'KeyValue',
+  'data': {
+    'number': 'int',
+    'qcode': 'QKeyCode' } }
+
+##
+# @send-key:
+#
+# Send keys to guest.
+#
+# @keys: An array of @KeyValue elements. All @KeyValues in this array are
+#        simultaneously sent to the guest. A @KeyValue.number value is sent
+#        directly to the guest, while @KeyValue.qcode must be a valid
+#        @QKeyCode value
+#
+# @hold-time: #optional time to delay key up events, milliseconds. Defaults
+#             to 100
+#
+# Returns: Nothing on success
+#          If key is unknown or redundant, InvalidParameter
+#
+# Since: 1.3.0
+#
+##
+{ 'command': 'send-key',
+  'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } }
+
+##
+# @screendump:
+#
+# Write a PPM of the VGA screen to a file.
+#
+# @filename: the path of a new PPM file to store the image
+#
+# Returns: Nothing on success
+#
+# Since: 0.14.0
+##
+{ 'command': 'screendump', 'data': {'filename': 'str'} }
+
+##
+# @nbd-server-start:
+#
+# Start an NBD server listening on the given host and port.  Block
+# devices can then be exported using @nbd-server-add.  The NBD
+# server will present them as named exports; for example, another
+# QEMU instance could refer to them as "nbd:HOST:PORT:exportname=NAME".
+#
+# @addr: Address on which to listen.
+#
+# Returns: error if the server is already running.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-start',
+  'data': { 'addr': 'SocketAddress' } }
+
+##
+# @nbd-server-add:
+#
+# Export a device to QEMU's embedded NBD server.
+#
+# @device: Block device to be exported
+#
+# @writable: Whether clients should be able to write to the device via the
+#     NBD connection (default false). #optional
+#
+# Returns: error if the device is already marked for export.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-add', 'data': {'device': 'str', '*writable': 'bool'} }
+
+##
+# @nbd-server-stop:
+#
+# Stop QEMU's embedded NBD server, and unregister all devices previously
+# added via @nbd-server-add.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-stop' }
+
+##
+# @ChardevFile:
+#
+# Configuration info for file chardevs.
+#
+# @in:  #optional The name of the input file
+# @out: The name of the output file
+#
+# Since: 1.4
+##
+{ 'type': 'ChardevFile', 'data': { '*in' : 'str',
+                                   'out' : 'str' } }
+
+##
+# @ChardevHostdev:
+#
+# Configuration info for device and pipe chardevs.
+#
+# @device: The name of the special file for the device,
+#          i.e. /dev/ttyS0 on Unix or COM1: on Windows
+# @type: What kind of device this is.
+#
+# Since: 1.4
+##
+{ 'type': 'ChardevHostdev', 'data': { 'device' : 'str' } }
+
+##
+# @ChardevSocket:
+#
+# Configuration info for (stream) socket chardevs.
+#
+# @addr: socket address to listen on (server=true)
+#        or connect to (server=false)
+# @server: #optional create server socket (default: true)
+# @wait: #optional wait for incoming connection on server
+#        sockets (default: false).
+# @nodelay: #optional set TCP_NODELAY socket option (default: false)
+# @telnet: #optional enable telnet protocol on server
+#          sockets (default: false)
+#
+# Since: 1.4
+##
+{ 'type': 'ChardevSocket', 'data': { 'addr'     : 'SocketAddress',
+                                     '*server'  : 'bool',
+                                     '*wait'    : 'bool',
+                                     '*nodelay' : 'bool',
+                                     '*telnet'  : 'bool' } }
+
+##
+# @ChardevUdp:
+#
+# Configuration info for datagram socket chardevs.
+#
+# @remote: remote address
+# @local: #optional local address
+#
+# Since: 1.5
+##
+{ 'type': 'ChardevUdp', 'data': { 'remote' : 'SocketAddress',
+                                  '*local' : 'SocketAddress' } }
+
+##
+# @ChardevMux:
+#
+# Configuration info for mux chardevs.
+#
+# @chardev: name of the base chardev.
+#
+# Since: 1.5
+##
+{ 'type': 'ChardevMux', 'data': { 'chardev' : 'str' } }
+
+##
+# @ChardevStdio:
+#
+# Configuration info for stdio chardevs.
+#
+# @signal: #optional Allow signals (such as SIGINT triggered by ^C)
+#          be delivered to qemu.  Default: true in -nographic mode,
+#          false otherwise.
+#
+# Since: 1.5
+##
+{ 'type': 'ChardevStdio', 'data': { '*signal' : 'bool' } }
+
+##
+# @ChardevSpiceChannel:
+#
+# Configuration info for spice vm channel chardevs.
+#
+# @type: kind of channel (for example vdagent).
+#
+# Since: 1.5
+##
+{ 'type': 'ChardevSpiceChannel', 'data': { 'type'  : 'str' } }
+
+##
+# @ChardevSpicePort:
+#
+# Configuration info for spice port chardevs.
+#
+# @fqdn: name of the channel (see docs/spice-port-fqdn.txt)
+#
+# Since: 1.5
+##
+{ 'type': 'ChardevSpicePort', 'data': { 'fqdn'  : 'str' } }
+
+##
+# @ChardevVC:
+#
+# Configuration info for virtual console chardevs.
+#
+# @width:  console width,  in pixels
+# @height: console height, in pixels
+# @cols:   console width,  in chars
+# @rows:   console height, in chars
+#
+# Since: 1.5
+##
+{ 'type': 'ChardevVC', 'data': { '*width'  : 'int',
+                                 '*height' : 'int',
+                                 '*cols'   : 'int',
+                                 '*rows'   : 'int' } }
+
+##
+# @ChardevRingbuf:
+#
+# Configuration info for ring buffer chardevs.
+#
+# @size: #optional ring buffer size, must be power of two, default is 65536
+#
+# Since: 1.5
+##
+{ 'type': 'ChardevRingbuf', 'data': { '*size'  : 'int' } }
+
+##
+# @ChardevBackend:
+#
+# Configuration info for the new chardev backend.
+#
+# Since: 1.4
+##
+{ 'type': 'ChardevDummy', 'data': { } }
+
+{ 'union': 'ChardevBackend', 'data': { 'file'   : 'ChardevFile',
+                                       'serial' : 'ChardevHostdev',
+                                       'parallel': 'ChardevHostdev',
+                                       'pipe'   : 'ChardevHostdev',
+                                       'socket' : 'ChardevSocket',
+                                       'udp'    : 'ChardevUdp',
+                                       'pty'    : 'ChardevDummy',
+                                       'null'   : 'ChardevDummy',
+                                       'mux'    : 'ChardevMux',
+                                       'msmouse': 'ChardevDummy',
+                                       'braille': 'ChardevDummy',
+                                       'stdio'  : 'ChardevStdio',
+                                       'console': 'ChardevDummy',
+                                       'spicevmc' : 'ChardevSpiceChannel',
+                                       'spiceport' : 'ChardevSpicePort',
+                                       'vc'     : 'ChardevVC',
+                                       'ringbuf': 'ChardevRingbuf',
+                                       # next one is just for compatibility
+                                       'memory' : 'ChardevRingbuf' } }
+
+##
+# @ChardevReturn:
+#
+# Return info about the chardev backend just created.
+#
+# @pty: #optional name of the slave pseudoterminal device, present if
+#       and only if a chardev of type 'pty' was created
+#
+# Since: 1.4
+##
+{ 'type' : 'ChardevReturn', 'data': { '*pty' : 'str' } }
+
+##
+# @chardev-add:
+#
+# Add a character device backend
+#
+# @id: the chardev's ID, must be unique
+# @backend: backend type and parameters
+#
+# Returns: ChardevReturn.
+#
+# Since: 1.4
+##
+{ 'command': 'chardev-add', 'data': {'id'      : 'str',
+                                     'backend' : 'ChardevBackend' },
+  'returns': 'ChardevReturn' }
+
+##
+# @chardev-remove:
+#
+# Remove a character device backend
+#
+# @id: the chardev's ID, must exist and not be in use
+#
+# Returns: Nothing on success
+#
+# Since: 1.4
+##
+{ 'command': 'chardev-remove', 'data': {'id': 'str'} }
+
+##
+# @TpmModel:
+#
+# An enumeration of TPM models
+#
+# @tpm-tis: TPM TIS model
+#
+# Since: 1.5
+##
+{ 'enum': 'TpmModel', 'data': [ 'tpm-tis' ] }
+
+##
+# @query-tpm-models:
+#
+# Return a list of supported TPM models
+#
+# Returns: a list of TpmModel
+#
+# Since: 1.5
+##
+{ 'command': 'query-tpm-models', 'returns': ['TpmModel'] }
+
+##
+# @TpmType:
+#
+# An enumeration of TPM types
+#
+# @passthrough: TPM passthrough type
+#
+# Since: 1.5
+##
+{ 'enum': 'TpmType', 'data': [ 'passthrough' ] }
+
+##
+# @query-tpm-types:
+#
+# Return a list of supported TPM types
+#
+# Returns: a list of TpmType
+#
+# Since: 1.5
+##
+{ 'command': 'query-tpm-types', 'returns': ['TpmType'] }
+
+##
+# @TPMPassthroughOptions:
+#
+# Information about the TPM passthrough type
+#
+# @path: #optional string describing the path used for accessing the TPM device
+#
+# @cancel-path: #optional string showing the TPM's sysfs cancel file
+#               for cancellation of TPM commands while they are executing
+#
+# Since: 1.5
+##
+{ 'type': 'TPMPassthroughOptions', 'data': { '*path' : 'str',
+                                             '*cancel-path' : 'str'} }
+
+##
+# @TpmTypeOptions:
+#
+# A union referencing different TPM backend types' configuration options
+#
+# @passthrough: The configuration options for the TPM passthrough type
+#
+# Since: 1.5
+##
+{ 'union': 'TpmTypeOptions',
+   'data': { 'passthrough' : 'TPMPassthroughOptions' } }
+
+##
+# @TpmInfo:
+#
+# Information about the TPM
+#
+# @id: The Id of the TPM
+#
+# @model: The TPM frontend model
+#
+# @options: The TPM (backend) type configuration options
+#
+# Since: 1.5
+##
+{ 'type': 'TPMInfo',
+  'data': {'id': 'str',
+           'model': 'TpmModel',
+           'options': 'TpmTypeOptions' } }
+
+##
+# @query-tpm:
+#
+# Return information about the TPM device
+#
+# Returns: @TPMInfo on success
+#
+# Since: 1.5
+##
+{ 'command': 'query-tpm', 'returns': ['TPMInfo'] }
+
+##
+# @AcpiTableOptions
+#
+# Specify an ACPI table on the command line to load.
+#
+# At most one of @file and @data can be specified. The list of files specified
+# by any one of them is loaded and concatenated in order. If both are omitted,
+# @data is implied.
+#
+# Other fields / optargs can be used to override fields of the generic ACPI
+# table header; refer to the ACPI specification 5.0, section 5.2.6 System
+# Description Table Header. If a header field is not overridden, then the
+# corresponding value from the concatenated blob is used (in case of @file), or
+# it is filled in with a hard-coded value (in case of @data).
+#
+# String fields are copied into the matching ACPI member from lowest address
+# upwards, and silently truncated / NUL-padded to length.
+#
+# @sig: #optional table signature / identifier (4 bytes)
+#
+# @rev: #optional table revision number (dependent on signature, 1 byte)
+#
+# @oem_id: #optional OEM identifier (6 bytes)
+#
+# @oem_table_id: #optional OEM table identifier (8 bytes)
+#
+# @oem_rev: #optional OEM-supplied revision number (4 bytes)
+#
+# @asl_compiler_id: #optional identifier of the utility that created the table
+#                   (4 bytes)
+#
+# @asl_compiler_rev: #optional revision number of the utility that created the
+#                    table (4 bytes)
+#
+# @file: #optional colon (:) separated list of pathnames to load and
+#        concatenate as table data. The resultant binary blob is expected to
+#        have an ACPI table header. At least one file is required. This field
+#        excludes @data.
+#
+# @data: #optional colon (:) separated list of pathnames to load and
+#        concatenate as table data. The resultant binary blob must not have an
+#        ACPI table header. At least one file is required. This field excludes
+#        @file.
+#
+# Since 1.5
+##
+{ 'type': 'AcpiTableOptions',
+  'data': {
+    '*sig':               'str',
+    '*rev':               'uint8',
+    '*oem_id':            'str',
+    '*oem_table_id':      'str',
+    '*oem_rev':           'uint32',
+    '*asl_compiler_id':   'str',
+    '*asl_compiler_rev':  'uint32',
+    '*file':              'str',
+    '*data':              'str' }}
+
+##
+# @CommandLineParameterType:
+#
+# Possible types for an option parameter.
+#
+# @string: accepts a character string
+#
+# @boolean: accepts "on" or "off"
+#
+# @number: accepts a number
+#
+# @size: accepts a number followed by an optional suffix (K)ilo,
+#        (M)ega, (G)iga, (T)era
+#
+# Since 1.5
+##
+{ 'enum': 'CommandLineParameterType',
+  'data': ['string', 'boolean', 'number', 'size'] }
+
+##
+# @CommandLineParameterInfo:
+#
+# Details about a single parameter of a command line option.
+#
+# @name: parameter name
+#
+# @type: parameter @CommandLineParameterType
+#
+# @help: #optional human readable text string, not suitable for parsing.
+#
+# Since 1.5
+##
+{ 'type': 'CommandLineParameterInfo',
+  'data': { 'name': 'str',
+            'type': 'CommandLineParameterType',
+            '*help': 'str' } }
+
+##
+# @CommandLineOptionInfo:
+#
+# Details about a command line option, including its list of parameter details
+#
+# @option: option name
+#
+# @parameters: an array of @CommandLineParameterInfo
+#
+# Since 1.5
+##
+{ 'type': 'CommandLineOptionInfo',
+  'data': { 'option': 'str', 'parameters': ['CommandLineParameterInfo'] } }
+
+##
+# @query-command-line-options:
+#
+# Query command line option schema.
+#
+# @option: #optional option name
+#
+# Returns: list of @CommandLineOptionInfo for all options (or for the given
+#          @option).  Returns an error if the given @option doesn't exist.
+#
+# Since 1.5
+##
+{'command': 'query-command-line-options', 'data': { '*option': 'str' },
+ 'returns': ['CommandLineOptionInfo'] }
+
+##
+# @X86CPURegister32
+#
+# A X86 32-bit register
+#
+# Since: 1.5
+##
+{ 'enum': 'X86CPURegister32',
+  'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ] }
+
+##
+# @X86CPUFeatureWordInfo
+#
+# Information about a X86 CPU feature word
+#
+# @cpuid-input-eax: Input EAX value for CPUID instruction for that feature word
+#
+# @cpuid-input-ecx: #optional Input ECX value for CPUID instruction for that
+#                   feature word
+#
+# @cpuid-register: Output register containing the feature bits
+#
+# @features: value of output register, containing the feature bits
+#
+# Since: 1.5
+##
+{ 'type': 'X86CPUFeatureWordInfo',
+  'data': { 'cpuid-input-eax': 'int',
+            '*cpuid-input-ecx': 'int',
+            'cpuid-register': 'X86CPURegister32',
+            'features': 'int' } }
+
+##
+# @RxState:
+#
+# Packets receiving state
+#
+# @normal: filter assigned packets according to the mac-table
+#
+# @none: don't receive any assigned packet
+#
+# @all: receive all assigned packets
+#
+# Since: 1.6
+##
+{ 'enum': 'RxState', 'data': [ 'normal', 'none', 'all' ] }
+
+##
+# @RxFilterInfo:
+#
+# Rx-filter information for a NIC.
+#
+# @name: net client name
+#
+# @promiscuous: whether promiscuous mode is enabled
+#
+# @multicast: multicast receive state
+#
+# @unicast: unicast receive state
+#
+# @broadcast-allowed: whether to receive broadcast
+#
+# @multicast-overflow: multicast table is overflowed or not
+#
+# @unicast-overflow: unicast table is overflowed or not
+#
+# @main-mac: the main macaddr string
+#
+# @vlan-table: a list of active vlan id
+#
+# @unicast-table: a list of unicast macaddr string
+#
+# @multicast-table: a list of multicast macaddr string
+#
+# Since 1.6
+##
+
+{ 'type': 'RxFilterInfo',
+  'data': {
+    'name':               'str',
+    'promiscuous':        'bool',
+    'multicast':          'RxState',
+    'unicast':            'RxState',
+    'broadcast-allowed':  'bool',
+    'multicast-overflow': 'bool',
+    'unicast-overflow':   'bool',
+    'main-mac':           'str',
+    'vlan-table':         ['int'],
+    'unicast-table':      ['str'],
+    'multicast-table':    ['str'] }}
+
+##
+# @query-rx-filter:
+#
+# Return rx-filter information for all NICs (or for the given NIC).
+#
+# @name: #optional net client name
+#
+# Returns: list of @RxFilterInfo for all NICs (or for the given NIC).
+#          Returns an error if the given @name doesn't exist, or given
+#          NIC doesn't support rx-filter querying, or given net client
+#          isn't a NIC.
+#
+# Since: 1.6
+##
+{ 'command': 'query-rx-filter', 'data': { '*name': 'str' },
+  'returns': ['RxFilterInfo'] }
+
+
+##
+# @BlockdevDiscardOptions
+#
+# Determines how to handle discard requests.
+#
+# @ignore:      Ignore the request
+# @unmap:       Forward as an unmap request
+#
+# Since: 1.7
+##
+{ 'enum': 'BlockdevDiscardOptions',
+  'data': [ 'ignore', 'unmap' ] }
+
+##
+# @BlockdevAioOptions
+#
+# Selects the AIO backend to handle I/O requests
+#
+# @threads:     Use qemu's thread pool
+# @native:      Use native AIO backend (only Linux and Windows)
+#
+# Since: 1.7
+##
+{ 'enum': 'BlockdevAioOptions',
+  'data': [ 'threads', 'native' ] }
+
+##
+# @BlockdevCacheOptions
+#
+# Includes cache-related options for block devices
+#
+# @writeback:   #optional enables writeback mode for any caches (default: true)
+# @direct:      #optional enables use of O_DIRECT (bypass the host page cache;
+#               default: false)
+# @no-flush:    #optional ignore any flush requests for the device (default:
+#               false)
+#
+# Since: 1.7
+##
+{ 'type': 'BlockdevCacheOptions',
+  'data': { '*writeback': 'bool',
+            '*direct': 'bool',
+            '*no-flush': 'bool' } }
+
+##
+# @BlockdevOptionsBase
+#
+# Options that are available for all block devices, independent of the block
+# driver.
+#
+# @driver:      block driver name
+# @id:          #optional id by which the new block device can be referred to.
+#               This is a required option on the top level of blockdev-add, and
+#               currently not allowed on any other level.
+# @discard:     #optional discard-related options (default: ignore)
+# @cache:       #optional cache-related options
+# @aio:         #optional AIO backend (default: threads)
+# @rerror:      #optional how to handle read errors on the device
+#               (default: report)
+# @werror:      #optional how to handle write errors on the device
+#               (default: enospc)
+# @read-only:   #optional whether the block device should be read-only
+#               (default: false)
+#
+# Since: 1.7
+##
+{ 'type': 'BlockdevOptionsBase',
+  'data': { 'driver': 'str',
+            '*id': 'str',
+            '*discard': 'BlockdevDiscardOptions',
+            '*cache': 'BlockdevCacheOptions',
+            '*aio': 'BlockdevAioOptions',
+            '*rerror': 'BlockdevOnError',
+            '*werror': 'BlockdevOnError',
+            '*read-only': 'bool' } }
+
+##
+# @BlockdevOptionsFile
+#
+# Driver specific block device options for the file backend and similar
+# protocols.
+#
+# @filename:    path to the image file
+#
+# Since: 1.7
+##
+{ 'type': 'BlockdevOptionsFile',
+  'data': { 'filename': 'str' } }
+
+##
+# @BlockdevOptionsVVFAT
+#
+# Driver specific block device options for the vvfat protocol.
+#
+# @dir:         directory to be exported as FAT image
+# @fat-type:    #optional FAT type: 12, 16 or 32
+# @floppy:      #optional whether to export a floppy image (true) or
+#               partitioned hard disk (false; default)
+# @rw:          #optional whether to allow write operations (default: false)
+#
+# Since: 1.7
+##
+{ 'type': 'BlockdevOptionsVVFAT',
+  'data': { 'dir': 'str', '*fat-type': 'int', '*floppy': 'bool',
+            '*rw': 'bool' } }
+
+##
+# @BlockdevOptionsGenericFormat
+#
+# Driver specific block device options for image format that have no option
+# besides their data source.
+#
+# @file:        reference to or definition of the data source block device
+#
+# Since: 1.7
+##
+{ 'type': 'BlockdevOptionsGenericFormat',
+  'data': { 'file': 'BlockdevRef' } }
+
+##
+# @BlockdevOptionsGenericCOWFormat
+#
+# Driver specific block device options for image format that have no option
+# besides their data source and an optional backing file.
+#
+# @backing:     #optional reference to or definition of the backing file block
+#               device (if missing, taken from the image file content). It is
+#               allowed to pass an empty string here in order to disable the
+#               default backing file.
+#
+# Since: 1.7
+##
+{ 'type': 'BlockdevOptionsGenericCOWFormat',
+  'base': 'BlockdevOptionsGenericFormat',
+  'data': { '*backing': 'BlockdevRef' } }
+
+##
+# @BlockdevOptionsQcow2
+#
+# Driver specific block device options for qcow2.
+#
+# @lazy-refcounts:        #optional whether to enable the lazy refcounts
+#                         feature (default is taken from the image file)
+#
+# @pass-discard-request:  #optional whether discard requests to the qcow2
+#                         device should be forwarded to the data source
+#
+# @pass-discard-snapshot: #optional whether discard requests for the data source
+#                         should be issued when a snapshot operation (e.g.
+#                         deleting a snapshot) frees clusters in the qcow2 file
+#
+# @pass-discard-other:    #optional whether discard requests for the data source
+#                         should be issued on other occasions where a cluster
+#                         gets freed
+#
+# Since: 1.7
+##
+{ 'type': 'BlockdevOptionsQcow2',
+  'base': 'BlockdevOptionsGenericCOWFormat',
+  'data': { '*lazy-refcounts': 'bool',
+            '*pass-discard-request': 'bool',
+            '*pass-discard-snapshot': 'bool',
+            '*pass-discard-other': 'bool' } }
+
+##
+# @BlockdevOptions
+#
+# Options for creating a block device.
+#
+# Since: 1.7
+##
+{ 'union': 'BlockdevOptions',
+  'base': 'BlockdevOptionsBase',
+  'discriminator': 'driver',
+  'data': {
+      'file':       'BlockdevOptionsFile',
+      'http':       'BlockdevOptionsFile',
+      'https':      'BlockdevOptionsFile',
+      'ftp':        'BlockdevOptionsFile',
+      'ftps':       'BlockdevOptionsFile',
+      'tftp':       'BlockdevOptionsFile',
+# TODO gluster: Wait for structured options
+# TODO iscsi: Wait for structured options
+# TODO nbd: Should take InetSocketAddress for 'host'?
+# TODO rbd: Wait for structured options
+# TODO sheepdog: Wait for structured options
+# TODO ssh: Should take InetSocketAddress for 'host'?
+      'vvfat':      'BlockdevOptionsVVFAT',
+
+# TODO blkdebug: Wait for structured options
+# TODO blkverify: Wait for structured options
+
+      'bochs':      'BlockdevOptionsGenericFormat',
+      'cloop':      'BlockdevOptionsGenericFormat',
+      'cow':        'BlockdevOptionsGenericCOWFormat',
+      'dmg':        'BlockdevOptionsGenericFormat',
+      'parallels':  'BlockdevOptionsGenericFormat',
+      'qcow':       'BlockdevOptionsGenericCOWFormat',
+      'qcow2':      'BlockdevOptionsQcow2',
+      'qed':        'BlockdevOptionsGenericCOWFormat',
+      'raw':        'BlockdevOptionsGenericFormat',
+      'vdi':        'BlockdevOptionsGenericFormat',
+      'vhdx':       'BlockdevOptionsGenericFormat',
+      'vmdk':       'BlockdevOptionsGenericCOWFormat',
+      'vpc':        'BlockdevOptionsGenericFormat'
+  } }
+
+##
+# @BlockdevRef
+#
+# Reference to a block device.
+#
+# @definition:      defines a new block device inline
+# @reference:       references the ID of an existing block device. An
+#                   empty string means that no block device should be
+#                   referenced.
+#
+# Since: 1.7
+##
+{ 'union': 'BlockdevRef',
+  'discriminator': {},
+  'data': { 'definition': 'BlockdevOptions',
+            'reference': 'str' } }
+
+##
+# @blockdev-add:
+#
+# Creates a new block device.
+#
+# @options: block device options for the new device
+#
+# Since: 1.7
+##
+{ 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
diff --git a/qemu-io.c b/qemu-io.c
deleted file mode 100644
index 0c1ab3e..0000000
--- a/qemu-io.c
+++ /dev/null
@@ -1,1836 +0,0 @@
-/*
- * Command line utility to exercise the QEMU I/O path.
- *
- * Copyright (C) 2009 Red Hat, Inc.
- * Copyright (c) 2003-2005 Silicon Graphics, Inc.
- *
- * 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 <sys/time.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <getopt.h>
-#include <libgen.h>
-
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "cmd.h"
-
-#define VERSION	"0.0.1"
-
-#define CMD_NOFILE_OK	0x01
-
-char *progname;
-static BlockDriverState *bs;
-
-static int misalign;
-
-/*
- * Parse the pattern argument to various sub-commands.
- *
- * Because the pattern is used as an argument to memset it must evaluate
- * to an unsigned integer that fits into a single byte.
- */
-static int parse_pattern(const char *arg)
-{
-	char *endptr = NULL;
-	long pattern;
-
-	pattern = strtol(arg, &endptr, 0);
-	if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
-		printf("%s is not a valid pattern byte\n", arg);
-		return -1;
-	}
-
-	return pattern;
-}
-
-/*
- * Memory allocation helpers.
- *
- * Make sure memory is aligned by default, or purposefully misaligned if
- * that is specified on the command line.
- */
-
-#define MISALIGN_OFFSET		16
-static void *qemu_io_alloc(size_t len, int pattern)
-{
-	void *buf;
-
-	if (misalign)
-		len += MISALIGN_OFFSET;
-	buf = qemu_blockalign(bs, len);
-	memset(buf, pattern, len);
-	if (misalign)
-		buf += MISALIGN_OFFSET;
-	return buf;
-}
-
-static void qemu_io_free(void *p)
-{
-	if (misalign)
-		p -= MISALIGN_OFFSET;
-	qemu_vfree(p);
-}
-
-static void
-dump_buffer(const void *buffer, int64_t offset, int len)
-{
-	int i, j;
-	const uint8_t *p;
-
-	for (i = 0, p = buffer; i < len; i += 16) {
-		const uint8_t *s = p;
-
-                printf("%08" PRIx64 ":  ", offset + i);
-		for (j = 0; j < 16 && i + j < len; j++, p++)
-			printf("%02x ", *p);
-		printf(" ");
-		for (j = 0; j < 16 && i + j < len; j++, s++) {
-			if (isalnum(*s))
-				printf("%c", *s);
-			else
-				printf(".");
-		}
-		printf("\n");
-	}
-}
-
-static void
-print_report(const char *op, struct timeval *t, int64_t offset,
-		int count, int total, int cnt, int Cflag)
-{
-	char s1[64], s2[64], ts[64];
-
-	timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
-	if (!Cflag) {
-		cvtstr((double)total, s1, sizeof(s1));
-		cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
-                printf("%s %d/%d bytes at offset %" PRId64 "\n",
-                       op, total, count, offset);
-		printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
-			s1, cnt, ts, s2, tdiv((double)cnt, *t));
-	} else {/* bytes,ops,time,bytes/sec,ops/sec */
-		printf("%d,%d,%s,%.3f,%.3f\n",
-			total, cnt, ts,
-			tdiv((double)total, *t),
-			tdiv((double)cnt, *t));
-	}
-}
-
-/*
- * Parse multiple length statements for vectored I/O, and construct an I/O
- * vector matching it.
- */
-static void *
-create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
-{
-	size_t *sizes = calloc(nr_iov, sizeof(size_t));
-	size_t count = 0;
-	void *buf = NULL;
-	void *p;
-	int i;
-
-	for (i = 0; i < nr_iov; i++) {
-		char *arg = argv[i];
-                int64_t len;
-
-		len = cvtnum(arg);
-		if (len < 0) {
-			printf("non-numeric length argument -- %s\n", arg);
-			goto fail;
-		}
-
-		/* should be SIZE_T_MAX, but that doesn't exist */
-		if (len > INT_MAX) {
-			printf("too large length argument -- %s\n", arg);
-			goto fail;
-		}
-
-		if (len & 0x1ff) {
-                        printf("length argument %" PRId64
-                               " is not sector aligned\n", len);
-			goto fail;
-		}
-
-		sizes[i] = len;
-		count += len;
-	}
-
-	qemu_iovec_init(qiov, nr_iov);
-
-	buf = p = qemu_io_alloc(count, pattern);
-
-	for (i = 0; i < nr_iov; i++) {
-		qemu_iovec_add(qiov, p, sizes[i]);
-		p += sizes[i];
-	}
-
-fail:
-	free(sizes);
-	return buf;
-}
-
-static int do_read(char *buf, int64_t offset, int count, int *total)
-{
-	int ret;
-
-	ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
-	if (ret < 0)
-		return ret;
-	*total = count;
-	return 1;
-}
-
-static int do_write(char *buf, int64_t offset, int count, int *total)
-{
-	int ret;
-
-	ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
-	if (ret < 0)
-		return ret;
-	*total = count;
-	return 1;
-}
-
-static int do_pread(char *buf, int64_t offset, int count, int *total)
-{
-	*total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
-	if (*total < 0)
-		return *total;
-	return 1;
-}
-
-static int do_pwrite(char *buf, int64_t offset, int count, int *total)
-{
-	*total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
-	if (*total < 0)
-		return *total;
-	return 1;
-}
-
-static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)
-{
-	*total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
-	if (*total < 0)
-		return *total;
-	return 1;
-}
-
-static int do_save_vmstate(char *buf, int64_t offset, int count, int *total)
-{
-	*total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
-	if (*total < 0)
-		return *total;
-	return 1;
-}
-
-#define NOT_DONE 0x7fffffff
-static void aio_rw_done(void *opaque, int ret)
-{
-	*(int *)opaque = ret;
-}
-
-static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
-{
-	BlockDriverAIOCB *acb;
-	int async_ret = NOT_DONE;
-
-	acb = bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
-			     aio_rw_done, &async_ret);
-	if (!acb)
-		return -EIO;
-
-	while (async_ret == NOT_DONE)
-		qemu_aio_wait();
-
-	*total = qiov->size;
-	return async_ret < 0 ? async_ret : 1;
-}
-
-static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total)
-{
-	BlockDriverAIOCB *acb;
-	int async_ret = NOT_DONE;
-
-	acb = bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
-			      aio_rw_done, &async_ret);
-	if (!acb)
-		return -EIO;
-
-	while (async_ret == NOT_DONE)
-		qemu_aio_wait();
-
-	*total = qiov->size;
-	return async_ret < 0 ? async_ret : 1;
-}
-
-struct multiwrite_async_ret {
-	int num_done;
-	int error;
-};
-
-static void multiwrite_cb(void *opaque, int ret)
-{
-	struct multiwrite_async_ret *async_ret = opaque;
-
-	async_ret->num_done++;
-	if (ret < 0) {
-		async_ret->error = ret;
-	}
-}
-
-static int do_aio_multiwrite(BlockRequest* reqs, int num_reqs, int *total)
-{
-	int i, ret;
-	struct multiwrite_async_ret async_ret = {
-		.num_done = 0,
-		.error = 0,
-	};
-
-	*total = 0;
-	for (i = 0; i < num_reqs; i++) {
-		reqs[i].cb = multiwrite_cb;
-		reqs[i].opaque = &async_ret;
-		*total += reqs[i].qiov->size;
-	}
-
-	ret = bdrv_aio_multiwrite(bs, reqs, num_reqs);
-	if (ret < 0) {
-		return ret;
-	}
-
-	while (async_ret.num_done < num_reqs) {
-		qemu_aio_wait();
-	}
-
-	return async_ret.error < 0 ? async_ret.error : 1;
-}
-
-static void
-read_help(void)
-{
-	printf(
-"\n"
-" reads a range of bytes from the given offset\n"
-"\n"
-" Example:\n"
-" 'read -v 512 1k' - dumps 1 kilobyte read from 512 bytes into the file\n"
-"\n"
-" Reads a segment of the currently open file, optionally dumping it to the\n"
-" standard output stream (with -v option) for subsequent inspection.\n"
-" -b, -- read from the VM state rather than the virtual disk\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -l, -- length for pattern verification (only with -P)\n"
-" -p, -- use bdrv_pread to read the file\n"
-" -P, -- use a pattern to verify read data\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-" -s, -- start offset for pattern verification (only with -P)\n"
-" -v, -- dump buffer to standard output\n"
-"\n");
-}
-
-static int read_f(int argc, char **argv);
-
-static const cmdinfo_t read_cmd = {
-	.name		= "read",
-	.altname	= "r",
-	.cfunc		= read_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
-	.oneline	= "reads a number of bytes at a specified offset",
-	.help		= read_help,
-};
-
-static int
-read_f(int argc, char **argv)
-{
-	struct timeval t1, t2;
-	int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
-	int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
-	int c, cnt;
-	char *buf;
-	int64_t offset;
-	int count;
-        /* Some compilers get confused and warn if this is not initialized.  */
-        int total = 0;
-	int pattern = 0, pattern_offset = 0, pattern_count = 0;
-
-	while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
-		switch (c) {
-		case 'b':
-			bflag = 1;
-			break;
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'l':
-			lflag = 1;
-			pattern_count = cvtnum(optarg);
-			if (pattern_count < 0) {
-				printf("non-numeric length argument -- %s\n", optarg);
-				return 0;
-			}
-			break;
-		case 'p':
-			pflag = 1;
-			break;
-		case 'P':
-			Pflag = 1;
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		case 's':
-			sflag = 1;
-			pattern_offset = cvtnum(optarg);
-			if (pattern_offset < 0) {
-				printf("non-numeric length argument -- %s\n", optarg);
-				return 0;
-			}
-			break;
-		case 'v':
-			vflag = 1;
-			break;
-		default:
-			return command_usage(&read_cmd);
-		}
-	}
-
-	if (optind != argc - 2)
-		return command_usage(&read_cmd);
-
-	if (bflag && pflag) {
-		printf("-b and -p cannot be specified at the same time\n");
-		return 0;
-	}
-
-	offset = cvtnum(argv[optind]);
-	if (offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-
-	optind++;
-	count = cvtnum(argv[optind]);
-	if (count < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-
-    if (!Pflag && (lflag || sflag)) {
-        return command_usage(&read_cmd);
-    }
-
-    if (!lflag) {
-        pattern_count = count - pattern_offset;
-    }
-
-    if ((pattern_count < 0) || (pattern_count + pattern_offset > count))  {
-        printf("pattern verfication range exceeds end of read data\n");
-        return 0;
-    }
-
-	if (!pflag)
-		if (offset & 0x1ff) {
-                        printf("offset %" PRId64 " is not sector aligned\n",
-                               offset);
-			return 0;
-
-		if (count & 0x1ff) {
-			printf("count %d is not sector aligned\n",
-				count);
-			return 0;
-		}
-	}
-
-	buf = qemu_io_alloc(count, 0xab);
-
-	gettimeofday(&t1, NULL);
-	if (pflag)
-		cnt = do_pread(buf, offset, count, &total);
-	else if (bflag)
-		cnt = do_load_vmstate(buf, offset, count, &total);
-	else
-		cnt = do_read(buf, offset, count, &total);
-	gettimeofday(&t2, NULL);
-
-	if (cnt < 0) {
-		printf("read failed: %s\n", strerror(-cnt));
-		goto out;
-	}
-
-	if (Pflag) {
-		void* cmp_buf = malloc(pattern_count);
-		memset(cmp_buf, pattern, pattern_count);
-		if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
-			printf("Pattern verification failed at offset %"
-                               PRId64 ", %d bytes\n",
-                               offset + pattern_offset, pattern_count);
-		}
-		free(cmp_buf);
-	}
-
-	if (qflag)
-		goto out;
-
-        if (vflag)
-		dump_buffer(buf, offset, count);
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, t1);
-	print_report("read", &t2, offset, count, total, cnt, Cflag);
-
-out:
-	qemu_io_free(buf);
-
-	return 0;
-}
-
-static void
-readv_help(void)
-{
-	printf(
-"\n"
-" reads a range of bytes from the given offset into multiple buffers\n"
-"\n"
-" Example:\n"
-" 'readv -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
-"\n"
-" Reads a segment of the currently open file, optionally dumping it to the\n"
-" standard output stream (with -v option) for subsequent inspection.\n"
-" Uses multiple iovec buffers if more than one byte range is specified.\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -P, -- use a pattern to verify read data\n"
-" -v, -- dump buffer to standard output\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int readv_f(int argc, char **argv);
-
-static const cmdinfo_t readv_cmd = {
-	.name		= "readv",
-	.cfunc		= readv_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cqv] [-P pattern ] off len [len..]",
-	.oneline	= "reads a number of bytes at a specified offset",
-	.help		= readv_help,
-};
-
-static int
-readv_f(int argc, char **argv)
-{
-	struct timeval t1, t2;
-	int Cflag = 0, qflag = 0, vflag = 0;
-	int c, cnt;
-	char *buf;
-	int64_t offset;
-        /* Some compilers get confused and warn if this is not initialized.  */
-        int total = 0;
-	int nr_iov;
-	QEMUIOVector qiov;
-	int pattern = 0;
-	int Pflag = 0;
-
-	while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
-		switch (c) {
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'P':
-			Pflag = 1;
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		case 'v':
-			vflag = 1;
-			break;
-		default:
-			return command_usage(&readv_cmd);
-		}
-	}
-
-	if (optind > argc - 2)
-		return command_usage(&readv_cmd);
-
-
-	offset = cvtnum(argv[optind]);
-	if (offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-	optind++;
-
-	if (offset & 0x1ff) {
-                printf("offset %" PRId64 " is not sector aligned\n",
-                       offset);
-		return 0;
-	}
-
-	nr_iov = argc - optind;
-	buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);
-
-	gettimeofday(&t1, NULL);
-	cnt = do_aio_readv(&qiov, offset, &total);
-	gettimeofday(&t2, NULL);
-
-	if (cnt < 0) {
-		printf("readv failed: %s\n", strerror(-cnt));
-		goto out;
-	}
-
-	if (Pflag) {
-		void* cmp_buf = malloc(qiov.size);
-		memset(cmp_buf, pattern, qiov.size);
-		if (memcmp(buf, cmp_buf, qiov.size)) {
-			printf("Pattern verification failed at offset %"
-                               PRId64 ", %zd bytes\n",
-                               offset, qiov.size);
-		}
-		free(cmp_buf);
-	}
-
-	if (qflag)
-		goto out;
-
-        if (vflag)
-		dump_buffer(buf, offset, qiov.size);
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, t1);
-	print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
-
-out:
-	qemu_io_free(buf);
-	return 0;
-}
-
-static void
-write_help(void)
-{
-	printf(
-"\n"
-" writes a range of bytes from the given offset\n"
-"\n"
-" Example:\n"
-" 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
-"\n"
-" Writes into a segment of the currently open file, using a buffer\n"
-" filled with a set pattern (0xcdcdcdcd).\n"
-" -b, -- write to the VM state rather than the virtual disk\n"
-" -p, -- use bdrv_pwrite to write the file\n"
-" -P, -- use different pattern to fill file\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int write_f(int argc, char **argv);
-
-static const cmdinfo_t write_cmd = {
-	.name		= "write",
-	.altname	= "w",
-	.cfunc		= write_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-abCpq] [-P pattern ] off len",
-	.oneline	= "writes a number of bytes at a specified offset",
-	.help		= write_help,
-};
-
-static int
-write_f(int argc, char **argv)
-{
-	struct timeval t1, t2;
-	int Cflag = 0, pflag = 0, qflag = 0, bflag = 0;
-	int c, cnt;
-	char *buf;
-	int64_t offset;
-	int count;
-        /* Some compilers get confused and warn if this is not initialized.  */
-        int total = 0;
-	int pattern = 0xcd;
-
-	while ((c = getopt(argc, argv, "bCpP:q")) != EOF) {
-		switch (c) {
-		case 'b':
-			bflag = 1;
-			break;
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'p':
-			pflag = 1;
-			break;
-		case 'P':
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		default:
-			return command_usage(&write_cmd);
-		}
-	}
-
-	if (optind != argc - 2)
-		return command_usage(&write_cmd);
-
-	if (bflag && pflag) {
-		printf("-b and -p cannot be specified at the same time\n");
-		return 0;
-	}
-
-	offset = cvtnum(argv[optind]);
-	if (offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-
-	optind++;
-	count = cvtnum(argv[optind]);
-	if (count < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-
-	if (!pflag) {
-		if (offset & 0x1ff) {
-                        printf("offset %" PRId64 " is not sector aligned\n",
-                               offset);
-			return 0;
-		}
-
-		if (count & 0x1ff) {
-			printf("count %d is not sector aligned\n",
-				count);
-			return 0;
-		}
-	}
-
-	buf = qemu_io_alloc(count, pattern);
-
-	gettimeofday(&t1, NULL);
-	if (pflag)
-		cnt = do_pwrite(buf, offset, count, &total);
-	else if (bflag)
-		cnt = do_save_vmstate(buf, offset, count, &total);
-	else
-		cnt = do_write(buf, offset, count, &total);
-	gettimeofday(&t2, NULL);
-
-	if (cnt < 0) {
-		printf("write failed: %s\n", strerror(-cnt));
-		goto out;
-	}
-
-	if (qflag)
-		goto out;
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, t1);
-	print_report("wrote", &t2, offset, count, total, cnt, Cflag);
-
-out:
-	qemu_io_free(buf);
-
-	return 0;
-}
-
-static void
-writev_help(void)
-{
-	printf(
-"\n"
-" writes a range of bytes from the given offset source from multiple buffers\n"
-"\n"
-" Example:\n"
-" 'write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
-"\n"
-" Writes into a segment of the currently open file, using a buffer\n"
-" filled with a set pattern (0xcdcdcdcd).\n"
-" -P, -- use different pattern to fill file\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int writev_f(int argc, char **argv);
-
-static const cmdinfo_t writev_cmd = {
-	.name		= "writev",
-	.cfunc		= writev_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cq] [-P pattern ] off len [len..]",
-	.oneline	= "writes a number of bytes at a specified offset",
-	.help		= writev_help,
-};
-
-static int
-writev_f(int argc, char **argv)
-{
-	struct timeval t1, t2;
-	int Cflag = 0, qflag = 0;
-	int c, cnt;
-	char *buf;
-	int64_t offset;
-        /* Some compilers get confused and warn if this is not initialized.  */
-        int total = 0;
-	int nr_iov;
-	int pattern = 0xcd;
-	QEMUIOVector qiov;
-
-	while ((c = getopt(argc, argv, "CqP:")) != EOF) {
-		switch (c) {
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		case 'P':
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		default:
-			return command_usage(&writev_cmd);
-		}
-	}
-
-	if (optind > argc - 2)
-		return command_usage(&writev_cmd);
-
-	offset = cvtnum(argv[optind]);
-	if (offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-	optind++;
-
-	if (offset & 0x1ff) {
-                printf("offset %" PRId64 " is not sector aligned\n",
-                       offset);
-		return 0;
-	}
-
-	nr_iov = argc - optind;
-	buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
-
-	gettimeofday(&t1, NULL);
-	cnt = do_aio_writev(&qiov, offset, &total);
-	gettimeofday(&t2, NULL);
-
-	if (cnt < 0) {
-		printf("writev failed: %s\n", strerror(-cnt));
-		goto out;
-	}
-
-	if (qflag)
-		goto out;
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, t1);
-	print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
-out:
-	qemu_io_free(buf);
-	return 0;
-}
-
-static void
-multiwrite_help(void)
-{
-	printf(
-"\n"
-" writes a range of bytes from the given offset source from multiple buffers,\n"
-" in a batch of requests that may be merged by qemu\n"
-"\n"
-" Example:\n"
-" 'multiwrite 512 1k 1k ; 4k 1k' \n"
-"  writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
-"\n"
-" Writes into a segment of the currently open file, using a buffer\n"
-" filled with a set pattern (0xcdcdcdcd). The pattern byte is increased\n"
-" by one for each request contained in the multiwrite command.\n"
-" -P, -- use different pattern to fill file\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int multiwrite_f(int argc, char **argv);
-
-static const cmdinfo_t multiwrite_cmd = {
-	.name		= "multiwrite",
-	.cfunc		= multiwrite_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
-	.oneline	= "issues multiple write requests at once",
-	.help		= multiwrite_help,
-};
-
-static int
-multiwrite_f(int argc, char **argv)
-{
-	struct timeval t1, t2;
-	int Cflag = 0, qflag = 0;
-	int c, cnt;
-	char **buf;
-	int64_t offset, first_offset = 0;
-	/* Some compilers get confused and warn if this is not initialized.  */
-	int total = 0;
-	int nr_iov;
-	int nr_reqs;
-	int pattern = 0xcd;
-	QEMUIOVector *qiovs;
-	int i;
-	BlockRequest *reqs;
-
-	while ((c = getopt(argc, argv, "CqP:")) != EOF) {
-		switch (c) {
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		case 'P':
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		default:
-			return command_usage(&writev_cmd);
-		}
-	}
-
-	if (optind > argc - 2)
-		return command_usage(&writev_cmd);
-
-	nr_reqs = 1;
-	for (i = optind; i < argc; i++) {
-		if (!strcmp(argv[i], ";")) {
-			nr_reqs++;
-		}
-	}
-
-	reqs = g_malloc(nr_reqs * sizeof(*reqs));
-	buf = g_malloc(nr_reqs * sizeof(*buf));
-	qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
-
-	for (i = 0; i < nr_reqs; i++) {
-		int j;
-
-		/* Read the offset of the request */
-		offset = cvtnum(argv[optind]);
-		if (offset < 0) {
-			printf("non-numeric offset argument -- %s\n", argv[optind]);
-			return 0;
-		}
-		optind++;
-
-		if (offset & 0x1ff) {
-			printf("offset %lld is not sector aligned\n",
-				(long long)offset);
-			return 0;
-		}
-
-        if (i == 0) {
-            first_offset = offset;
-        }
-
-		/* Read lengths for qiov entries */
-		for (j = optind; j < argc; j++) {
-			if (!strcmp(argv[j], ";")) {
-				break;
-			}
-		}
-
-		nr_iov = j - optind;
-
-		/* Build request */
-		reqs[i].qiov = &qiovs[i];
-		buf[i] = create_iovec(reqs[i].qiov, &argv[optind], nr_iov, pattern);
-		reqs[i].sector = offset >> 9;
-		reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
-
-		optind = j + 1;
-
-		offset += reqs[i].qiov->size;
-		pattern++;
-	}
-
-	gettimeofday(&t1, NULL);
-	cnt = do_aio_multiwrite(reqs, nr_reqs, &total);
-	gettimeofday(&t2, NULL);
-
-	if (cnt < 0) {
-		printf("aio_multiwrite failed: %s\n", strerror(-cnt));
-		goto out;
-	}
-
-	if (qflag)
-		goto out;
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, t1);
-	print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
-out:
-	for (i = 0; i < nr_reqs; i++) {
-		qemu_io_free(buf[i]);
-		qemu_iovec_destroy(&qiovs[i]);
-	}
-	g_free(buf);
-	g_free(reqs);
-	g_free(qiovs);
-	return 0;
-}
-
-struct aio_ctx {
-	QEMUIOVector qiov;
-	int64_t offset;
-	char *buf;
-	int qflag;
-	int vflag;
-	int Cflag;
-	int Pflag;
-	int pattern;
-	struct timeval t1;
-};
-
-static void
-aio_write_done(void *opaque, int ret)
-{
-	struct aio_ctx *ctx = opaque;
-	struct timeval t2;
-
-	gettimeofday(&t2, NULL);
-
-
-	if (ret < 0) {
-		printf("aio_write failed: %s\n", strerror(-ret));
-		goto out;
-	}
-
-	if (ctx->qflag) {
-		goto out;
-	}
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, ctx->t1);
-	print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
-		     ctx->qiov.size, 1, ctx->Cflag);
-out:
-	qemu_io_free(ctx->buf);
-	free(ctx);
-}
-
-static void
-aio_read_done(void *opaque, int ret)
-{
-	struct aio_ctx *ctx = opaque;
-	struct timeval t2;
-
-	gettimeofday(&t2, NULL);
-
-	if (ret < 0) {
-		printf("readv failed: %s\n", strerror(-ret));
-		goto out;
-	}
-
-	if (ctx->Pflag) {
-		void *cmp_buf = malloc(ctx->qiov.size);
-
-		memset(cmp_buf, ctx->pattern, ctx->qiov.size);
-		if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
-			printf("Pattern verification failed at offset %"
-                               PRId64 ", %zd bytes\n",
-                               ctx->offset, ctx->qiov.size);
-		}
-		free(cmp_buf);
-	}
-
-	if (ctx->qflag) {
-		goto out;
-	}
-
-	if (ctx->vflag) {
-		dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
-	}
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, ctx->t1);
-	print_report("read", &t2, ctx->offset, ctx->qiov.size,
-		     ctx->qiov.size, 1, ctx->Cflag);
-out:
-	qemu_io_free(ctx->buf);
-	free(ctx);
-}
-
-static void
-aio_read_help(void)
-{
-	printf(
-"\n"
-" asynchronously reads a range of bytes from the given offset\n"
-"\n"
-" Example:\n"
-" 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
-"\n"
-" Reads a segment of the currently open file, optionally dumping it to the\n"
-" standard output stream (with -v option) for subsequent inspection.\n"
-" The read is performed asynchronously and the aio_flush command must be\n"
-" used to ensure all outstanding aio requests have been completed\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -P, -- use a pattern to verify read data\n"
-" -v, -- dump buffer to standard output\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int aio_read_f(int argc, char **argv);
-
-static const cmdinfo_t aio_read_cmd = {
-	.name		= "aio_read",
-	.cfunc		= aio_read_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cqv] [-P pattern ] off len [len..]",
-	.oneline	= "asynchronously reads a number of bytes",
-	.help		= aio_read_help,
-};
-
-static int
-aio_read_f(int argc, char **argv)
-{
-	int nr_iov, c;
-	struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
-	BlockDriverAIOCB *acb;
-
-	while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
-		switch (c) {
-		case 'C':
-			ctx->Cflag = 1;
-			break;
-		case 'P':
-			ctx->Pflag = 1;
-			ctx->pattern = parse_pattern(optarg);
-			if (ctx->pattern < 0) {
-                                free(ctx);
-				return 0;
-                        }
-			break;
-		case 'q':
-			ctx->qflag = 1;
-			break;
-		case 'v':
-			ctx->vflag = 1;
-			break;
-		default:
-			free(ctx);
-			return command_usage(&aio_read_cmd);
-		}
-	}
-
-	if (optind > argc - 2) {
-		free(ctx);
-		return command_usage(&aio_read_cmd);
-	}
-
-	ctx->offset = cvtnum(argv[optind]);
-	if (ctx->offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		free(ctx);
-		return 0;
-	}
-	optind++;
-
-	if (ctx->offset & 0x1ff) {
-		printf("offset %" PRId64 " is not sector aligned\n",
-                       ctx->offset);
-		free(ctx);
-		return 0;
-	}
-
-	nr_iov = argc - optind;
-	ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
-
-	gettimeofday(&ctx->t1, NULL);
-	acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
-			      ctx->qiov.size >> 9, aio_read_done, ctx);
-	if (!acb) {
-		free(ctx->buf);
-		free(ctx);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static void
-aio_write_help(void)
-{
-	printf(
-"\n"
-" asynchronously writes a range of bytes from the given offset source \n"
-" from multiple buffers\n"
-"\n"
-" Example:\n"
-" 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
-"\n"
-" Writes into a segment of the currently open file, using a buffer\n"
-" filled with a set pattern (0xcdcdcdcd).\n"
-" The write is performed asynchronously and the aio_flush command must be\n"
-" used to ensure all outstanding aio requests have been completed\n"
-" -P, -- use different pattern to fill file\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int aio_write_f(int argc, char **argv);
-
-static const cmdinfo_t aio_write_cmd = {
-	.name		= "aio_write",
-	.cfunc		= aio_write_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cq] [-P pattern ] off len [len..]",
-	.oneline	= "asynchronously writes a number of bytes",
-	.help		= aio_write_help,
-};
-
-static int
-aio_write_f(int argc, char **argv)
-{
-	int nr_iov, c;
-	int pattern = 0xcd;
-	struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
-	BlockDriverAIOCB *acb;
-
-	while ((c = getopt(argc, argv, "CqP:")) != EOF) {
-		switch (c) {
-		case 'C':
-			ctx->Cflag = 1;
-			break;
-		case 'q':
-			ctx->qflag = 1;
-			break;
-		case 'P':
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		default:
-			free(ctx);
-			return command_usage(&aio_write_cmd);
-		}
-	}
-
-	if (optind > argc - 2) {
-		free(ctx);
-		return command_usage(&aio_write_cmd);
-	}
-
-	ctx->offset = cvtnum(argv[optind]);
-	if (ctx->offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		free(ctx);
-		return 0;
-	}
-	optind++;
-
-	if (ctx->offset & 0x1ff) {
-		printf("offset %" PRId64 " is not sector aligned\n",
-                       ctx->offset);
-		free(ctx);
-		return 0;
-	}
-
-	nr_iov = argc - optind;
-	ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
-
-	gettimeofday(&ctx->t1, NULL);
-	acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
-			      ctx->qiov.size >> 9, aio_write_done, ctx);
-	if (!acb) {
-		free(ctx->buf);
-		free(ctx);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int
-aio_flush_f(int argc, char **argv)
-{
-	qemu_aio_flush();
-	return 0;
-}
-
-static const cmdinfo_t aio_flush_cmd = {
-	.name		= "aio_flush",
-	.cfunc		= aio_flush_f,
-	.oneline	= "completes all outstanding aio requests"
-};
-
-static int
-flush_f(int argc, char **argv)
-{
-	bdrv_flush(bs);
-	return 0;
-}
-
-static const cmdinfo_t flush_cmd = {
-	.name		= "flush",
-	.altname	= "f",
-	.cfunc		= flush_f,
-	.oneline	= "flush all in-core file state to disk",
-};
-
-static int
-truncate_f(int argc, char **argv)
-{
-	int64_t offset;
-	int ret;
-
-	offset = cvtnum(argv[1]);
-	if (offset < 0) {
-		printf("non-numeric truncate argument -- %s\n", argv[1]);
-		return 0;
-	}
-
-	ret = bdrv_truncate(bs, offset);
-	if (ret < 0) {
-		printf("truncate: %s\n", strerror(-ret));
-		return 0;
-	}
-
-	return 0;
-}
-
-static const cmdinfo_t truncate_cmd = {
-	.name		= "truncate",
-	.altname	= "t",
-	.cfunc		= truncate_f,
-	.argmin		= 1,
-	.argmax		= 1,
-	.args		= "off",
-	.oneline	= "truncates the current file at the given offset",
-};
-
-static int
-length_f(int argc, char **argv)
-{
-        int64_t size;
-	char s1[64];
-
-	size = bdrv_getlength(bs);
-	if (size < 0) {
-		printf("getlength: %s\n", strerror(-size));
-		return 0;
-	}
-
-	cvtstr(size, s1, sizeof(s1));
-	printf("%s\n", s1);
-	return 0;
-}
-
-
-static const cmdinfo_t length_cmd = {
-	.name		= "length",
-	.altname	= "l",
-	.cfunc		= length_f,
-	.oneline	= "gets the length of the current file",
-};
-
-
-static int
-info_f(int argc, char **argv)
-{
-	BlockDriverInfo bdi;
-	char s1[64], s2[64];
-	int ret;
-
-	if (bs->drv && bs->drv->format_name)
-		printf("format name: %s\n", bs->drv->format_name);
-	if (bs->drv && bs->drv->protocol_name)
-		printf("format name: %s\n", bs->drv->protocol_name);
-
-	ret = bdrv_get_info(bs, &bdi);
-	if (ret)
-		return 0;
-
-	cvtstr(bdi.cluster_size, s1, sizeof(s1));
-	cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
-
-	printf("cluster size: %s\n", s1);
-	printf("vm state offset: %s\n", s2);
-
-	return 0;
-}
-
-
-
-static const cmdinfo_t info_cmd = {
-	.name		= "info",
-	.altname	= "i",
-	.cfunc		= info_f,
-	.oneline	= "prints information about the current file",
-};
-
-static void
-discard_help(void)
-{
-	printf(
-"\n"
-" discards a range of bytes from the given offset\n"
-"\n"
-" Example:\n"
-" 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
-"\n"
-" Discards a segment of the currently open file.\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int discard_f(int argc, char **argv);
-
-static const cmdinfo_t discard_cmd = {
-	.name		= "discard",
-	.altname	= "d",
-	.cfunc		= discard_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cq] off len",
-	.oneline	= "discards a number of bytes at a specified offset",
-	.help		= discard_help,
-};
-
-static int
-discard_f(int argc, char **argv)
-{
-	struct timeval t1, t2;
-	int Cflag = 0, qflag = 0;
-	int c, ret;
-	int64_t offset;
-	int count;
-
-	while ((c = getopt(argc, argv, "Cq")) != EOF) {
-		switch (c) {
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		default:
-			return command_usage(&discard_cmd);
-		}
-	}
-
-	if (optind != argc - 2) {
-		return command_usage(&discard_cmd);
-	}
-
-	offset = cvtnum(argv[optind]);
-	if (offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-
-	optind++;
-	count = cvtnum(argv[optind]);
-	if (count < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-
-	gettimeofday(&t1, NULL);
-	ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS, count >> BDRV_SECTOR_BITS);
-	gettimeofday(&t2, NULL);
-
-	if (ret < 0) {
-		printf("discard failed: %s\n", strerror(-ret));
-		goto out;
-	}
-
-	/* Finally, report back -- -C gives a parsable format */
-	if (!qflag) {
-		t2 = tsub(t2, t1);
-		print_report("discard", &t2, offset, count, count, 1, Cflag);
-	}
-
-out:
-	return 0;
-}
-
-static int
-alloc_f(int argc, char **argv)
-{
-	int64_t offset;
-	int nb_sectors, remaining;
-	char s1[64];
-	int num, sum_alloc;
-	int ret;
-
-	offset = cvtnum(argv[1]);
-	if (offset & 0x1ff) {
-                printf("offset %" PRId64 " is not sector aligned\n",
-                       offset);
-		return 0;
-	}
-
-	if (argc == 3)
-		nb_sectors = cvtnum(argv[2]);
-	else
-		nb_sectors = 1;
-
-	remaining = nb_sectors;
-	sum_alloc = 0;
-	while (remaining) {
-		ret = bdrv_is_allocated(bs, offset >> 9, nb_sectors, &num);
-		remaining -= num;
-		if (ret) {
-			sum_alloc += num;
-		}
-	}
-
-	cvtstr(offset, s1, sizeof(s1));
-
-	if (nb_sectors == 1)
-		printf("sector allocated at offset %s\n", s1);
-	else
-		printf("%d/%d sectors allocated at offset %s\n",
-			sum_alloc, nb_sectors, s1);
-	return 0;
-}
-
-static const cmdinfo_t alloc_cmd = {
-	.name		= "alloc",
-	.altname	= "a",
-	.argmin		= 1,
-	.argmax		= 2,
-	.cfunc		= alloc_f,
-	.args		= "off [sectors]",
-	.oneline	= "checks if a sector is present in the file",
-};
-
-static int
-map_f(int argc, char **argv)
-{
-	int64_t offset;
-	int64_t nb_sectors;
-	char s1[64];
-	int num, num_checked;
-	int ret;
-	const char *retstr;
-
-	offset = 0;
-	nb_sectors = bs->total_sectors;
-
-	do {
-		num_checked = MIN(nb_sectors, INT_MAX);
-		ret = bdrv_is_allocated(bs, offset, num_checked, &num);
-		retstr = ret ? "    allocated" : "not allocated";
-		cvtstr(offset << 9ULL, s1, sizeof(s1));
-		printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
-				offset << 9ULL, num, num_checked, retstr, s1, ret);
-
-		offset += num;
-		nb_sectors -= num;
-	} while(offset < bs->total_sectors);
-
-	return 0;
-}
-
-static const cmdinfo_t map_cmd = {
-       .name           = "map",
-       .argmin         = 0,
-       .argmax         = 0,
-       .cfunc          = map_f,
-       .args           = "",
-       .oneline        = "prints the allocated areas of a file",
-};
-
-
-static int
-close_f(int argc, char **argv)
-{
-	bdrv_close(bs);
-	bs = NULL;
-	return 0;
-}
-
-static const cmdinfo_t close_cmd = {
-	.name		= "close",
-	.altname	= "c",
-	.cfunc		= close_f,
-	.oneline	= "close the current open file",
-};
-
-static int openfile(char *name, int flags, int growable)
-{
-	if (bs) {
-		fprintf(stderr, "file open already, try 'help close'\n");
-		return 1;
-	}
-
-	if (growable) {
-		if (bdrv_file_open(&bs, name, flags)) {
-			fprintf(stderr, "%s: can't open device %s\n", progname, name);
-			return 1;
-		}
-	} else {
-		bs = bdrv_new("hda");
-		if (!bs)
-			return 1;
-
-		if (bdrv_open(bs, name, flags, NULL) < 0) {
-			fprintf(stderr, "%s: can't open device %s\n", progname, name);
-			bs = NULL;
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
-static void
-open_help(void)
-{
-	printf(
-"\n"
-" opens a new file in the requested mode\n"
-"\n"
-" Example:\n"
-" 'open -Cn /tmp/data' - creates/opens data file read-write and uncached\n"
-"\n"
-" Opens a file for subsequent use by all of the other qemu-io commands.\n"
-" -r, -- open file read-only\n"
-" -s, -- use snapshot file\n"
-" -n, -- disable host cache\n"
-" -g, -- allow file to grow (only applies to protocols)"
-"\n");
-}
-
-static int open_f(int argc, char **argv);
-
-static const cmdinfo_t open_cmd = {
-	.name		= "open",
-	.altname	= "o",
-	.cfunc		= open_f,
-	.argmin		= 1,
-	.argmax		= -1,
-	.flags		= CMD_NOFILE_OK,
-	.args		= "[-Crsn] [path]",
-	.oneline	= "open the file specified by path",
-	.help		= open_help,
-};
-
-static int
-open_f(int argc, char **argv)
-{
-	int flags = 0;
-	int readonly = 0;
-	int growable = 0;
-	int c;
-
-	while ((c = getopt(argc, argv, "snrg")) != EOF) {
-		switch (c) {
-		case 's':
-			flags |= BDRV_O_SNAPSHOT;
-			break;
-		case 'n':
-			flags |= BDRV_O_NOCACHE;
-			break;
-		case 'r':
-			readonly = 1;
-			break;
-		case 'g':
-			growable = 1;
-			break;
-		default:
-			return command_usage(&open_cmd);
-		}
-	}
-
-	if (!readonly) {
-            flags |= BDRV_O_RDWR;
-        }
-
-	if (optind != argc - 1)
-		return command_usage(&open_cmd);
-
-	return openfile(argv[optind], flags, growable);
-}
-
-static int
-init_args_command(
-        int     index)
-{
-	/* only one device allowed so far */
-	if (index >= 1)
-		return 0;
-	return ++index;
-}
-
-static int
-init_check_command(
-	const cmdinfo_t *ct)
-{
-	if (ct->flags & CMD_FLAG_GLOBAL)
-		return 1;
-	if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
-		fprintf(stderr, "no file open, try 'help open'\n");
-		return 0;
-	}
-	return 1;
-}
-
-static void usage(const char *name)
-{
-	printf(
-"Usage: %s [-h] [-V] [-rsnm] [-c cmd] ... [file]\n"
-"QEMU Disk exerciser\n"
-"\n"
-"  -c, --cmd            command to execute\n"
-"  -r, --read-only      export read-only\n"
-"  -s, --snapshot       use snapshot file\n"
-"  -n, --nocache        disable host cache\n"
-"  -g, --growable       allow file to grow (only applies to protocols)\n"
-"  -m, --misalign       misalign allocations for O_DIRECT\n"
-"  -k, --native-aio     use kernel AIO implementation (on Linux only)\n"
-"  -h, --help           display this help and exit\n"
-"  -V, --version        output version information and exit\n"
-"\n",
-	name);
-}
-
-
-int main(int argc, char **argv)
-{
-	int readonly = 0;
-	int growable = 0;
-	const char *sopt = "hVc:rsnmgk";
-        const struct option lopt[] = {
-		{ "help", 0, NULL, 'h' },
-		{ "version", 0, NULL, 'V' },
-		{ "offset", 1, NULL, 'o' },
-		{ "cmd", 1, NULL, 'c' },
-		{ "read-only", 0, NULL, 'r' },
-		{ "snapshot", 0, NULL, 's' },
-		{ "nocache", 0, NULL, 'n' },
-		{ "misalign", 0, NULL, 'm' },
-		{ "growable", 0, NULL, 'g' },
-		{ "native-aio", 0, NULL, 'k' },
-		{ NULL, 0, NULL, 0 }
-	};
-	int c;
-	int opt_index = 0;
-	int flags = 0;
-
-	progname = basename(argv[0]);
-
-	while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
-		switch (c) {
-		case 's':
-			flags |= BDRV_O_SNAPSHOT;
-			break;
-		case 'n':
-			flags |= BDRV_O_NOCACHE;
-			break;
-		case 'c':
-			add_user_command(optarg);
-			break;
-		case 'r':
-			readonly = 1;
-			break;
-		case 'm':
-			misalign = 1;
-			break;
-		case 'g':
-			growable = 1;
-			break;
-		case 'k':
-			flags |= BDRV_O_NATIVE_AIO;
-			break;
-		case 'V':
-			printf("%s version %s\n", progname, VERSION);
-			exit(0);
-		case 'h':
-			usage(progname);
-			exit(0);
-		default:
-			usage(progname);
-			exit(1);
-		}
-	}
-
-	if ((argc - optind) > 1) {
-		usage(progname);
-		exit(1);
-	}
-
-	bdrv_init();
-
-	/* initialize commands */
-	quit_init();
-	help_init();
-	add_command(&open_cmd);
-	add_command(&close_cmd);
-	add_command(&read_cmd);
-	add_command(&readv_cmd);
-	add_command(&write_cmd);
-	add_command(&writev_cmd);
-	add_command(&multiwrite_cmd);
-	add_command(&aio_read_cmd);
-	add_command(&aio_write_cmd);
-	add_command(&aio_flush_cmd);
-	add_command(&flush_cmd);
-	add_command(&truncate_cmd);
-	add_command(&length_cmd);
-	add_command(&info_cmd);
-	add_command(&discard_cmd);
-	add_command(&alloc_cmd);
-	add_command(&map_cmd);
-
-	add_args_command(init_args_command);
-	add_check_command(init_check_command);
-
-	/* open the device */
-	if (!readonly) {
-            flags |= BDRV_O_RDWR;
-        }
-
-	if ((argc - optind) == 1)
-		openfile(argv[optind], flags, growable);
-	command_loop();
-
-	/*
-	 * Make sure all outstanding requests get flushed the program exits.
-	 */
-	qemu_aio_flush();
-
-	if (bs)
-		bdrv_close(bs);
-	return 0;
-}
diff --git a/qemu-log.c b/qemu-log.c
new file mode 100644
index 0000000..797f2af
--- /dev/null
+++ b/qemu-log.c
@@ -0,0 +1,174 @@
+/*
+ * Logging support
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu-common.h"
+#include "qemu/log.h"
+
+static char *logfilename;
+FILE *qemu_logfile;
+int qemu_loglevel;
+static int log_append = 0;
+
+void qemu_log(const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    if (qemu_logfile) {
+        vfprintf(qemu_logfile, fmt, ap);
+    }
+    va_end(ap);
+}
+
+void qemu_log_mask(int mask, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    if ((qemu_loglevel & mask) && qemu_logfile) {
+        vfprintf(qemu_logfile, fmt, ap);
+    }
+    va_end(ap);
+}
+
+/* enable or disable low levels log */
+void do_qemu_set_log(int log_flags, bool use_own_buffers)
+{
+    qemu_loglevel = log_flags;
+    if (qemu_loglevel && !qemu_logfile) {
+        if (logfilename) {
+            qemu_logfile = fopen(logfilename, log_append ? "a" : "w");
+            if (!qemu_logfile) {
+                perror(logfilename);
+                _exit(1);
+            }
+        } else {
+            /* Default to stderr if no log file specified */
+            qemu_logfile = stderr;
+        }
+        /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
+        if (use_own_buffers) {
+            static char logfile_buf[4096];
+
+            setvbuf(qemu_logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
+        } else {
+#if defined(_WIN32)
+            /* Win32 doesn't support line-buffering, so use unbuffered output. */
+            setvbuf(qemu_logfile, NULL, _IONBF, 0);
+#else
+            setvbuf(qemu_logfile, NULL, _IOLBF, 0);
+#endif
+            log_append = 1;
+        }
+    }
+    if (!qemu_loglevel && qemu_logfile) {
+        qemu_log_close();
+    }
+}
+
+void qemu_set_log_filename(const char *filename)
+{
+    g_free(logfilename);
+    logfilename = g_strdup(filename);
+    qemu_log_close();
+    qemu_set_log(qemu_loglevel);
+}
+
+const QEMULogItem qemu_log_items[] = {
+    { CPU_LOG_TB_OUT_ASM, "out_asm",
+      "show generated host assembly code for each compiled TB" },
+    { CPU_LOG_TB_IN_ASM, "in_asm",
+      "show target assembly code for each compiled TB" },
+    { CPU_LOG_TB_OP, "op",
+      "show micro ops for each compiled TB" },
+    { CPU_LOG_TB_OP_OPT, "op_opt",
+      "show micro ops (x86 only: before eflags optimization) and\n"
+      "after liveness analysis" },
+    { CPU_LOG_INT, "int",
+      "show interrupts/exceptions in short format" },
+    { CPU_LOG_EXEC, "exec",
+      "show trace before each executed TB (lots of logs)" },
+    { CPU_LOG_TB_CPU, "cpu",
+      "show CPU state before block translation" },
+    { CPU_LOG_PCALL, "pcall",
+      "x86 only: show protected mode far calls/returns/exceptions" },
+    { CPU_LOG_RESET, "cpu_reset",
+      "x86 only: show CPU state before CPU resets" },
+    { CPU_LOG_IOPORT, "ioport",
+      "show all i/o ports accesses" },
+    { LOG_UNIMP, "unimp",
+      "log unimplemented functionality" },
+    { LOG_GUEST_ERROR, "guest_errors",
+      "log when the guest OS does something invalid (eg accessing a\n"
+      "non-existent register)" },
+    { 0, NULL, NULL },
+};
+
+static int cmp1(const char *s1, int n, const char *s2)
+{
+    if (strlen(s2) != n) {
+        return 0;
+    }
+    return memcmp(s1, s2, n) == 0;
+}
+
+/* takes a comma separated list of log masks. Return 0 if error. */
+int qemu_str_to_log_mask(const char *str)
+{
+    const QEMULogItem *item;
+    int mask;
+    const char *p, *p1;
+
+    p = str;
+    mask = 0;
+    for (;;) {
+        p1 = strchr(p, ',');
+        if (!p1) {
+            p1 = p + strlen(p);
+        }
+        if (cmp1(p,p1-p,"all")) {
+            for (item = qemu_log_items; item->mask != 0; item++) {
+                mask |= item->mask;
+            }
+        } else {
+            for (item = qemu_log_items; item->mask != 0; item++) {
+                if (cmp1(p, p1 - p, item->name)) {
+                    goto found;
+                }
+            }
+            return 0;
+        }
+    found:
+        mask |= item->mask;
+        if (*p1 != ',') {
+            break;
+        }
+        p = p1 + 1;
+    }
+    return mask;
+}
+
+void qemu_print_log_usage(FILE *f)
+{
+    const QEMULogItem *item;
+    fprintf(f, "Log items (comma separated):\n");
+    for (item = qemu_log_items; item->mask != 0; item++) {
+        fprintf(f, "%-10s %s\n", item->name, item->help);
+    }
+}
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
deleted file mode 100644
index fd158ea..0000000
--- a/qemu-monitor.hx
+++ /dev/null
@@ -1,630 +0,0 @@
-HXCOMM Use DEFHEADING() to define headings in both help text and texi
-HXCOMM Text between STEXI and ETEXI are copied to texi version and
-HXCOMM discarded from C version
-HXCOMM DEF(command, args, callback, arg_string, help) is used to construct
-HXCOMM monitor commands
-HXCOMM HXCOMM can be used for comments, discarded from both texi and C
-
-STEXI
-@table @option
-ETEXI
-
-    { "help|?", "s?", help_cmd, "[cmd]", "show the help" },
-STEXI
-@item help or ? [@var{cmd}]
-Show the help for all commands or just for command @var{cmd}.
-ETEXI
-
-    { "commit", "s", do_commit,
-      "device|all", "commit changes to the disk images (if -snapshot is used) or backing files" },
-STEXI
-@item commit
-Commit changes to the disk images (if -snapshot is used) or backing files.
-ETEXI
-
-    { "info", "s?", do_info,
-      "[subcommand]", "show various information about the system state" },
-STEXI
-@item info @var{subcommand}
-Show various information about the system state.
-
-@table @option
-@item info version
-show the version of QEMU
-@item info network
-show the various VLANs and the associated devices
-@item info chardev
-show the character devices
-@item info block
-show the block devices
-@item info block
-show block device statistics
-@item info registers
-show the cpu registers
-@item info cpus
-show infos for each CPU
-@item info history
-show the command line history
-@item info irq
-show the interrupts statistics (if available)
-@item info pic
-show i8259 (PIC) state
-@item info pci
-show emulated PCI device info
-@item info tlb
-show virtual to physical memory mappings (i386 only)
-@item info mem
-show the active virtual memory mappings (i386 only)
-@item info hpet
-show state of HPET (i386 only)
-@item info kqemu
-show KQEMU information
-@item info kvm
-show KVM information
-@item info usb
-show USB devices plugged on the virtual USB hub
-@item info usbhost
-show all USB host devices
-@item info profile
-show profiling information
-@item info capture
-show information about active capturing
-@item info snapshots
-show list of VM snapshots
-@item info status
-show the current VM status (running|paused)
-@item info pcmcia
-show guest PCMCIA status
-@item info mice
-show which guest mouse is receiving events
-@item info vnc
-show the vnc server status
-@item info name
-show the current VM name
-@item info uuid
-show the current VM UUID
-@item info cpustats
-show CPU statistics
-@item info slirp
-show SLIRP statistics (if available)
-@item info migrate
-show migration status
-@item info balloon
-show balloon information
-@item info qtree
-show device tree
-@end table
-ETEXI
-
-    { "q|quit", "", do_quit,
-      "", "quit the emulator" },
-STEXI
-@item q or quit
-Quit the emulator.
-ETEXI
-
-    { "eject", "-fB", do_eject,
-      "[-f] device", "eject a removable medium (use -f to force it)" },
-STEXI
-@item eject [-f] @var{device}
-Eject a removable medium (use -f to force it).
-ETEXI
-
-    { "change", "BFs?", do_change,
-      "device filename [format]", "change a removable medium, optional format" },
-STEXI
-@item change @var{device} @var{setting}
-
-Change the configuration of a device.
-
-@table @option
-@item change @var{diskdevice} @var{filename} [@var{format}]
-Change the medium for a removable disk device to point to @var{filename}. eg
-
-@example
-(qemu) change ide1-cd0 /path/to/some.iso
-@end example
-
-@var{format} is optional.
-
-@item change vnc @var{display},@var{options}
-Change the configuration of the VNC server. The valid syntax for @var{display}
-and @var{options} are described at @ref{sec_invocation}. eg
-
-@example
-(qemu) change vnc localhost:1
-@end example
-
-@item change vnc password [@var{password}]
-
-Change the password associated with the VNC server. If the new password is not
-supplied, the monitor will prompt for it to be entered. VNC passwords are only
-significant up to 8 letters. eg
-
-@example
-(qemu) change vnc password
-Password: ********
-@end example
-
-@end table
-ETEXI
-
-    { "screendump", "F", do_screen_dump,
-      "filename", "save screen into PPM image 'filename'" },
-STEXI
-@item screendump @var{filename}
-Save screen into PPM image @var{filename}.
-ETEXI
-
-    { "logfile", "F", do_logfile,
-      "filename", "output logs to 'filename'" },
-STEXI
-@item logfile @var{filename}
-Output logs to @var{filename}.
-ETEXI
-
-    { "log", "s", do_log,
-      "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
-STEXI
-@item log @var{item1}[,...]
-Activate logging of the specified items to @file{/tmp/qemu.log}.
-ETEXI
-
-    { "savevm", "s?", do_savevm,
-      "[tag|id]", "save a VM snapshot. If no tag or id are provided, a new snapshot is created" },
-STEXI
-@item savevm [@var{tag}|@var{id}]
-Create a snapshot of the whole virtual machine. If @var{tag} is
-provided, it is used as human readable identifier. If there is already
-a snapshot with the same tag or ID, it is replaced. More info at
-@ref{vm_snapshots}.
-ETEXI
-
-    { "loadvm", "s", do_loadvm,
-      "tag|id", "restore a VM snapshot from its tag or id" },
-STEXI
-@item loadvm @var{tag}|@var{id}
-Set the whole virtual machine to the snapshot identified by the tag
-@var{tag} or the unique snapshot ID @var{id}.
-ETEXI
-
-    { "delvm", "s", do_delvm,
-      "tag|id", "delete a VM snapshot from its tag or id" },
-STEXI
-@item delvm @var{tag}|@var{id}
-Delete the snapshot identified by @var{tag} or @var{id}.
-ETEXI
-
-    { "singlestep", "s?", do_singlestep,
-      "[on|off]", "run emulation in singlestep mode or switch to normal mode", },
-STEXI
-@item singlestep [off]
-Run the emulation in single step mode.
-If called with option off, the emulation returns to normal mode.
-ETEXI
-
-    { "stop", "", do_stop,
-      "", "stop emulation", },
-STEXI
-@item stop
-Stop emulation.
-ETEXI
-
-    { "c|cont", "", do_cont,
-      "", "resume emulation", },
-STEXI
-@item c or cont
-Resume emulation.
-ETEXI
-
-    { "gdbserver", "s?", do_gdbserver,
-      "[device]", "start gdbserver on given device (default 'tcp::1234'), stop with 'none'", },
-STEXI
-@item gdbserver [@var{port}]
-Start gdbserver session (default @var{port}=1234)
-ETEXI
-
-    { "x", "/l", do_memory_dump,
-      "/fmt addr", "virtual memory dump starting at 'addr'", },
-STEXI
-@item x/fmt @var{addr}
-Virtual memory dump starting at @var{addr}.
-ETEXI
-
-    { "xp", "/l", do_physical_memory_dump,
-      "/fmt addr", "physical memory dump starting at 'addr'", },
-STEXI
-@item xp /@var{fmt} @var{addr}
-Physical memory dump starting at @var{addr}.
-
-@var{fmt} is a format which tells the command how to format the
-data. Its syntax is: @option{/@{count@}@{format@}@{size@}}
-
-@table @var
-@item count
-is the number of items to be dumped.
-
-@item format
-can be x (hex), d (signed decimal), u (unsigned decimal), o (octal),
-c (char) or i (asm instruction).
-
-@item size
-can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). On x86,
-@code{h} or @code{w} can be specified with the @code{i} format to
-respectively select 16 or 32 bit code instruction size.
-
-@end table
-
-Examples:
-@itemize
-@item
-Dump 10 instructions at the current instruction pointer:
-@example
-(qemu) x/10i $eip
-0x90107063:  ret
-0x90107064:  sti
-0x90107065:  lea    0x0(%esi,1),%esi
-0x90107069:  lea    0x0(%edi,1),%edi
-0x90107070:  ret
-0x90107071:  jmp    0x90107080
-0x90107073:  nop
-0x90107074:  nop
-0x90107075:  nop
-0x90107076:  nop
-@end example
-
-@item
-Dump 80 16 bit values at the start of the video memory.
-@smallexample
-(qemu) xp/80hx 0xb8000
-0x000b8000: 0x0b50 0x0b6c 0x0b65 0x0b78 0x0b38 0x0b36 0x0b2f 0x0b42
-0x000b8010: 0x0b6f 0x0b63 0x0b68 0x0b73 0x0b20 0x0b56 0x0b47 0x0b41
-0x000b8020: 0x0b42 0x0b69 0x0b6f 0x0b73 0x0b20 0x0b63 0x0b75 0x0b72
-0x000b8030: 0x0b72 0x0b65 0x0b6e 0x0b74 0x0b2d 0x0b63 0x0b76 0x0b73
-0x000b8040: 0x0b20 0x0b30 0x0b35 0x0b20 0x0b4e 0x0b6f 0x0b76 0x0b20
-0x000b8050: 0x0b32 0x0b30 0x0b30 0x0b33 0x0720 0x0720 0x0720 0x0720
-0x000b8060: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8070: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8080: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8090: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-@end smallexample
-@end itemize
-ETEXI
-
-    { "p|print", "/l", do_print,
-      "/fmt expr", "print expression value (use $reg for CPU register access)", },
-STEXI
-@item p or print/@var{fmt} @var{expr}
-
-Print expression value. Only the @var{format} part of @var{fmt} is
-used.
-ETEXI
-
-    { "i", "/ii.", do_ioport_read,
-      "/fmt addr", "I/O port read" },
-STEXI
-Read I/O port.
-ETEXI
-
-
-    { "sendkey", "si?", do_sendkey,
-      "keys [hold_ms]", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)" },
-STEXI
-@item sendkey @var{keys}
-
-Send @var{keys} to the emulator. @var{keys} could be the name of the
-key or @code{#} followed by the raw value in either decimal or hexadecimal
-format. Use @code{-} to press several keys simultaneously. Example:
-@example
-sendkey ctrl-alt-f1
-@end example
-
-This command is useful to send keys that your graphical user interface
-intercepts at low level, such as @code{ctrl-alt-f1} in X Window.
-ETEXI
-
-    { "system_reset", "", do_system_reset,
-      "", "reset the system" },
-STEXI
-@item system_reset
-
-Reset the system.
-ETEXI
-
-    { "system_powerdown", "", do_system_powerdown,
-      "", "send system power down event" },
-STEXI
-@item system_powerdown
-
-Power down the system (if supported).
-ETEXI
-
-    { "sum", "ii", do_sum,
-      "addr size", "compute the checksum of a memory region" },
-STEXI
-@item sum @var{addr} @var{size}
-
-Compute the checksum of a memory region.
-ETEXI
-
-    { "usb_add", "s", do_usb_add,
-      "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
-STEXI
-@item usb_add @var{devname}
-
-Add the USB device @var{devname}.  For details of available devices see
-@ref{usb_devices}
-ETEXI
-
-    { "usb_del", "s", do_usb_del,
-      "device", "remove USB device 'bus.addr'" },
-STEXI
-@item usb_del @var{devname}
-
-Remove the USB device @var{devname} from the QEMU virtual USB
-hub. @var{devname} has the syntax @code{bus.addr}. Use the monitor
-command @code{info usb} to see the devices you can remove.
-ETEXI
-
-    { "cpu", "i", do_cpu_set,
-      "index", "set the default CPU" },
-STEXI
-Set the default CPU.
-ETEXI
-
-    { "mouse_move", "sss?", do_mouse_move,
-      "dx dy [dz]", "send mouse move events" },
-STEXI
-@item mouse_move @var{dx} @var{dy} [@var{dz}]
-Move the active mouse to the specified coordinates @var{dx} @var{dy}
-with optional scroll axis @var{dz}.
-ETEXI
-
-    { "mouse_button", "i", do_mouse_button,
-      "state", "change mouse button state (1=L, 2=M, 4=R)" },
-STEXI
-@item mouse_button @var{val}
-Change the active mouse button state @var{val} (1=L, 2=M, 4=R).
-ETEXI
-
-    { "mouse_set", "i", do_mouse_set,
-      "index", "set which mouse device receives events" },
-STEXI
-@item mouse_set @var{index}
-Set which mouse device receives events at given @var{index}, index
-can be obtained with
-@example
-info mice
-@end example
-ETEXI
-
-#ifdef HAS_AUDIO
-    { "wavcapture", "si?i?i?", do_wav_capture,
-      "path [frequency [bits [channels]]]",
-      "capture audio to a wave file (default frequency=44100 bits=16 channels=2)" },
-#endif
-STEXI
-@item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels}]]]
-Capture audio into @var{filename}. Using sample rate @var{frequency}
-bits per sample @var{bits} and number of channels @var{channels}.
-
-Defaults:
-@itemize @minus
-@item Sample rate = 44100 Hz - CD quality
-@item Bits = 16
-@item Number of channels = 2 - Stereo
-@end itemize
-ETEXI
-
-#ifdef HAS_AUDIO
-    { "stopcapture", "i", do_stop_capture,
-      "capture index", "stop capture" },
-#endif
-STEXI
-@item stopcapture @var{index}
-Stop capture with a given @var{index}, index can be obtained with
-@example
-info capture
-@end example
-ETEXI
-
-    { "memsave", "lis", do_memory_save,
-      "addr size file", "save to disk virtual memory dump starting at 'addr' of size 'size'", },
-STEXI
-@item memsave @var{addr} @var{size} @var{file}
-save to disk virtual memory dump starting at @var{addr} of size @var{size}.
-ETEXI
-
-    { "pmemsave", "lis", do_physical_memory_save,
-      "addr size file", "save to disk physical memory dump starting at 'addr' of size 'size'", },
-STEXI
-@item pmemsave @var{addr} @var{size} @var{file}
-save to disk physical memory dump starting at @var{addr} of size @var{size}.
-ETEXI
-
-    { "boot_set", "s", do_boot_set,
-      "bootdevice", "define new values for the boot device list" },
-STEXI
-@item boot_set @var{bootdevicelist}
-
-Define new values for the boot device list. Those values will override
-the values specified on the command line through the @code{-boot} option.
-
-The values that can be specified here depend on the machine type, but are
-the same that can be specified in the @code{-boot} command line option.
-ETEXI
-
-#if defined(TARGET_I386)
-    { "nmi", "i", do_inject_nmi,
-      "cpu", "inject an NMI on the given CPU", },
-#endif
-STEXI
-@item nmi @var{cpu}
-Inject an NMI on the given CPU (x86 only).
-ETEXI
-
-    { "migrate", "-ds", do_migrate,
-      "[-d] uri", "migrate to URI (using -d to not wait for completion)" },
-STEXI
-@item migrate [-d] @var{uri}
-Migrate to @var{uri} (using -d to not wait for completion).
-ETEXI
-
-    { "migrate_cancel", "", do_migrate_cancel,
-      "", "cancel the current VM migration" },
-STEXI
-@item migrate_cancel
-Cancel the current VM migration.
-ETEXI
-
-    { "migrate_set_speed", "s", do_migrate_set_speed,
-      "value", "set maximum speed (in bytes) for migrations" },
-STEXI
-@item migrate_set_speed @var{value}
-Set maximum speed to @var{value} (in bytes) for migrations.
-ETEXI
-
-    { "migrate_set_downtime", "s", do_migrate_set_downtime,
-      "value", "set maximum tolerated downtime (in seconds) for migrations" },
-
-STEXI
-@item migrate_set_downtime @var{second}
-Set maximum tolerated downtime (in seconds) for migration.
-ETEXI
-#ifndef CONFIG_ANDROID
-#if defined(TARGET_I386)
-    { "drive_add", "ss", drive_hot_add, "pci_addr=[[<domain>:]<bus>:]<slot>\n"
-                                         "[file=file][,if=type][,bus=n]\n"
-                                        "[,unit=m][,media=d][index=i]\n"
-                                        "[,cyls=c,heads=h,secs=s[,trans=t]]\n"
-                                        "[snapshot=on|off][,cache=on|off]",
-                                        "add drive to PCI storage controller" },
-#endif
-#endif
-STEXI
-@item drive_add
-Add drive to PCI storage controller.
-ETEXI
-
-#ifndef CONFIG_ANDROID
-#if defined(TARGET_I386)
-    { "pci_add", "sss", pci_device_hot_add, "pci_addr=auto|[[<domain>:]<bus>:]<slot> nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...", "hot-add PCI device" },
-#endif
-#endif
-
-STEXI
-@item pci_add
-Hot-add PCI device.
-ETEXI
-
-#ifndef CONFIG_ANDROID
-#if defined(TARGET_I386)
-    { "pci_del", "s", pci_device_hot_remove, "pci_addr=[[<domain>:]<bus>:]<slot>", "hot remove PCI device" },
-#endif
-#endif
-STEXI
-@item pci_del
-Hot remove PCI device.
-ETEXI
-
-    { "host_net_add", "ss?", net_host_device_add,
-      "tap|user|socket|vde|dump [options]", "add host VLAN client" },
-STEXI
-@item host_net_add
-Add host VLAN client.
-ETEXI
-
-    { "host_net_remove", "is", net_host_device_remove,
-      "vlan_id name", "remove host VLAN client" },
-STEXI
-@item host_net_remove
-Remove host VLAN client.
-ETEXI
-
-#ifdef CONFIG_SLIRP
-    { "host_net_redir", "ss?", net_slirp_redir,
-      "[tcp|udp]:host-port:[guest-host]:guest-port", "redirect TCP or UDP connections from host to guest (requires -net user)\n"
-      "host_net_redir remove [tcp:|udp:]host-port -- remove redirection\n"
-      "host_net_redir list -- show all redirections" },
-#endif
-STEXI
-@item host_net_redir
-Redirect TCP or UDP connections from host to guest (requires -net user).
-ETEXI
-
-    { "balloon", "i", do_balloon,
-      "target", "request VM to change it's memory allocation (in MB)" },
-STEXI
-@item balloon @var{value}
-Request VM to change its memory allocation to @var{value} (in MB).
-ETEXI
-
-    { "set_link", "ss", do_set_link,
-      "name up|down", "change the link status of a network adapter" },
-STEXI
-@item set_link @var{name} [up|down]
-Set link @var{name} up or down.
-ETEXI
-
-    { "watchdog_action", "s", do_watchdog_action,
-      "[reset|shutdown|poweroff|pause|debug|none]", "change watchdog action" },
-STEXI
-@item watchdog_action
-Change watchdog action.
-ETEXI
-
-    { "acl", "sss?i?", do_acl, "<command> <aclname> [<match> [<index>]]\n",
-                               "acl show vnc.username\n"
-                               "acl policy vnc.username deny\n"
-                               "acl allow vnc.username fred\n"
-                               "acl deny vnc.username bob\n"
-                               "acl reset vnc.username\n" },
-STEXI
-@item acl @var{subcommand} @var{aclname} @var{match} @var{index}
-
-Manage access control lists for network services. There are currently
-two named access control lists, @var{vnc.x509dname} and @var{vnc.username}
-matching on the x509 client certificate distinguished name, and SASL
-username respectively.
-
-@table @option
-@item acl show <aclname>
-list all the match rules in the access control list, and the default
-policy
-@item acl policy <aclname> @code{allow|deny}
-set the default access control list policy, used in the event that
-none of the explicit rules match. The default policy at startup is
-always @code{deny}
-@item acl allow <aclname> <match> [<index>]
-add a match to the access control list, allowing access. The match will
-normally be an exact username or x509 distinguished name, but can
-optionally include wildcard globs. eg @code{*@@EXAMPLE.COM} to allow
-all users in the @code{EXAMPLE.COM} kerberos realm. The match will
-normally be appended to the end of the ACL, but can be inserted
-earlier in the list if the optional @code{index} parameter is supplied.
-@item acl deny <aclname> <match> [<index>]
-add a match to the access control list, denying access. The match will
-normally be an exact username or x509 distinguished name, but can
-optionally include wildcard globs. eg @code{*@@EXAMPLE.COM} to allow
-all users in the @code{EXAMPLE.COM} kerberos realm. The match will
-normally be appended to the end of the ACL, but can be inserted
-earlier in the list if the optional @code{index} parameter is supplied.
-@item acl remove <aclname> <match>
-remove the specified match rule from the access control list.
-@item acl reset <aclname>
-remove all matches from the access control list, and set the default
-policy back to @code{deny}.
-@end table
-ETEXI
-
-#if defined(TARGET_I386)
-    { "mce", "iillll", do_inject_mce, "cpu bank status mcgstatus addr misc", "inject a MCE on the given CPU"},
-#endif
-STEXI
-@item mce @var{cpu} @var{bank} @var{status} @var{mcgstatus} @var{addr} @var{misc}
-Inject an MCE on the given CPU (x86 only).
-ETEXI
-
-STEXI
-@end table
-ETEXI
diff --git a/qemu-options.hx b/qemu-options.hx
index b2ecf1b..48e9782 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1328,25 +1328,6 @@
 Set the filename for the BIOS.
 ETEXI
 
-#ifdef CONFIG_KQEMU
-DEF("kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu, \
-    "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n")
-#endif
-STEXI
-@item -kernel-kqemu
-Enable KQEMU full virtualization (default is user mode only).
-ETEXI
-
-#ifdef CONFIG_KQEMU
-DEF("no-kqemu", 0, QEMU_OPTION_no_kqemu, \
-    "-no-kqemu       disable KQEMU kernel module usage\n")
-#endif
-STEXI
-@item -no-kqemu
-Disable KQEMU kernel module usage. KQEMU options are only available if
-KQEMU support is enabled when compiling.
-ETEXI
-
 #ifdef CONFIG_KVM
 DEF("enable-kvm", 0, QEMU_OPTION_enable_kvm, \
     "-enable-kvm     enable KVM full virtualization support\n")
@@ -1687,19 +1668,9 @@
     "-old-param      old param mode\n")
 #endif
 
-#ifdef CONFIG_TRACE
-DEF("tracing", HAS_ARG, QEMU_OPTION_tracing, \
-    "-tracing on|off enable/disable tracing\n")
-
-DEF("trace", HAS_ARG, QEMU_OPTION_trace, \
-    "-trace name\n" \
-    "                set trace directory\n")
-
 DEF("nand", HAS_ARG, QEMU_OPTION_nand, \
     "-nand <params>  enable NAND Flash partition\n")
 
-#endif /* CONFIG_TRACE */
-
 #ifdef CONFIG_ANDROID
 
 DEF("savevm-on-exit", HAS_ARG, QEMU_OPTION_savevm_on_exit, \
diff --git a/qemu-timer.c b/qemu-timer.c
index 25127e8..cbb119d 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -39,31 +39,8 @@
 #include <sys/param.h>
 #endif
 
-#ifdef __linux__
-#include <sys/ioctl.h>
-#include <linux/rtc.h>
-/* For the benefit of older linux systems which don't supply it,
-   we use a local copy of hpet.h. */
-/* #include <linux/hpet.h> */
-#include "hw/timer/hpet.h"
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#include <mmsystem.h>
-#endif
-
 #include "qemu/timer.h"
 
-/* Conversion factor from emulated instructions to virtual clock ticks.  */
-int icount_time_shift;
-/* Arbitrarily pick 1MIPS as the minimum allowable speed.  */
-#define MAX_ICOUNT_SHIFT 10
-/* Compensate for varying guest execution speed.  */
-int64_t qemu_icount_bias;
-static QEMUTimer *icount_rt_timer;
-static QEMUTimer *icount_vm_timer;
-
 /***********************************************************/
 /* guest cycle counter */
 
@@ -107,6 +84,10 @@
 
 TimersState timers_state;
 
+void qemu_timer_register_savevm(void) {
+    register_savevm("timer", 0, 2, timer_save, timer_load, &timers_state);
+}
+
 /* return the host CPU cycle counter and handle stop/restart */
 int64_t cpu_get_ticks(void)
 {
@@ -129,7 +110,7 @@
 }
 
 /* return the host CPU monotonic timer and handle stop/restart */
-static int64_t cpu_get_clock(void)
+int64_t cpu_get_clock(void)
 {
     int64_t ti;
     if (!timers_state.cpu_ticks_enabled) {
@@ -140,22 +121,6 @@
     }
 }
 
-#ifndef CONFIG_IOTHREAD
-static int64_t qemu_icount_delta(void)
-{
-    if (!use_icount) {
-        return 5000 * (int64_t) 1000000;
-    } else if (use_icount == 1) {
-        /* When not using an adaptive execution frequency
-           we tend to get badly out of sync with real time,
-           so just delay for a reasonable amount of time.  */
-        return 0;
-    } else {
-        return cpu_get_icount() - cpu_get_clock();
-    }
-}
-#endif
-
 /* enable cpu_get_ticks() */
 void cpu_enable_ticks(void)
 {
@@ -180,10 +145,6 @@
 /***********************************************************/
 /* timers */
 
-#define QEMU_CLOCK_REALTIME 0
-#define QEMU_CLOCK_VIRTUAL  1
-#define QEMU_CLOCK_HOST     2
-
 struct QEMUClock {
     int type;
     int enabled;
@@ -191,6 +152,10 @@
     QEMUTimer *warp_timer;
 };
 
+QEMUTimer* qemu_clock_get_warp_timer(QEMUClock* clock) {
+    return clock ? clock->warp_timer : NULL;
+}
+
 struct QEMUTimer {
     QEMUClock *clock;
     int64_t expire_time;	/* in nanoseconds */
@@ -200,232 +165,16 @@
     struct QEMUTimer *next;
 };
 
-struct qemu_alarm_timer {
-    char const *name;
-    int (*start)(struct qemu_alarm_timer *t);
-    void (*stop)(struct qemu_alarm_timer *t);
-    void (*rearm)(struct qemu_alarm_timer *t);
-#if defined(__linux__)
-    int fd;
-    timer_t timer;
-#elif defined(_WIN32)
-    HANDLE timer;
-#endif
-    char expired;
-    char pending;
-};
-
-static struct qemu_alarm_timer *alarm_timer;
-
 static bool qemu_timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
 {
     return timer_head && (timer_head->expire_time <= current_time);
 }
 
-int qemu_alarm_pending(void)
-{
-    return alarm_timer->pending;
-}
-
-static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
-{
-    return !!t->rearm;
-}
-
-static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
-{
-    if (!alarm_has_dynticks(t))
-        return;
-
-    t->rearm(t);
-}
-
-/* TODO: MIN_TIMER_REARM_NS should be optimized */
-#define MIN_TIMER_REARM_NS 250000
-
-#ifdef _WIN32
-
-static int mm_start_timer(struct qemu_alarm_timer *t);
-static void mm_stop_timer(struct qemu_alarm_timer *t);
-static void mm_rearm_timer(struct qemu_alarm_timer *t);
-
-static int win32_start_timer(struct qemu_alarm_timer *t);
-static void win32_stop_timer(struct qemu_alarm_timer *t);
-static void win32_rearm_timer(struct qemu_alarm_timer *t);
-
-#else
-
-static int unix_start_timer(struct qemu_alarm_timer *t);
-static void unix_stop_timer(struct qemu_alarm_timer *t);
-
-#ifdef __linux__
-
-static int dynticks_start_timer(struct qemu_alarm_timer *t);
-static void dynticks_stop_timer(struct qemu_alarm_timer *t);
-static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
-
-static int hpet_start_timer(struct qemu_alarm_timer *t);
-static void hpet_stop_timer(struct qemu_alarm_timer *t);
-
-static int rtc_start_timer(struct qemu_alarm_timer *t);
-static void rtc_stop_timer(struct qemu_alarm_timer *t);
-
-#endif /* __linux__ */
-
-#endif /* _WIN32 */
-
-/* Correlation between real and virtual time is always going to be
-   fairly approximate, so ignore small variation.
-   When the guest is idle real and virtual time will be aligned in
-   the IO wait loop.  */
-#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10)
-
-static void icount_adjust(void)
-{
-    int64_t cur_time;
-    int64_t cur_icount;
-    int64_t delta;
-    static int64_t last_delta;
-    /* If the VM is not running, then do nothing.  */
-    if (!vm_running)
-        return;
-
-    cur_time = cpu_get_clock();
-    cur_icount = qemu_get_clock_ns(vm_clock);
-    delta = cur_icount - cur_time;
-    /* FIXME: This is a very crude algorithm, somewhat prone to oscillation.  */
-    if (delta > 0
-        && last_delta + ICOUNT_WOBBLE < delta * 2
-        && icount_time_shift > 0) {
-        /* The guest is getting too far ahead.  Slow time down.  */
-        icount_time_shift--;
-    }
-    if (delta < 0
-        && last_delta - ICOUNT_WOBBLE > delta * 2
-        && icount_time_shift < MAX_ICOUNT_SHIFT) {
-        /* The guest is getting too far behind.  Speed time up.  */
-        icount_time_shift++;
-    }
-    last_delta = delta;
-    qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
-}
-
-static void icount_adjust_rt(void * opaque)
-{
-    qemu_mod_timer(icount_rt_timer,
-                   qemu_get_clock_ms(rt_clock) + 1000);
-    icount_adjust();
-}
-
-static void icount_adjust_vm(void * opaque)
-{
-    qemu_mod_timer(icount_vm_timer,
-                   qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10);
-    icount_adjust();
-}
-
-int64_t qemu_icount_round(int64_t count)
-{
-    return (count + (1 << icount_time_shift) - 1) >> icount_time_shift;
-}
-
-static struct qemu_alarm_timer alarm_timers[] = {
-#ifndef _WIN32
-#ifdef __linux__
-    /* HPET - if available - is preferred */
-    {"hpet", hpet_start_timer, hpet_stop_timer, NULL},
-    /* ...otherwise try RTC */
-    {"rtc", rtc_start_timer, rtc_stop_timer, NULL},
-#endif
-    {"unix", unix_start_timer, unix_stop_timer, NULL},
-#ifdef __linux__
-    /* on Linux, the 'dynticks' clock sometimes doesn't work
-     * properly. this results in the UI freezing while emulation
-     * continues, for several seconds... So move it to the end
-     * of the list. */
-    {"dynticks", dynticks_start_timer,
-     dynticks_stop_timer, dynticks_rearm_timer},
-#endif
-#else
-    {"mmtimer", mm_start_timer, mm_stop_timer, NULL},
-    {"mmtimer2", mm_start_timer, mm_stop_timer, mm_rearm_timer},
-    {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
-    {"win32", win32_start_timer, win32_stop_timer, NULL},
-#endif
-    {NULL, }
-};
-
-static void show_available_alarms(void)
-{
-    int i;
-
-    printf("Available alarm timers, in order of precedence:\n");
-    for (i = 0; alarm_timers[i].name; i++)
-        printf("%s\n", alarm_timers[i].name);
-}
-
-void configure_alarms(char const *opt)
-{
-    int i;
-    int cur = 0;
-    int count = ARRAY_SIZE(alarm_timers) - 1;
-    char *arg;
-    char *name;
-    struct qemu_alarm_timer tmp;
-
-    if (!strcmp(opt, "?")) {
-        show_available_alarms();
-        exit(0);
-    }
-
-    arg = g_strdup(opt);
-
-    /* Reorder the array */
-    name = strtok(arg, ",");
-    while (name) {
-        for (i = 0; i < count && alarm_timers[i].name; i++) {
-            if (!strcmp(alarm_timers[i].name, name))
-                break;
-        }
-
-        if (i == count) {
-            fprintf(stderr, "Unknown clock %s\n", name);
-            goto next;
-        }
-
-        if (i < cur)
-            /* Ignore */
-            goto next;
-
-	/* Swap */
-        tmp = alarm_timers[i];
-        alarm_timers[i] = alarm_timers[cur];
-        alarm_timers[cur] = tmp;
-
-        cur++;
-next:
-        name = strtok(NULL, ",");
-    }
-
-    g_free(arg);
-
-    if (cur) {
-        /* Disable remaining timers */
-        for (i = cur; i < count; i++)
-            alarm_timers[i].name = NULL;
-    } else {
-        show_available_alarms();
-        exit(1);
-    }
-}
-
-#define QEMU_NUM_CLOCKS 3
-
 QEMUClock *rt_clock;
 QEMUClock *vm_clock;
 QEMUClock *host_clock;
 
-static QEMUTimer *active_timers[QEMU_NUM_CLOCKS];
+QEMUTimer *active_timers[QEMU_NUM_CLOCKS];
 
 static QEMUClock *qemu_new_clock(int type)
 {
@@ -441,88 +190,23 @@
     clock->enabled = enabled;
 }
 
-static int64_t vm_clock_warp_start;
-
-static void icount_warp_rt(void *opaque)
-{
-    if (vm_clock_warp_start == -1) {
-        return;
-    }
-
-    if (vm_running) {
-        int64_t clock = qemu_get_clock_ns(rt_clock);
-        int64_t warp_delta = clock - vm_clock_warp_start;
-        if (use_icount == 1) {
-            qemu_icount_bias += warp_delta;
-        } else {
-            /*
-             * In adaptive mode, do not let the vm_clock run too
-             * far ahead of real time.
-             */
-            int64_t cur_time = cpu_get_clock();
-            int64_t cur_icount = qemu_get_clock_ns(vm_clock);
-            int64_t delta = cur_time - cur_icount;
-            qemu_icount_bias += MIN(warp_delta, delta);
-        }
-        if (qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],
-                               qemu_get_clock_ns(vm_clock))) {
-            qemu_notify_event();
-        }
-    }
-    vm_clock_warp_start = -1;
+int qemu_clock_has_active_timer(QEMUClock* clock) {
+    return active_timers[clock->type] != NULL;
 }
 
-void qemu_clock_warp(QEMUClock *clock)
-{
-    int64_t deadline;
+int64_t qemu_clock_next_deadline(QEMUClock* clock) {
+    /* To avoid problems with overflow limit this to 2^32.  */
+    int64_t delta = INT32_MAX;
 
-    if (!clock->warp_timer) {
-        return;
+    if (active_timers[clock->type]) {
+        delta = active_timers[clock->type]->expire_time -
+                qemu_get_clock_ns(clock);
     }
 
-    /*
-     * There are too many global variables to make the "warp" behavior
-     * applicable to other clocks.  But a clock argument removes the
-     * need for if statements all over the place.
-     */
-    assert(clock == vm_clock);
+    if (delta < 0)
+        delta = 0;
 
-    /*
-     * If the CPUs have been sleeping, advance the vm_clock timer now.  This
-     * ensures that the deadline for the timer is computed correctly below.
-     * This also makes sure that the insn counter is synchronized before the
-     * CPU starts running, in case the CPU is woken by an event other than
-     * the earliest vm_clock timer.
-     */
-    icount_warp_rt(NULL);
-    if (qemu_cpu_has_work(cpu_single_env) || !active_timers[clock->type]) {
-        qemu_del_timer(clock->warp_timer);
-        return;
-    }
-
-    vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
-    deadline = qemu_next_icount_deadline();
-    if (deadline > 0) {
-        /*
-         * Ensure the vm_clock proceeds even when the virtual CPU goes to
-         * sleep.  Otherwise, the CPU might be waiting for a future timer
-         * interrupt to wake it up, but the interrupt never comes because
-         * the vCPU isn't running any insns and thus doesn't advance the
-         * vm_clock.
-         *
-         * An extreme solution for this problem would be to never let VCPUs
-         * sleep in icount mode if there is a pending vm_clock timer; rather
-         * time could just advance to the next vm_clock event.  Instead, we
-         * do stop VCPUs and only advance vm_clock after some "real" time,
-         * (related to the time left until the next event) has passed.  This
-         * rt_clock timer will do this.  This avoids that the warps are too
-         * visible externally---for example, you will not be sending network
-         * packets continously instead of every 100ms.
-         */
-        qemu_mod_timer(clock->warp_timer, vm_clock_warp_start + deadline);
-    } else {
-        qemu_notify_event();
-    }
+    return delta;
 }
 
 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
@@ -588,14 +272,7 @@
 
     /* Rearm if necessary  */
     if (pt == &active_timers[ts->clock->type]) {
-        if (!alarm_timer->pending) {
-            qemu_rearm_alarm_timer(alarm_timer);
-        }
-        /* Interrupt execution to force deadline recalculation.  */
-        qemu_clock_warp(ts->clock);
-        if (use_icount) {
-            qemu_notify_event();
-    }
+        qemu_adjust_clock(ts->clock);
     }
 }
 
@@ -621,7 +298,7 @@
     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;
@@ -727,662 +404,3 @@
     }
 };
 #endif
-
-void configure_icount(const char *option)
-{
-    register_savevm("timer", 0, 2, timer_save, timer_load, &timers_state);
-
-    if (!option)
-        return;
-
-#ifdef CONFIG_IOTHREAD
-    vm_clock->warp_timer = qemu_new_timer_ns(rt_clock, icount_warp_rt, NULL);
-#endif
-
-    if (strcmp(option, "auto") != 0) {
-        icount_time_shift = strtol(option, NULL, 0);
-        use_icount = 1;
-        return;
-    }
-
-    use_icount = 2;
-
-    /* 125MIPS seems a reasonable initial guess at the guest speed.
-       It will be corrected fairly quickly anyway.  */
-    icount_time_shift = 3;
-
-    /* Have both realtime and virtual time triggers for speed adjustment.
-       The realtime trigger catches emulated time passing too slowly,
-       the virtual time trigger catches emulated time passing too fast.
-       Realtime triggers occur even when idle, so use them less frequently
-       than VM triggers.  */
-    icount_rt_timer = qemu_new_timer_ms(rt_clock, icount_adjust_rt, NULL);
-    qemu_mod_timer(icount_rt_timer,
-                   qemu_get_clock_ms(rt_clock) + 1000);
-    icount_vm_timer = qemu_new_timer_ns(vm_clock, icount_adjust_vm, NULL);
-    qemu_mod_timer(icount_vm_timer,
-                   qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10);
-}
-
-void qemu_run_all_timers(void)
-{
-    alarm_timer->pending = 0;
-
-    /* rearm timer, if not periodic */
-    if (alarm_timer->expired) {
-        alarm_timer->expired = 0;
-        qemu_rearm_alarm_timer(alarm_timer);
-    }
-
-    /* vm time timers */
-    if (vm_running) {
-        qemu_run_timers(vm_clock);
-    }
-
-    qemu_run_timers(rt_clock);
-    qemu_run_timers(host_clock);
-}
-
-static int timer_alarm_pending = 1;
-
-int qemu_timer_alarm_pending(void)
-{
-    int ret = timer_alarm_pending;
-    timer_alarm_pending = 0;
-    return ret;
-}
-
-
-static int64_t qemu_next_alarm_deadline(void);
-
-#ifdef _WIN32
-static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
-#else
-static void host_alarm_handler(int host_signum)
-#endif
-{
-    struct qemu_alarm_timer *t = alarm_timer;
-    if (!t)
-	return;
-
-#if 0
-#define DISP_FREQ 1000
-    {
-        static int64_t delta_min = INT64_MAX;
-        static int64_t delta_max, delta_cum, last_clock, delta, ti;
-        static int count;
-        ti = qemu_get_clock_ns(vm_clock);
-        if (last_clock != 0) {
-            delta = ti - last_clock;
-            if (delta < delta_min)
-                delta_min = delta;
-            if (delta > delta_max)
-                delta_max = delta;
-            delta_cum += delta;
-            if (++count == DISP_FREQ) {
-                printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
-                       muldiv64(delta_min, 1000000, get_ticks_per_sec()),
-                       muldiv64(delta_max, 1000000, get_ticks_per_sec()),
-                       muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()),
-                       (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ));
-                count = 0;
-                delta_min = INT64_MAX;
-                delta_max = 0;
-                delta_cum = 0;
-            }
-        }
-        last_clock = ti;
-    }
-#endif
-    if (alarm_has_dynticks(t) ||
-        qemu_next_alarm_deadline () <= 0) {
-        t->expired = alarm_has_dynticks(t);
-        t->pending = 1;
-        timer_alarm_pending = 1;
-        qemu_notify_event();
-    }
-}
-
-int64_t qemu_next_icount_deadline(void)
-{
-    /* To avoid problems with overflow limit this to 2^32.  */
-    int64_t delta = INT32_MAX;
-
-    assert(use_icount);
-    if (active_timers[QEMU_CLOCK_VIRTUAL]) {
-        delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
-                     qemu_get_clock_ns(vm_clock);
-    }
-
-    if (delta < 0)
-        delta = 0;
-
-    return delta;
-}
-
-static int64_t qemu_next_alarm_deadline(void)
-{
-    int64_t delta;
-    int64_t rtdelta;
-
-    if (!use_icount && active_timers[QEMU_CLOCK_VIRTUAL]) {
-        delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
-                     qemu_get_clock_ns(vm_clock);
-    } else {
-        delta = INT32_MAX;
-    }
-    if (active_timers[QEMU_CLOCK_HOST]) {
-        int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
-                 qemu_get_clock_ns(host_clock);
-        if (hdelta < delta)
-            delta = hdelta;
-    }
-    if (active_timers[QEMU_CLOCK_REALTIME]) {
-        rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time -
-                 qemu_get_clock_ns(rt_clock));
-        if (rtdelta < delta)
-            delta = rtdelta;
-    }
-
-    return delta;
-}
-
-#if defined(__linux__)
-
-#define RTC_FREQ 1024
-
-static void enable_sigio_timer(int fd)
-{
-    struct sigaction act;
-
-    /* timer signal */
-    sigfillset(&act.sa_mask);
-    act.sa_flags = 0;
-    act.sa_handler = host_alarm_handler;
-
-    sigaction(SIGIO, &act, NULL);
-    fcntl_setfl(fd, O_ASYNC);
-    fcntl(fd, F_SETOWN, getpid());
-}
-
-static int hpet_start_timer(struct qemu_alarm_timer *t)
-{
-    struct hpet_info info;
-    int r, fd;
-
-    fd = open("/dev/hpet", O_RDONLY);
-    if (fd < 0)
-        return -1;
-
-    /* Set frequency */
-    r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
-    if (r < 0) {
-        fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
-                "error, but for better emulation accuracy type:\n"
-                "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
-        goto fail;
-    }
-
-    /* Check capabilities */
-    r = ioctl(fd, HPET_INFO, &info);
-    if (r < 0)
-        goto fail;
-
-    /* Enable periodic mode */
-    r = ioctl(fd, HPET_EPI, 0);
-    if (info.hi_flags && (r < 0))
-        goto fail;
-
-    /* Enable interrupt */
-    r = ioctl(fd, HPET_IE_ON, 0);
-    if (r < 0)
-        goto fail;
-
-    enable_sigio_timer(fd);
-    t->fd = fd;
-
-    return 0;
-fail:
-    close(fd);
-    return -1;
-}
-
-static void hpet_stop_timer(struct qemu_alarm_timer *t)
-{
-    int fd = t->fd;
-
-    close(fd);
-}
-
-static int rtc_start_timer(struct qemu_alarm_timer *t)
-{
-    int rtc_fd;
-    unsigned long current_rtc_freq = 0;
-
-    TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
-    if (rtc_fd < 0)
-        return -1;
-    ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
-    if (current_rtc_freq != RTC_FREQ &&
-        ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
-        fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
-                "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
-                "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
-        goto fail;
-    }
-    if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
-    fail:
-        close(rtc_fd);
-        return -1;
-    }
-
-    enable_sigio_timer(rtc_fd);
-
-    t->fd = rtc_fd;
-
-    return 0;
-}
-
-static void rtc_stop_timer(struct qemu_alarm_timer *t)
-{
-    int rtc_fd = t->fd;
-
-    close(rtc_fd);
-}
-
-static int dynticks_start_timer(struct qemu_alarm_timer *t)
-{
-    struct sigevent ev;
-    timer_t host_timer;
-    struct sigaction act;
-
-    sigfillset(&act.sa_mask);
-    act.sa_flags = 0;
-    act.sa_handler = host_alarm_handler;
-
-    sigaction(SIGALRM, &act, NULL);
-
-    /*
-     * Initialize ev struct to 0 to avoid valgrind complaining
-     * about uninitialized data in timer_create call
-     */
-    memset(&ev, 0, sizeof(ev));
-    ev.sigev_value.sival_int = 0;
-    ev.sigev_notify = SIGEV_SIGNAL;
-    ev.sigev_signo = SIGALRM;
-
-    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
-        perror("timer_create");
-
-        /* disable dynticks */
-        fprintf(stderr, "Dynamic Ticks disabled\n");
-
-        return -1;
-    }
-
-    t->timer = host_timer;
-
-    return 0;
-}
-
-static void dynticks_stop_timer(struct qemu_alarm_timer *t)
-{
-    timer_t host_timer = t->timer;
-
-    timer_delete(host_timer);
-}
-
-static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
-{
-    timer_t host_timer = t->timer;
-    struct itimerspec timeout;
-    int64_t nearest_delta_ns = INT64_MAX;
-    int64_t current_ns;
-
-    assert(alarm_has_dynticks(t));
-    if (!active_timers[QEMU_CLOCK_REALTIME] &&
-        !active_timers[QEMU_CLOCK_VIRTUAL] &&
-        !active_timers[QEMU_CLOCK_HOST])
-        return;
-
-    nearest_delta_ns = qemu_next_alarm_deadline();
-    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
-        nearest_delta_ns = MIN_TIMER_REARM_NS;
-
-    /* check whether a timer is already running */
-    if (timer_gettime(host_timer, &timeout)) {
-        perror("gettime");
-        fprintf(stderr, "Internal timer error: aborting\n");
-        exit(1);
-    }
-    current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
-    if (current_ns && current_ns <= nearest_delta_ns)
-        return;
-
-    timeout.it_interval.tv_sec = 0;
-    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
-    timeout.it_value.tv_sec =  nearest_delta_ns / 1000000000;
-    timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
-    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
-        perror("settime");
-        fprintf(stderr, "Internal timer error: aborting\n");
-        exit(1);
-    }
-}
-
-#endif /* defined(__linux__) */
-
-#if !defined(_WIN32)
-
-static int unix_start_timer(struct qemu_alarm_timer *t)
-{
-    struct sigaction act;
-    struct itimerval itv;
-    int err;
-
-    /* timer signal */
-    sigfillset(&act.sa_mask);
-    act.sa_flags = 0;
-    act.sa_handler = host_alarm_handler;
-
-    sigaction(SIGALRM, &act, NULL);
-
-    itv.it_interval.tv_sec = 0;
-    /* for i386 kernel 2.6 to get 1 ms */
-    itv.it_interval.tv_usec = 999;
-    itv.it_value.tv_sec = 0;
-    itv.it_value.tv_usec = 10 * 1000;
-
-    err = setitimer(ITIMER_REAL, &itv, NULL);
-    if (err)
-        return -1;
-
-    return 0;
-}
-
-static void unix_stop_timer(struct qemu_alarm_timer *t)
-{
-    struct itimerval itv;
-
-    memset(&itv, 0, sizeof(itv));
-    setitimer(ITIMER_REAL, &itv, NULL);
-}
-
-#endif /* !defined(_WIN32) */
-
-
-#ifdef _WIN32
-
-static MMRESULT mm_timer;
-static unsigned mm_period;
-
-static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
-                                      DWORD_PTR dwUser, DWORD_PTR dw1,
-                                      DWORD_PTR dw2)
-{
-    struct qemu_alarm_timer *t = alarm_timer;
-    if (!t) {
-        return;
-    }
-    if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) {
-        t->expired = alarm_has_dynticks(t);
-        t->pending = 1;
-        qemu_notify_event();
-    }
-}
-
-static int mm_start_timer(struct qemu_alarm_timer *t)
-{
-    TIMECAPS tc;
-    UINT flags;
-
-    memset(&tc, 0, sizeof(tc));
-    timeGetDevCaps(&tc, sizeof(tc));
-
-    mm_period = tc.wPeriodMin;
-    timeBeginPeriod(mm_period);
-
-    flags = TIME_CALLBACK_FUNCTION;
-    if (alarm_has_dynticks(t)) {
-        flags |= TIME_ONESHOT;
-    } else {
-        flags |= TIME_PERIODIC;
-    }
-
-    mm_timer = timeSetEvent(1,                  /* interval (ms) */
-                            mm_period,          /* resolution */
-                            mm_alarm_handler,   /* function */
-                            (DWORD_PTR)t,       /* parameter */
-                        flags);
-
-    if (!mm_timer) {
-        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
-                GetLastError());
-        timeEndPeriod(mm_period);
-        return -1;
-    }
-
-    return 0;
-}
-
-static void mm_stop_timer(struct qemu_alarm_timer *t)
-{
-    timeKillEvent(mm_timer);
-    timeEndPeriod(mm_period);
-}
-
-static void mm_rearm_timer(struct qemu_alarm_timer *t)
-{
-    int nearest_delta_ms;
-
-    assert(alarm_has_dynticks(t));
-    if (!active_timers[QEMU_CLOCK_REALTIME] &&
-        !active_timers[QEMU_CLOCK_VIRTUAL] &&
-        !active_timers[QEMU_CLOCK_HOST]) {
-        return;
-    }
-
-    timeKillEvent(mm_timer);
-
-    nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
-    if (nearest_delta_ms < 1) {
-        nearest_delta_ms = 1;
-    }
-    mm_timer = timeSetEvent(nearest_delta_ms,
-                            mm_period,
-                            mm_alarm_handler,
-                            (DWORD_PTR)t,
-                            TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
-
-    if (!mm_timer) {
-        fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
-                GetLastError());
-
-        timeEndPeriod(mm_period);
-        exit(1);
-    }
-}
-
-static int win32_start_timer(struct qemu_alarm_timer *t)
-{
-    HANDLE hTimer;
-    BOOLEAN success;
-
-    /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
-       is zero) that has already expired, the timer is not updated.  Since
-       creating a new timer is relatively expensive, set a bogus one-hour
-       interval in the dynticks case.  */
-    success = CreateTimerQueueTimer(&hTimer,
-                          NULL,
-                          host_alarm_handler,
-                          t,
-                          1,
-                          alarm_has_dynticks(t) ? 3600000 : 1,
-                          WT_EXECUTEINTIMERTHREAD);
-
-    if (!success) {
-        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
-                GetLastError());
-        return -1;
-    }
-
-    t->timer = hTimer;
-    return 0;
-}
-
-static void win32_stop_timer(struct qemu_alarm_timer *t)
-{
-    HANDLE hTimer = t->timer;
-
-    if (hTimer) {
-        DeleteTimerQueueTimer(NULL, hTimer, NULL);
-    }
-}
-
-static void win32_rearm_timer(struct qemu_alarm_timer *t)
-{
-    HANDLE hTimer = t->timer;
-    int nearest_delta_ms;
-    BOOLEAN success;
-
-    assert(alarm_has_dynticks(t));
-    if (!active_timers[QEMU_CLOCK_REALTIME] &&
-        !active_timers[QEMU_CLOCK_VIRTUAL] &&
-        !active_timers[QEMU_CLOCK_HOST])
-        return;
-
-    nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
-    if (nearest_delta_ms < 1) {
-        nearest_delta_ms = 1;
-    }
-    success = ChangeTimerQueueTimer(NULL,
-                                    hTimer,
-                                    nearest_delta_ms,
-                                    3600000);
-
-    if (!success) {
-        fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
-                GetLastError());
-        exit(-1);
-    }
-
-}
-
-#endif /* _WIN32 */
-
-static void alarm_timer_on_change_state_rearm(void *opaque, int running, int reason)
-{
-    if (running)
-        qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque);
-}
-
-int init_timer_alarm(void)
-{
-    struct qemu_alarm_timer *t = NULL;
-    int i, err = -1;
-
-    for (i = 0; alarm_timers[i].name; i++) {
-        t = &alarm_timers[i];
-
-        err = t->start(t);
-        if (!err)
-            break;
-    }
-
-    if (err) {
-        err = -ENOENT;
-        goto fail;
-    }
-
-    /* first event is at time 0 */
-    t->pending = 1;
-    alarm_timer = t;
-    qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t);
-
-    return 0;
-
-fail:
-    return err;
-}
-
-void quit_timers(void)
-{
-    struct qemu_alarm_timer *t = alarm_timer;
-    alarm_timer = NULL;
-    t->stop(t);
-}
-
-extern int tcg_has_work(void);
-
-int qemu_calculate_timeout(void)
-{
-#ifndef CONFIG_IOTHREAD
-    int timeout;
-
-    if (!vm_running)
-        timeout = 5000;
-    else if (tcg_has_work())
-        timeout = 0;
-    else if (!use_icount) {
-#ifdef WIN32
-        /* This corresponds to the case where the emulated system is
-         * totally idle and waiting for i/o. The problem is that on
-         * Windows, the default value will prevent Windows user events
-         * to be delivered in less than 5 seconds.
-         *
-         * Upstream contains a different way to handle this, for now
-         * this hack should be sufficient until we integrate it into
-         * our tree.
-         */
-        timeout = 1000/15;  /* deliver user events every 15/th of second */
-#else
-        timeout = 5000;
-#endif
-    } else {
-     /* XXX: use timeout computed from timers */
-        int64_t add;
-        int64_t delta;
-        /* Advance virtual time to the next event.  */
-	delta = qemu_icount_delta();
-        if (delta > 0) {
-            /* If virtual time is ahead of real time then just
-               wait for IO.  */
-            timeout = (delta + 999999) / 1000000;
-        } else {
-            /* Wait for either IO to occur or the next
-               timer event.  */
-            add = qemu_next_icount_deadline();
-            /* We advance the timer before checking for IO.
-               Limit the amount we advance so that early IO
-               activity won't get the guest too far ahead.  */
-            if (add > 10000000)
-                add = 10000000;
-            delta += add;
-            qemu_icount += qemu_icount_round (add);
-            timeout = delta / 1000000;
-            if (timeout < 0)
-                timeout = 0;
-        }
-    }
-
-    return timeout;
-#else /* CONFIG_IOTHREAD */
-    return 1000;
-#endif
-}
-
-/* Return the virtual CPU time, based on the instruction counter.  */
-int64_t cpu_get_icount(void)
-{
-    int64_t icount;
-    CPUState *env = cpu_single_env;;
-
-    icount = qemu_icount;
-    if (env) {
-        if (!can_do_io(env)) {
-            fprintf(stderr, "Bad clock read\n");
-        }
-        icount -= (env->icount_decr.u16.low + env->icount_extra);
-    }
-    return qemu_icount_bias + (icount << icount_time_shift);
-}
diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
index dd04142..440df60 100644
--- a/qobject/json-lexer.c
+++ b/qobject/json-lexer.c
@@ -18,6 +18,8 @@
 #include "qemu-common.h"
 #include "qapi/qmp/json-lexer.h"
 
+#define MAX_TOKEN_SIZE (64ULL << 20)
+
 /*
  * \"([^\\\"]|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*\"
  * '([^\\']|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*'
@@ -274,7 +276,7 @@
     lexer->x = lexer->y = 0;
 }
 
-static int json_lexer_feed_char(JSONLexer *lexer, char ch)
+static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
 {
     int char_consumed, new_state;
 
@@ -299,18 +301,48 @@
         case JSON_KEYWORD:
         case JSON_STRING:
             lexer->emit(lexer, lexer->token, new_state, lexer->x, lexer->y);
+            /* fall through */
         case JSON_SKIP:
             QDECREF(lexer->token);
             lexer->token = qstring_new();
             new_state = IN_START;
             break;
         case IN_ERROR:
-            return -EINVAL;
+            /* XXX: To avoid having previous bad input leaving the parser in an
+             * unresponsive state where we consume unpredictable amounts of
+             * subsequent "good" input, percolate this error state up to the
+             * tokenizer/parser by forcing a NULL object to be emitted, then
+             * reset state.
+             *
+             * Also note that this handling is required for reliable channel
+             * negotiation between QMP and the guest agent, since chr(0xFF)
+             * is placed at the beginning of certain events to ensure proper
+             * delivery when the channel is in an unknown state. chr(0xFF) is
+             * never a valid ASCII/UTF-8 sequence, so this should reliably
+             * induce an error/flush state.
+             */
+            lexer->emit(lexer, lexer->token, JSON_ERROR, lexer->x, lexer->y);
+            QDECREF(lexer->token);
+            lexer->token = qstring_new();
+            new_state = IN_START;
+            lexer->state = new_state;
+            return 0;
         default:
             break;
         }
         lexer->state = new_state;
-    } while (!char_consumed);
+    } while (!char_consumed && !flush);
+
+    /* Do not let a single token grow to an arbitrarily large size,
+     * this is a security consideration.
+     */
+    if (lexer->token->length > MAX_TOKEN_SIZE) {
+        lexer->emit(lexer, lexer->token, lexer->state, lexer->x, lexer->y);
+        QDECREF(lexer->token);
+        lexer->token = qstring_new();
+        lexer->state = IN_START;
+    }
+
     return 0;
 }
 
@@ -321,7 +353,7 @@
     for (i = 0; i < size; i++) {
         int err;
 
-        err = json_lexer_feed_char(lexer, buffer[i]);
+        err = json_lexer_feed_char(lexer, buffer[i], false);
         if (err < 0) {
             return err;
         }
@@ -332,7 +364,7 @@
 
 int json_lexer_flush(JSONLexer *lexer)
 {
-    return lexer->state == IN_START ? 0 : json_lexer_feed_char(lexer, 0);
+    return lexer->state == IN_START ? 0 : json_lexer_feed_char(lexer, 0, true);
 }
 
 void json_lexer_destroy(JSONLexer *lexer)
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index c3d5a3a..e7947b3 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -22,9 +22,16 @@
 #include "qapi/qmp/qbool.h"
 #include "qapi/qmp/json-parser.h"
 #include "qapi/qmp/json-lexer.h"
+#include "qapi/qmp/qerror.h"
 
 typedef struct JSONParserContext
 {
+    Error *err;
+    struct {
+        QObject **buf;
+        size_t pos;
+        size_t count;
+    } tokens;
 } JSONParserContext;
 
 #define BUG_ON(cond) assert(!(cond))
@@ -38,7 +45,7 @@
  * 4) deal with premature EOI
  */
 
-static QObject *parse_value(JSONParserContext *ctxt, QList **tokens, va_list *ap);
+static QObject *parse_value(JSONParserContext *ctxt, va_list *ap);
 
 /**
  * Token manipulators
@@ -95,11 +102,15 @@
                                            QObject *token, const char *msg, ...)
 {
     va_list ap;
+    char message[1024];
     va_start(ap, msg);
-    fprintf(stderr, "parse error: ");
-    vfprintf(stderr, msg, ap);
-    fprintf(stderr, "\n");
+    vsnprintf(message, sizeof(message), msg, ap);
     va_end(ap);
+    if (ctxt->err) {
+        error_free(ctxt->err);
+        ctxt->err = NULL;
+    }
+    error_set(&ctxt->err, QERR_JSON_PARSE_ERROR, message);
 }
 
 /**
@@ -264,28 +275,122 @@
     return NULL;
 }
 
+static QObject *parser_context_pop_token(JSONParserContext *ctxt)
+{
+    QObject *token;
+    g_assert(ctxt->tokens.pos < ctxt->tokens.count);
+    token = ctxt->tokens.buf[ctxt->tokens.pos];
+    ctxt->tokens.pos++;
+    return token;
+}
+
+/* Note: parser_context_{peek|pop}_token do not increment the
+ * token object's refcount. In both cases the references will continue
+ * to be tracked and cleaned up in parser_context_free(), so do not
+ * attempt to free the token object.
+ */
+static QObject *parser_context_peek_token(JSONParserContext *ctxt)
+{
+    QObject *token;
+    g_assert(ctxt->tokens.pos < ctxt->tokens.count);
+    token = ctxt->tokens.buf[ctxt->tokens.pos];
+    return token;
+}
+
+static JSONParserContext parser_context_save(JSONParserContext *ctxt)
+{
+    JSONParserContext saved_ctxt = {0};
+    saved_ctxt.tokens.pos = ctxt->tokens.pos;
+    saved_ctxt.tokens.count = ctxt->tokens.count;
+    saved_ctxt.tokens.buf = ctxt->tokens.buf;
+    return saved_ctxt;
+}
+
+static void parser_context_restore(JSONParserContext *ctxt,
+                                   JSONParserContext saved_ctxt)
+{
+    ctxt->tokens.pos = saved_ctxt.tokens.pos;
+    ctxt->tokens.count = saved_ctxt.tokens.count;
+    ctxt->tokens.buf = saved_ctxt.tokens.buf;
+}
+
+static void tokens_append_from_iter(QObject *obj, void *opaque)
+{
+    JSONParserContext *ctxt = opaque;
+    g_assert(ctxt->tokens.pos < ctxt->tokens.count);
+    ctxt->tokens.buf[ctxt->tokens.pos++] = obj;
+    qobject_incref(obj);
+}
+
+static JSONParserContext *parser_context_new(QList *tokens)
+{
+    JSONParserContext *ctxt;
+    size_t count;
+
+    if (!tokens) {
+        return NULL;
+    }
+
+    count = qlist_size(tokens);
+    if (count == 0) {
+        return NULL;
+    }
+
+    ctxt = g_malloc0(sizeof(JSONParserContext));
+    ctxt->tokens.pos = 0;
+    ctxt->tokens.count = count;
+    ctxt->tokens.buf = g_malloc(count * sizeof(QObject *));
+    qlist_iter(tokens, tokens_append_from_iter, ctxt);
+    ctxt->tokens.pos = 0;
+
+    return ctxt;
+}
+
+/* to support error propagation, ctxt->err must be freed separately */
+static void parser_context_free(JSONParserContext *ctxt)
+{
+    int i;
+    if (ctxt) {
+        for (i = 0; i < ctxt->tokens.count; i++) {
+            qobject_decref(ctxt->tokens.buf[i]);
+        }
+        g_free(ctxt->tokens.buf);
+        g_free(ctxt);
+    }
+}
+
 /**
  * Parsing rules
  */
-static int parse_pair(JSONParserContext *ctxt, QDict *dict, QList **tokens, va_list *ap)
+static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
 {
-    QObject *key, *token = NULL, *value, *peek;
-    QList *working = qlist_copy(*tokens);
+    QObject *key = NULL, *token = NULL, *value, *peek;
+    JSONParserContext saved_ctxt = parser_context_save(ctxt);
 
-    peek = qlist_peek(working);
-    key = parse_value(ctxt, &working, ap);
+    peek = parser_context_peek_token(ctxt);
+    if (peek == NULL) {
+        parse_error(ctxt, NULL, "premature EOI");
+        goto out;
+    }
+
+    key = parse_value(ctxt, ap);
     if (!key || qobject_type(key) != QTYPE_QSTRING) {
         parse_error(ctxt, peek, "key is not a string in object");
         goto out;
     }
 
-    token = qlist_pop(working);
+    token = parser_context_pop_token(ctxt);
+    if (token == NULL) {
+        parse_error(ctxt, NULL, "premature EOI");
+        goto out;
+    }
+
     if (!token_is_operator(token, ':')) {
         parse_error(ctxt, token, "missing : in object pair");
         goto out;
     }
 
-    value = parse_value(ctxt, &working, ap);
+    value = parse_value(ctxt, ap);
     if (value == NULL) {
         parse_error(ctxt, token, "Missing value in dict");
         goto out;
@@ -293,97 +398,112 @@
 
     qdict_put_obj(dict, qstring_get_str(qobject_to_qstring(key)), value);
 
-    qobject_decref(token);
     qobject_decref(key);
-    QDECREF(*tokens);
-    *tokens = working;
 
     return 0;
 
 out:
-    qobject_decref(token);
+    parser_context_restore(ctxt, saved_ctxt);
     qobject_decref(key);
-    QDECREF(working);
 
     return -1;
 }
 
-static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *ap)
+static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
 {
     QDict *dict = NULL;
     QObject *token, *peek;
-    QList *working = qlist_copy(*tokens);
+    JSONParserContext saved_ctxt = parser_context_save(ctxt);
 
-    token = qlist_pop(working);
+    token = parser_context_pop_token(ctxt);
+    if (token == NULL) {
+        goto out;
+    }
+
     if (!token_is_operator(token, '{')) {
         goto out;
     }
-    qobject_decref(token);
     token = NULL;
 
     dict = qdict_new();
 
-    peek = qlist_peek(working);
+    peek = parser_context_peek_token(ctxt);
+    if (peek == NULL) {
+        parse_error(ctxt, NULL, "premature EOI");
+        goto out;
+    }
+
     if (!token_is_operator(peek, '}')) {
-        if (parse_pair(ctxt, dict, &working, ap) == -1) {
+        if (parse_pair(ctxt, dict, ap) == -1) {
             goto out;
         }
 
-        token = qlist_pop(working);
+        token = parser_context_pop_token(ctxt);
+        if (token == NULL) {
+            parse_error(ctxt, NULL, "premature EOI");
+            goto out;
+        }
+
         while (!token_is_operator(token, '}')) {
             if (!token_is_operator(token, ',')) {
                 parse_error(ctxt, token, "expected separator in dict");
                 goto out;
             }
-            qobject_decref(token);
             token = NULL;
 
-            if (parse_pair(ctxt, dict, &working, ap) == -1) {
+            if (parse_pair(ctxt, dict, ap) == -1) {
                 goto out;
             }
 
-            token = qlist_pop(working);
+            token = parser_context_pop_token(ctxt);
+            if (token == NULL) {
+                parse_error(ctxt, NULL, "premature EOI");
+                goto out;
+            }
         }
-        qobject_decref(token);
         token = NULL;
     } else {
-        token = qlist_pop(working);
-        qobject_decref(token);
+        token = parser_context_pop_token(ctxt);
         token = NULL;
     }
 
-    QDECREF(*tokens);
-    *tokens = working;
-
     return QOBJECT(dict);
 
 out:
-    qobject_decref(token);
-    QDECREF(working);
+    parser_context_restore(ctxt, saved_ctxt);
     QDECREF(dict);
     return NULL;
 }
 
-static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap)
+static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
 {
     QList *list = NULL;
     QObject *token, *peek;
-    QList *working = qlist_copy(*tokens);
+    JSONParserContext saved_ctxt = parser_context_save(ctxt);
 
-    token = qlist_pop(working);
-    if (!token_is_operator(token, '[')) {
+    token = parser_context_pop_token(ctxt);
+    if (token == NULL) {
         goto out;
     }
-    qobject_decref(token);
+
+    if (!token_is_operator(token, '[')) {
+        token = NULL;
+        goto out;
+    }
     token = NULL;
 
     list = qlist_new();
 
-    peek = qlist_peek(working);
+    peek = parser_context_peek_token(ctxt);
+    if (peek == NULL) {
+        parse_error(ctxt, NULL, "premature EOI");
+        goto out;
+    }
+
     if (!token_is_operator(peek, ']')) {
         QObject *obj;
 
-        obj = parse_value(ctxt, &working, ap);
+        obj = parse_value(ctxt, ap);
         if (obj == NULL) {
             parse_error(ctxt, token, "expecting value");
             goto out;
@@ -391,17 +511,21 @@
 
         qlist_append_obj(list, obj);
 
-        token = qlist_pop(working);
+        token = parser_context_pop_token(ctxt);
+        if (token == NULL) {
+            parse_error(ctxt, NULL, "premature EOI");
+            goto out;
+        }
+
         while (!token_is_operator(token, ']')) {
             if (!token_is_operator(token, ',')) {
                 parse_error(ctxt, token, "expected separator in list");
                 goto out;
             }
 
-            qobject_decref(token);
             token = NULL;
 
-            obj = parse_value(ctxt, &working, ap);
+            obj = parse_value(ctxt, ap);
             if (obj == NULL) {
                 parse_error(ctxt, token, "expecting value");
                 goto out;
@@ -409,35 +533,36 @@
 
             qlist_append_obj(list, obj);
 
-            token = qlist_pop(working);
+            token = parser_context_pop_token(ctxt);
+            if (token == NULL) {
+                parse_error(ctxt, NULL, "premature EOI");
+                goto out;
+            }
         }
 
-        qobject_decref(token);
         token = NULL;
     } else {
-        token = qlist_pop(working);
-        qobject_decref(token);
+        token = parser_context_pop_token(ctxt);
         token = NULL;
     }
 
-    QDECREF(*tokens);
-    *tokens = working;
-
     return QOBJECT(list);
 
 out:
-    qobject_decref(token);
-    QDECREF(working);
+    parser_context_restore(ctxt, saved_ctxt);
     QDECREF(list);
     return NULL;
 }
 
-static QObject *parse_keyword(JSONParserContext *ctxt, QList **tokens)
+static QObject *parse_keyword(JSONParserContext *ctxt)
 {
     QObject *token, *ret;
-    QList *working = qlist_copy(*tokens);
+    JSONParserContext saved_ctxt = parser_context_save(ctxt);
 
-    token = qlist_pop(working);
+    token = parser_context_pop_token(ctxt);
+    if (token == NULL) {
+        goto out;
+    }
 
     if (token_get_type(token) != JSON_KEYWORD) {
         goto out;
@@ -452,29 +577,27 @@
         goto out;
     }
 
-    qobject_decref(token);
-    QDECREF(*tokens);
-    *tokens = working;
-
     return ret;
 
 out: 
-    qobject_decref(token);
-    QDECREF(working);
+    parser_context_restore(ctxt, saved_ctxt);
 
     return NULL;
 }
 
-static QObject *parse_escape(JSONParserContext *ctxt, QList **tokens, va_list *ap)
+static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
 {
     QObject *token = NULL, *obj;
-    QList *working = qlist_copy(*tokens);
+    JSONParserContext saved_ctxt = parser_context_save(ctxt);
 
     if (ap == NULL) {
         goto out;
     }
 
-    token = qlist_pop(working);
+    token = parser_context_pop_token(ctxt);
+    if (token == NULL) {
+        goto out;
+    }
 
     if (token_is_escape(token, "%p")) {
         obj = va_arg(*ap, QObject *);
@@ -495,32 +618,51 @@
         goto out;
     }
 
-    qobject_decref(token);
-    QDECREF(*tokens);
-    *tokens = working;
-
     return obj;
 
 out:
-    qobject_decref(token);
-    QDECREF(working);
+    parser_context_restore(ctxt, saved_ctxt);
 
     return NULL;
 }
 
-static QObject *parse_literal(JSONParserContext *ctxt, QList **tokens)
+static QObject *parse_literal(JSONParserContext *ctxt)
 {
     QObject *token, *obj;
-    QList *working = qlist_copy(*tokens);
+    JSONParserContext saved_ctxt = parser_context_save(ctxt);
 
-    token = qlist_pop(working);
+    token = parser_context_pop_token(ctxt);
+    if (token == NULL) {
+        goto out;
+    }
+
     switch (token_get_type(token)) {
     case JSON_STRING:
         obj = QOBJECT(qstring_from_escaped_str(ctxt, token));
         break;
-    case JSON_INTEGER:
-        obj = QOBJECT(qint_from_int(strtoll(token_get_value(token), NULL, 10)));
-        break;
+    case JSON_INTEGER: {
+        /* A possibility exists that this is a whole-valued float where the
+         * fractional part was left out due to being 0 (.0). It's not a big
+         * deal to treat these as ints in the parser, so long as users of the
+         * resulting QObject know to expect a QInt in place of a QFloat in
+         * cases like these.
+         *
+         * However, in some cases these values will overflow/underflow a
+         * QInt/int64 container, thus we should assume these are to be handled
+         * as QFloats/doubles rather than silently changing their values.
+         *
+         * strtoll() indicates these instances by setting errno to ERANGE
+         */
+        int64_t value;
+
+        errno = 0; /* strtoll doesn't set errno on success */
+        value = strtoll(token_get_value(token), NULL, 10);
+        if (errno != ERANGE) {
+            obj = QOBJECT(qint_from_int(value));
+            break;
+        }
+        /* fall through to JSON_FLOAT */
+    }
     case JSON_FLOAT:
         /* FIXME dependent on locale */
         obj = QOBJECT(qfloat_from_double(strtod(token_get_value(token), NULL)));
@@ -529,35 +671,30 @@
         goto out;
     }
 
-    qobject_decref(token);
-    QDECREF(*tokens);
-    *tokens = working;
-
     return obj;
 
 out:
-    qobject_decref(token);
-    QDECREF(working);
+    parser_context_restore(ctxt, saved_ctxt);
 
     return NULL;
 }
 
-static QObject *parse_value(JSONParserContext *ctxt, QList **tokens, va_list *ap)
+static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
 {
     QObject *obj;
 
-    obj = parse_object(ctxt, tokens, ap);
+    obj = parse_object(ctxt, ap);
     if (obj == NULL) {
-        obj = parse_array(ctxt, tokens, ap);
+        obj = parse_array(ctxt, ap);
     }
     if (obj == NULL) {
-        obj = parse_escape(ctxt, tokens, ap);
+        obj = parse_escape(ctxt, ap);
     }
     if (obj == NULL) {
-        obj = parse_keyword(ctxt, tokens);
+        obj = parse_keyword(ctxt);
     } 
     if (obj == NULL) {
-        obj = parse_literal(ctxt, tokens);
+        obj = parse_literal(ctxt);
     }
 
     return obj;
@@ -565,13 +702,23 @@
 
 QObject *json_parser_parse(QList *tokens, va_list *ap)
 {
-    JSONParserContext ctxt = {};
-    QList *working = qlist_copy(tokens);
+    return json_parser_parse_err(tokens, ap, NULL);
+}
+
+QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp)
+{
+    JSONParserContext *ctxt = parser_context_new(tokens);
     QObject *result;
 
-    result = parse_value(&ctxt, &working, ap);
+    if (!ctxt) {
+        return NULL;
+    }
 
-    QDECREF(working);
+    result = parse_value(ctxt, ap);
+
+    error_propagate(errp, ctxt->err);
+
+    parser_context_free(ctxt);
 
     return result;
 }
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
index 8241125..1b2f9b1 100644
--- a/qobject/json-streamer.c
+++ b/qobject/json-streamer.c
@@ -18,6 +18,9 @@
 #include "qapi/qmp/json-lexer.h"
 #include "qapi/qmp/json-streamer.h"
 
+#define MAX_TOKEN_SIZE (64ULL << 20)
+#define MAX_NESTING (1ULL << 10)
+
 static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y)
 {
     JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
@@ -49,14 +52,44 @@
     qdict_put(dict, "x", qint_from_int(x));
     qdict_put(dict, "y", qint_from_int(y));
 
+    parser->token_size += token->length;
+
     qlist_append(parser->tokens, dict);
 
-    if (parser->brace_count == 0 &&
-        parser->bracket_count == 0) {
-        parser->emit(parser, parser->tokens);
-        QDECREF(parser->tokens);
-        parser->tokens = qlist_new();
+    if (type == JSON_ERROR) {
+        goto out_emit_bad;
+    } else if (parser->brace_count < 0 ||
+        parser->bracket_count < 0 ||
+        (parser->brace_count == 0 &&
+         parser->bracket_count == 0)) {
+        goto out_emit;
+    } else if (parser->token_size > MAX_TOKEN_SIZE ||
+               parser->bracket_count > MAX_NESTING ||
+               parser->brace_count > MAX_NESTING) {
+        /* Security consideration, we limit total memory allocated per object
+         * and the maximum recursion depth that a message can force.
+         */
+        goto out_emit;
     }
+
+    return;
+
+out_emit_bad:
+    /* clear out token list and tell the parser to emit and error
+     * indication by passing it a NULL list
+     */
+    QDECREF(parser->tokens);
+    parser->tokens = NULL;
+out_emit:
+    /* send current list of tokens to parser and reset tokenizer */
+    parser->brace_count = 0;
+    parser->bracket_count = 0;
+    parser->emit(parser, parser->tokens);
+    if (parser->tokens) {
+        QDECREF(parser->tokens);
+    }
+    parser->tokens = qlist_new();
+    parser->token_size = 0;
 }
 
 void json_message_parser_init(JSONMessageParser *parser,
@@ -66,6 +99,7 @@
     parser->brace_count = 0;
     parser->bracket_count = 0;
     parser->tokens = qlist_new();
+    parser->token_size = 0;
 
     json_lexer_init(&parser->lexer, json_message_process_token);
 }
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 7543ccc..17e14f0 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -401,6 +401,28 @@
 }
 
 /**
+ * qdict_clone_shallow(): Clones a given QDict. Its entries are not copied, but
+ * another reference is added.
+ */
+QDict *qdict_clone_shallow(const QDict *src)
+{
+    QDict *dest;
+    QDictEntry *entry;
+    int i;
+
+    dest = qdict_new();
+
+    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
+        QLIST_FOREACH(entry, &src->table[i], next) {
+            qobject_incref(entry->value);
+            qdict_put_obj(dest, entry->key, entry->value);
+        }
+    }
+
+    return dest;
+}
+
+/**
  * qentry_destroy(): Free all the memory allocated by a QDictEntry
  */
 static void qentry_destroy(QDictEntry *e)
@@ -454,3 +476,81 @@
 
     g_free(qdict);
 }
+
+static void qdict_do_flatten(QDict *qdict, QDict *target, const char *prefix)
+{
+    QObject *value;
+    const QDictEntry *entry, *next;
+    char *new_key;
+    bool delete;
+
+    entry = qdict_first(qdict);
+
+    while (entry != NULL) {
+
+        next = qdict_next(qdict, entry);
+        value = qdict_entry_value(entry);
+        new_key = NULL;
+        delete = false;
+
+        if (prefix) {
+            new_key = g_strdup_printf("%s.%s", prefix, entry->key);
+        }
+
+        if (qobject_type(value) == QTYPE_QDICT) {
+            /* Entries of QDicts are processed recursively, the QDict object
+             * itself disappears. */
+            qdict_do_flatten(qobject_to_qdict(value), target,
+                             new_key ? new_key : entry->key);
+            delete = true;
+        } else if (prefix) {
+            /* All other objects are moved to the target unchanged. */
+            qobject_incref(value);
+            qdict_put_obj(target, new_key, value);
+            delete = true;
+        }
+
+        g_free(new_key);
+
+        if (delete) {
+            qdict_del(qdict, entry->key);
+
+            /* Restart loop after modifying the iterated QDict */
+            entry = qdict_first(qdict);
+            continue;
+        }
+
+        entry = next;
+    }
+}
+
+/**
+ * qdict_flatten(): For each nested QDict with key x, all fields with key y
+ * are moved to this QDict and their key is renamed to "x.y". This operation
+ * is applied recursively for nested QDicts.
+ */
+void qdict_flatten(QDict *qdict)
+{
+    qdict_do_flatten(qdict, qdict, NULL);
+}
+
+/* extract all the src QDict entries starting by start into dst */
+void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start)
+
+{
+    const QDictEntry *entry, *next;
+    const char *p;
+
+    *dst = qdict_new();
+    entry = qdict_first(src);
+
+    while (entry != NULL) {
+        next = qdict_next(src, entry);
+        if (strstart(entry->key, start, &p)) {
+            qobject_incref(entry->value);
+            qdict_put_obj(*dst, p, entry->value);
+            qdict_del(src, entry->key);
+        }
+        entry = next;
+    }
+}
diff --git a/qobject/qerror.c b/qobject/qerror.c
index 40d0cbb..fc8331a 100644
--- a/qobject/qerror.c
+++ b/qobject/qerror.c
@@ -23,201 +23,11 @@
 };
 
 /**
- * The 'desc' parameter is a printf-like string, the format of the format
- * string is:
- *
- * %(KEY)
- *
- * Where KEY is a QDict key, which has to be passed to qerror_from_info().
- *
- * Example:
- *
- * "foo error on device: %(device) slot: %(slot_nr)"
- *
- * A single percent sign can be printed if followed by a second one,
- * for example:
- *
- * "running out of foo: %(foo)%%"
- *
- * Please keep the entries in alphabetical order.
- * Use "sed -n '/^static.*qerror_table\[\]/,/^};/s/QERR_/&/gp' qerror.c | sort -c"
- * to check.
- */
-static const QErrorStringTable qerror_table[] = {
-    {
-        .error_fmt = QERR_BAD_BUS_FOR_DEVICE,
-        .desc      = "Device '%(device)' can't go on a %(bad_bus_type) bus",
-    },
-    {
-        .error_fmt = QERR_BUS_NOT_FOUND,
-        .desc      = "Bus '%(bus)' not found",
-    },
-    {
-        .error_fmt = QERR_BUS_NO_HOTPLUG,
-        .desc      = "Bus '%(bus)' does not support hotplugging",
-    },
-    {
-        .error_fmt = QERR_COMMAND_NOT_FOUND,
-        .desc      = "The command %(name) has not been found",
-    },
-    {
-        .error_fmt = QERR_DEVICE_ENCRYPTED,
-        .desc      = "Device '%(device)' is encrypted",
-    },
-    {
-        .error_fmt = QERR_DEVICE_INIT_FAILED,
-        .desc      = "Device '%(device)' could not be initialized",
-    },
-    {
-        .error_fmt = QERR_DEVICE_IN_USE,
-        .desc      = "Device '%(device)' is in use",
-    },
-    {
-        .error_fmt = QERR_DEVICE_LOCKED,
-        .desc      = "Device '%(device)' is locked",
-    },
-    {
-        .error_fmt = QERR_DEVICE_MULTIPLE_BUSSES,
-        .desc      = "Device '%(device)' has multiple child busses",
-    },
-    {
-        .error_fmt = QERR_DEVICE_NOT_ACTIVE,
-        .desc      = "Device '%(device)' has not been activated",
-    },
-    {
-        .error_fmt = QERR_DEVICE_NOT_ENCRYPTED,
-        .desc      = "Device '%(device)' is not encrypted",
-    },
-    {
-        .error_fmt = QERR_DEVICE_NOT_FOUND,
-        .desc      = "Device '%(device)' not found",
-    },
-    {
-        .error_fmt = QERR_DEVICE_NOT_REMOVABLE,
-        .desc      = "Device '%(device)' is not removable",
-    },
-    {
-        .error_fmt = QERR_DEVICE_NO_BUS,
-        .desc      = "Device '%(device)' has no child bus",
-    },
-    {
-        .error_fmt = QERR_DEVICE_NO_HOTPLUG,
-        .desc      = "Device '%(device)' does not support hotplugging",
-    },
-    {
-        .error_fmt = QERR_DUPLICATE_ID,
-        .desc      = "Duplicate ID '%(id)' for %(object)",
-    },
-    {
-        .error_fmt = QERR_FD_NOT_FOUND,
-        .desc      = "File descriptor named '%(name)' not found",
-    },
-    {
-        .error_fmt = QERR_FD_NOT_SUPPLIED,
-        .desc      = "No file descriptor supplied via SCM_RIGHTS",
-    },
-    {
-        .error_fmt = QERR_INVALID_BLOCK_FORMAT,
-        .desc      = "Invalid block format '%(name)'",
-    },
-    {
-        .error_fmt = QERR_INVALID_PARAMETER,
-        .desc      = "Invalid parameter '%(name)'",
-    },
-    {
-        .error_fmt = QERR_INVALID_PARAMETER_TYPE,
-        .desc      = "Invalid parameter type, expected: %(expected)",
-    },
-    {
-        .error_fmt = QERR_INVALID_PARAMETER_VALUE,
-        .desc      = "Parameter '%(name)' expects %(expected)",
-    },
-    {
-        .error_fmt = QERR_INVALID_PASSWORD,
-        .desc      = "Password incorrect",
-    },
-    {
-        .error_fmt = QERR_JSON_PARSING,
-        .desc      = "Invalid JSON syntax",
-    },
-    {
-        .error_fmt = QERR_KVM_MISSING_CAP,
-        .desc      = "Using KVM without %(capability), %(feature) unavailable",
-    },
-    {
-        .error_fmt = QERR_MIGRATION_EXPECTED,
-        .desc      = "An incoming migration is expected before this command can be executed",
-    },
-    {
-        .error_fmt = QERR_MISSING_PARAMETER,
-        .desc      = "Parameter '%(name)' is missing",
-    },
-    {
-        .error_fmt = QERR_NO_BUS_FOR_DEVICE,
-        .desc      = "No '%(bus)' bus found for device '%(device)'",
-    },
-    {
-        .error_fmt = QERR_OPEN_FILE_FAILED,
-        .desc      = "Could not open '%(filename)'",
-    },
-    {
-        .error_fmt = QERR_PROPERTY_NOT_FOUND,
-        .desc      = "Property '%(device).%(property)' not found",
-    },
-    {
-        .error_fmt = QERR_PROPERTY_VALUE_BAD,
-        .desc      = "Property '%(device).%(property)' doesn't take value '%(value)'",
-    },
-    {
-        .error_fmt = QERR_PROPERTY_VALUE_IN_USE,
-        .desc      = "Property '%(device).%(property)' can't take value '%(value)', it's in use",
-    },
-    {
-        .error_fmt = QERR_PROPERTY_VALUE_NOT_FOUND,
-        .desc      = "Property '%(device).%(property)' can't find value '%(value)'",
-    },
-    {
-        .error_fmt = QERR_QMP_BAD_INPUT_OBJECT,
-        .desc      = "Expected '%(expected)' in QMP input",
-    },
-    {
-        .error_fmt = QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
-        .desc      = "QMP input object member '%(member)' expects '%(expected)'",
-    },
-    {
-        .error_fmt = QERR_QMP_EXTRA_MEMBER,
-        .desc      = "QMP input object member '%(member)' is unexpected",
-    },
-    {
-        .error_fmt = QERR_SET_PASSWD_FAILED,
-        .desc      = "Could not set password",
-    },
-    {
-        .error_fmt = QERR_TOO_MANY_FILES,
-        .desc      = "Too many open files",
-    },
-    {
-        .error_fmt = QERR_UNDEFINED_ERROR,
-        .desc      = "An undefined error has ocurred",
-    },
-    {
-        .error_fmt = QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
-        .desc      = "'%(device)' uses a %(format) feature which is not "
-                     "supported by this qemu version: %(feature)",
-    },
-    {
-        .error_fmt = QERR_VNC_SERVER_FAILED,
-        .desc      = "Could not start VNC server on %(target)",
-    },
-    {}
-};
-
-/**
  * qerror_new(): Create a new QError
  *
  * Return strong reference.
  */
-QError *qerror_new(void)
+static QError *qerror_new(void)
 {
     QError *qerr;
 
@@ -227,179 +37,31 @@
     return qerr;
 }
 
-static void GCC_FMT_ATTR(2, 3) qerror_abort(const QError *qerr,
-                                            const char *fmt, ...)
-{
-    va_list ap;
-
-    fprintf(stderr, "qerror: bad call in function '%s':\n", qerr->func);
-    fprintf(stderr, "qerror: -> ");
-
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
-
-    fprintf(stderr, "\nqerror: call at %s:%d\n", qerr->file, qerr->linenr);
-    abort();
-}
-
-static void GCC_FMT_ATTR(2, 0) qerror_set_data(QError *qerr,
-                                               const char *fmt, va_list *va)
-{
-    QObject *obj;
-
-    obj = qobject_from_jsonv(fmt, va);
-    if (!obj) {
-        qerror_abort(qerr, "invalid format '%s'", fmt);
-    }
-    if (qobject_type(obj) != QTYPE_QDICT) {
-        qerror_abort(qerr, "error format is not a QDict '%s'", fmt);
-    }
-
-    qerr->error = qobject_to_qdict(obj);
-
-    obj = qdict_get(qerr->error, "class");
-    if (!obj) {
-        qerror_abort(qerr, "missing 'class' key in '%s'", fmt);
-    }
-    if (qobject_type(obj) != QTYPE_QSTRING) {
-        qerror_abort(qerr, "'class' key value should be a QString");
-    }
-    
-    obj = qdict_get(qerr->error, "data");
-    if (!obj) {
-        qerror_abort(qerr, "missing 'data' key in '%s'", fmt);
-    }
-    if (qobject_type(obj) != QTYPE_QDICT) {
-        qerror_abort(qerr, "'data' key value should be a QDICT");
-    }
-}
-
-static void qerror_set_desc(QError *qerr, const char *fmt)
-{
-    int i;
-
-    // FIXME: inefficient loop
-
-    for (i = 0; qerror_table[i].error_fmt; i++) {
-        if (strcmp(qerror_table[i].error_fmt, fmt) == 0) {
-            qerr->entry = &qerror_table[i];
-            return;
-        }
-    }
-
-    qerror_abort(qerr, "error format '%s' not found", fmt);
-}
-
 /**
  * qerror_from_info(): Create a new QError from error information
  *
- * The information consists of:
- *
- * - file   the file name of where the error occurred
- * - linenr the line number of where the error occurred
- * - func   the function name of where the error occurred
- * - fmt    JSON printf-like dictionary, there must exist keys 'class' and
- *          'data'
- * - va     va_list of all arguments specified by fmt
- *
  * Return strong reference.
  */
-QError *qerror_from_info(const char *file, int linenr, const char *func,
-                         const char *fmt, va_list *va)
+static QError * GCC_FMT_ATTR(2, 0)
+qerror_from_info(ErrorClass err_class, const char *fmt, va_list *va)
 {
     QError *qerr;
 
     qerr = qerror_new();
     loc_save(&qerr->loc);
-    qerr->linenr = linenr;
-    qerr->file = file;
-    qerr->func = func;
 
-    if (!fmt) {
-        qerror_abort(qerr, "QDict not specified");
-    }
-
-    qerror_set_data(qerr, fmt, va);
-    qerror_set_desc(qerr, fmt);
+    qerr->err_msg = g_strdup_vprintf(fmt, *va);
+    qerr->err_class = err_class;
 
     return qerr;
 }
 
-static void parse_error(const QError *qerror, int c)
-{
-    qerror_abort(qerror, "expected '%c' in '%s'", c, qerror->entry->desc);
-}
-
-static const char *append_field(QString *outstr, const QError *qerror,
-                                const char *start)
-{
-    QObject *obj;
-    QDict *qdict;
-    QString *key_qs;
-    const char *end, *key;
-
-    if (*start != '%')
-        parse_error(qerror, '%');
-    start++;
-    if (*start != '(')
-        parse_error(qerror, '(');
-    start++;
-
-    end = strchr(start, ')');
-    if (!end)
-        parse_error(qerror, ')');
-
-    key_qs = qstring_from_substr(start, 0, end - start - 1);
-    key = qstring_get_str(key_qs);
-
-    qdict = qobject_to_qdict(qdict_get(qerror->error, "data"));
-    obj = qdict_get(qdict, key);
-    if (!obj) {
-        qerror_abort(qerror, "key '%s' not found in QDict", key);
-    }
-
-    switch (qobject_type(obj)) {
-        case QTYPE_QSTRING:
-            qstring_append(outstr, qdict_get_str(qdict, key));
-            break;
-        case QTYPE_QINT:
-            qstring_append_int(outstr, qdict_get_int(qdict, key));
-            break;
-        default:
-            qerror_abort(qerror, "invalid type '%c'", qobject_type(obj));
-    }
-
-    QDECREF(key_qs);
-    return ++end;
-}
-
 /**
  * qerror_human(): Format QError data into human-readable string.
- *
- * Formats according to member 'desc' of the specified QError object.
  */
 QString *qerror_human(const QError *qerror)
 {
-    const char *p;
-    QString *qstring;
-
-    assert(qerror->entry != NULL);
-
-    qstring = qstring_new();
-
-    for (p = qerror->entry->desc; *p != '\0';) {
-        if (*p != '%') {
-            qstring_append_chr(qstring, *p++);
-        } else if (*(p + 1) == '%') {
-            qstring_append_chr(qstring, '%');
-            p += 2;
-        } else {
-            p = append_field(qstring, qerror, p);
-        }
-    }
-
-    return qstring;
+    return qstring_from_str(qerror->err_msg);
 }
 
 /**
@@ -409,7 +71,7 @@
  * it uses error_report() for this, so that the output is routed to the right
  * place (ie. stderr or Monitor's device).
  */
-void qerror_print(QError *qerror)
+static void qerror_print(QError *qerror)
 {
     QString *qstring = qerror_human(qerror);
     loc_push_restore(&qerror->loc);
@@ -418,14 +80,13 @@
     QDECREF(qstring);
 }
 
-void qerror_report_internal(const char *file, int linenr, const char *func,
-                            const char *fmt, ...)
+void qerror_report(ErrorClass eclass, const char *fmt, ...)
 {
     va_list va;
     QError *qerror;
 
     va_start(va, fmt);
-    qerror = qerror_from_info(file, linenr, func, fmt, &va);
+    qerror = qerror_from_info(eclass, fmt, &va);
     va_end(va);
 
     if (monitor_cur_is_qmp()) {
@@ -436,10 +97,42 @@
     }
 }
 
+/* Evil... */
+struct Error
+{
+    char *msg;
+    ErrorClass err_class;
+};
+
+void qerror_report_err(Error *err)
+{
+    QError *qerr;
+
+    qerr = qerror_new();
+    loc_save(&qerr->loc);
+    qerr->err_msg = g_strdup(err->msg);
+    qerr->err_class = err->err_class;
+
+    if (monitor_cur_is_qmp()) {
+        monitor_set_error(cur_mon, qerr);
+    } else {
+        qerror_print(qerr);
+        QDECREF(qerr);
+    }
+}
+
+void assert_no_error(Error *err)
+{
+    if (err) {
+        qerror_report_err(err);
+        abort();
+    }
+}
+
 /**
  * qobject_to_qerror(): Convert a QObject into a QError
  */
-QError *qobject_to_qerror(const QObject *obj)
+static QError *qobject_to_qerror(const QObject *obj)
 {
     if (qobject_type(obj) != QTYPE_QERROR) {
         return NULL;
@@ -458,6 +151,6 @@
     assert(obj != NULL);
     qerr = qobject_to_qerror(obj);
 
-    QDECREF(qerr->error);
+    g_free(qerr->err_msg);
     g_free(qerr);
 }
diff --git a/qobject/qjson.c b/qobject/qjson.c
index 83a6b4f..6cf2511 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -136,68 +136,56 @@
     case QTYPE_QSTRING: {
         QString *val = qobject_to_qstring(obj);
         const char *ptr;
+        int cp;
+        char buf[16];
+        char *end;
 
         ptr = qstring_get_str(val);
         qstring_append(str, "\"");
-        while (*ptr) {
-            if ((ptr[0] & 0xE0) == 0xE0 &&
-                (ptr[1] & 0x80) && (ptr[2] & 0x80)) {
-                uint16_t wchar;
-                char escape[7];
 
-                wchar  = (ptr[0] & 0x0F) << 12;
-                wchar |= (ptr[1] & 0x3F) << 6;
-                wchar |= (ptr[2] & 0x3F);
-                ptr += 2;
-
-                snprintf(escape, sizeof(escape), "\\u%04X", wchar);
-                qstring_append(str, escape);
-            } else if ((ptr[0] & 0xE0) == 0xC0 && (ptr[1] & 0x80)) {
-                uint16_t wchar;
-                char escape[7];
-
-                wchar  = (ptr[0] & 0x1F) << 6;
-                wchar |= (ptr[1] & 0x3F);
-                ptr++;
-
-                snprintf(escape, sizeof(escape), "\\u%04X", wchar);
-                qstring_append(str, escape);
-            } else switch (ptr[0]) {
-                case '\"':
-                    qstring_append(str, "\\\"");
-                    break;
-                case '\\':
-                    qstring_append(str, "\\\\");
-                    break;
-                case '\b':
-                    qstring_append(str, "\\b");
-                    break;
-                case '\f':
-                    qstring_append(str, "\\f");
-                    break;
-                case '\n':
-                    qstring_append(str, "\\n");
-                    break;
-                case '\r':
-                    qstring_append(str, "\\r");
-                    break;
-                case '\t':
-                    qstring_append(str, "\\t");
-                    break;
-                default: {
-                    if (ptr[0] <= 0x1F) {
-                        char escape[7];
-                        snprintf(escape, sizeof(escape), "\\u%04X", ptr[0]);
-                        qstring_append(str, escape);
-                    } else {
-                        char buf[2] = { ptr[0], 0 };
-                        qstring_append(str, buf);
-                    }
-                    break;
+        for (; *ptr; ptr = end) {
+            cp = mod_utf8_codepoint(ptr, 6, &end);
+            switch (cp) {
+            case '\"':
+                qstring_append(str, "\\\"");
+                break;
+            case '\\':
+                qstring_append(str, "\\\\");
+                break;
+            case '\b':
+                qstring_append(str, "\\b");
+                break;
+            case '\f':
+                qstring_append(str, "\\f");
+                break;
+            case '\n':
+                qstring_append(str, "\\n");
+                break;
+            case '\r':
+                qstring_append(str, "\\r");
+                break;
+            case '\t':
+                qstring_append(str, "\\t");
+                break;
+            default:
+                if (cp < 0) {
+                    cp = 0xFFFD; /* replacement character */
                 }
+                if (cp > 0xFFFF) {
+                    /* beyond BMP; need a surrogate pair */
+                    snprintf(buf, sizeof(buf), "\\u%04X\\u%04X",
+                             0xD800 + ((cp - 0x10000) >> 10),
+                             0xDC00 + ((cp - 0x10000) & 0x3FF));
+                } else if (cp < 0x20 || cp >= 0x7F) {
+                    snprintf(buf, sizeof(buf), "\\u%04X", cp);
+                } else {
+                    buf[0] = cp;
+                    buf[1] = 0;
                 }
-            ptr++;
-        }
+                qstring_append(str, buf);
+            }
+        };
+
         qstring_append(str, "\"");
         break;
     }
@@ -272,6 +260,8 @@
         /* XXX: should QError be emitted? */
     case QTYPE_NONE:
         break;
+    case QTYPE_MAX:
+        abort();
     }
 }
 
diff --git a/qobject/qlist.c b/qobject/qlist.c
index 815b6aa..1ced0de 100644
--- a/qobject/qlist.c
+++ b/qobject/qlist.c
@@ -124,6 +124,19 @@
     return QTAILQ_EMPTY(&qlist->head);
 }
 
+static void qlist_size_iter(QObject *obj, void *opaque)
+{
+    size_t *count = opaque;
+    (*count)++;
+}
+
+size_t qlist_size(const QList *qlist)
+{
+    size_t count = 0;
+    qlist_iter(qlist, qlist_size_iter, &count);
+    return count;
+}
+
 /**
  * qobject_to_qlist(): Convert a QObject into a QList
  */
diff --git a/qobject/qstring.c b/qobject/qstring.c
index 5f7376c..607b7a1 100644
--- a/qobject/qstring.c
+++ b/qobject/qstring.c
@@ -32,6 +32,14 @@
 }
 
 /**
+ * qstring_get_length(): Get the length of a QString
+ */
+size_t qstring_get_length(const QString *qstring)
+{
+    return qstring->length;
+}
+
+/**
  * qstring_from_substr(): Create a new QString from a C string substring
  *
  * Return string reference
diff --git a/qom/container.c b/qom/container.c
new file mode 100644
index 0000000..62b1648
--- /dev/null
+++ b/qom/container.c
@@ -0,0 +1,52 @@
+/*
+ * Device Container
+ *
+ * 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 "qom/object.h"
+#include "qemu/module.h"
+#include <assert.h>
+
+static const TypeInfo container_info = {
+    .name          = "container",
+    .instance_size = sizeof(Object),
+    .parent        = TYPE_OBJECT,
+};
+
+static void container_register_types(void)
+{
+    type_register_static(&container_info);
+}
+
+Object *container_get(Object *root, 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 = 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);
+        }
+    }
+
+    g_strfreev(parts);
+
+    return obj;
+}
+
+
+type_init(container_register_types)
diff --git a/qom/object.c b/qom/object.c
new file mode 100644
index 0000000..fc19cf6
--- /dev/null
+++ b/qom/object.c
@@ -0,0 +1,1432 @@
+/*
+ * QEMU Object Model
+ *
+ * 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 "qom/object.h"
+#include "qemu-common.h"
+#include "qapi/visitor.h"
+#include "qapi/string-input-visitor.h"
+#include "qapi/string-output-visitor.h"
+#include "qapi/qmp/qerror.h"
+#include "trace.h"
+
+/* TODO: replace QObject with a simpler visitor to avoid a dependency
+ * of the QOM core on QObject?  */
+#include "qom/qom-qobject.h"
+#include "qapi/qmp/qobject.h"
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qint.h"
+#include "qapi/qmp/qstring.h"
+
+#define MAX_INTERFACES 32
+
+typedef struct InterfaceImpl InterfaceImpl;
+typedef struct TypeImpl TypeImpl;
+
+struct InterfaceImpl
+{
+    const char *typename;
+};
+
+struct TypeImpl
+{
+    const char *name;
+
+    size_t class_size;
+
+    size_t instance_size;
+
+    void (*class_init)(ObjectClass *klass, void *data);
+    void (*class_base_init)(ObjectClass *klass, void *data);
+    void (*class_finalize)(ObjectClass *klass, void *data);
+
+    void *class_data;
+
+    void (*instance_init)(Object *obj);
+    void (*instance_post_init)(Object *obj);
+    void (*instance_finalize)(Object *obj);
+
+    bool abstract;
+
+    const char *parent;
+    TypeImpl *parent_type;
+
+    ObjectClass *class;
+
+    int num_interfaces;
+    InterfaceImpl interfaces[MAX_INTERFACES];
+};
+
+static Type type_interface;
+
+static GHashTable *type_table_get(void)
+{
+    static GHashTable *type_table;
+
+    if (type_table == NULL) {
+        type_table = g_hash_table_new(g_str_hash, g_str_equal);
+    }
+
+    return type_table;
+}
+
+static void type_table_add(TypeImpl *ti)
+{
+    g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
+}
+
+static TypeImpl *type_table_lookup(const char *name)
+{
+    return g_hash_table_lookup(type_table_get(), name);
+}
+
+static TypeImpl *type_register_internal(const TypeInfo *info)
+{
+    TypeImpl *ti = g_malloc0(sizeof(*ti));
+    int i;
+
+    g_assert(info->name != NULL);
+
+    if (type_table_lookup(info->name) != NULL) {
+        fprintf(stderr, "Registering `%s' which already exists\n", info->name);
+        abort();
+    }
+
+    ti->name = g_strdup(info->name);
+    ti->parent = g_strdup(info->parent);
+
+    ti->class_size = info->class_size;
+    ti->instance_size = info->instance_size;
+
+    ti->class_init = info->class_init;
+    ti->class_base_init = info->class_base_init;
+    ti->class_finalize = info->class_finalize;
+    ti->class_data = info->class_data;
+
+    ti->instance_init = info->instance_init;
+    ti->instance_post_init = info->instance_post_init;
+    ti->instance_finalize = info->instance_finalize;
+
+    ti->abstract = info->abstract;
+
+    for (i = 0; info->interfaces && info->interfaces[i].type; i++) {
+        ti->interfaces[i].typename = g_strdup(info->interfaces[i].type);
+    }
+    ti->num_interfaces = i;
+
+    type_table_add(ti);
+
+    return ti;
+}
+
+TypeImpl *type_register(const TypeInfo *info)
+{
+    assert(info->parent);
+    return type_register_internal(info);
+}
+
+TypeImpl *type_register_static(const TypeInfo *info)
+{
+    return type_register(info);
+}
+
+static TypeImpl *type_get_by_name(const char *name)
+{
+    if (name == NULL) {
+        return NULL;
+    }
+
+    return type_table_lookup(name);
+}
+
+static TypeImpl *type_get_parent(TypeImpl *type)
+{
+    if (!type->parent_type && type->parent) {
+        type->parent_type = type_get_by_name(type->parent);
+        g_assert(type->parent_type != NULL);
+    }
+
+    return type->parent_type;
+}
+
+static bool type_has_parent(TypeImpl *type)
+{
+    return (type->parent != NULL);
+}
+
+static size_t type_class_get_size(TypeImpl *ti)
+{
+    if (ti->class_size) {
+        return ti->class_size;
+    }
+
+    if (type_has_parent(ti)) {
+        return type_class_get_size(type_get_parent(ti));
+    }
+
+    return sizeof(ObjectClass);
+}
+
+static size_t type_object_get_size(TypeImpl *ti)
+{
+    if (ti->instance_size) {
+        return ti->instance_size;
+    }
+
+    if (type_has_parent(ti)) {
+        return type_object_get_size(type_get_parent(ti));
+    }
+
+    return 0;
+}
+
+static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
+{
+    assert(target_type);
+
+    /* Check if typename is a direct ancestor of type */
+    while (type) {
+        if (type == target_type) {
+            return true;
+        }
+
+        type = type_get_parent(type);
+    }
+
+    return false;
+}
+
+static void type_initialize(TypeImpl *ti);
+
+static void type_initialize_interface(TypeImpl *ti, const char *parent)
+{
+    InterfaceClass *new_iface;
+    TypeInfo info = { };
+    TypeImpl *iface_impl;
+
+    info.parent = parent;
+    info.name = g_strdup_printf("%s::%s", ti->name, info.parent);
+    info.abstract = true;
+
+    iface_impl = type_register(&info);
+    type_initialize(iface_impl);
+    g_free((char *)info.name);
+
+    new_iface = (InterfaceClass *)iface_impl->class;
+    new_iface->concrete_class = ti->class;
+
+    ti->class->interfaces = g_slist_append(ti->class->interfaces,
+                                           iface_impl->class);
+}
+
+static void type_initialize(TypeImpl *ti)
+{
+    TypeImpl *parent;
+
+    if (ti->class) {
+        return;
+    }
+
+    ti->class_size = type_class_get_size(ti);
+    ti->instance_size = type_object_get_size(ti);
+
+    ti->class = g_malloc0(ti->class_size);
+
+    parent = type_get_parent(ti);
+    if (parent) {
+        type_initialize(parent);
+        GSList *e;
+        int i;
+
+        g_assert(parent->class_size <= ti->class_size);
+        memcpy(ti->class, parent->class, parent->class_size);
+        ti->class->interfaces = NULL;
+
+        for (e = parent->class->interfaces; e; e = e->next) {
+            ObjectClass *iface = e->data;
+            type_initialize_interface(ti, object_class_get_name(iface));
+        }
+
+        for (i = 0; i < ti->num_interfaces; i++) {
+            TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
+            for (e = ti->class->interfaces; e; e = e->next) {
+                TypeImpl *target_type = OBJECT_CLASS(e->data)->type;
+
+                if (type_is_ancestor(target_type, t)) {
+                    break;
+                }
+            }
+
+            if (e) {
+                continue;
+            }
+
+            type_initialize_interface(ti, ti->interfaces[i].typename);
+        }
+    }
+
+    ti->class->type = ti;
+
+    while (parent) {
+        if (parent->class_base_init) {
+            parent->class_base_init(ti->class, ti->class_data);
+        }
+        parent = type_get_parent(parent);
+    }
+
+    if (ti->class_init) {
+        ti->class_init(ti->class, ti->class_data);
+    }
+
+
+}
+
+static void object_init_with_type(Object *obj, TypeImpl *ti)
+{
+    if (type_has_parent(ti)) {
+        object_init_with_type(obj, type_get_parent(ti));
+    }
+
+    if (ti->instance_init) {
+        ti->instance_init(obj);
+    }
+}
+
+static void object_post_init_with_type(Object *obj, TypeImpl *ti)
+{
+    if (ti->instance_post_init) {
+        ti->instance_post_init(obj);
+    }
+
+    if (type_has_parent(ti)) {
+        object_post_init_with_type(obj, type_get_parent(ti));
+    }
+}
+
+void object_initialize_with_type(void *data, size_t size, TypeImpl *type)
+{
+    Object *obj = data;
+
+    g_assert(type != NULL);
+    type_initialize(type);
+
+    g_assert(type->instance_size >= sizeof(Object));
+    g_assert(type->abstract == false);
+    g_assert(size >= type->instance_size);
+
+    memset(obj, 0, type->instance_size);
+    obj->class = type->class;
+    object_ref(obj);
+    QTAILQ_INIT(&obj->properties);
+    object_init_with_type(obj, type);
+    object_post_init_with_type(obj, type);
+}
+
+void object_initialize(void *data, size_t size, const char *typename)
+{
+    TypeImpl *type = type_get_by_name(typename);
+
+    object_initialize_with_type(data, size, type);
+}
+
+static inline bool object_property_is_child(ObjectProperty *prop)
+{
+    return strstart(prop->type, "child<", NULL);
+}
+
+static inline bool object_property_is_link(ObjectProperty *prop)
+{
+    return strstart(prop->type, "link<", NULL);
+}
+
+static void object_property_del_all(Object *obj)
+{
+    while (!QTAILQ_EMPTY(&obj->properties)) {
+        ObjectProperty *prop = QTAILQ_FIRST(&obj->properties);
+
+        QTAILQ_REMOVE(&obj->properties, prop, node);
+
+        if (prop->release) {
+            prop->release(obj, prop->name, prop->opaque);
+        }
+
+        g_free(prop->name);
+        g_free(prop->type);
+        g_free(prop);
+    }
+}
+
+static void object_property_del_child(Object *obj, Object *child, Error **errp)
+{
+    ObjectProperty *prop;
+
+    QTAILQ_FOREACH(prop, &obj->properties, node) {
+        if (object_property_is_child(prop) && prop->opaque == child) {
+            object_property_del(obj, prop->name, errp);
+            break;
+        }
+    }
+}
+
+void object_unparent(Object *obj)
+{
+    if (!obj->parent) {
+        return;
+    }
+
+    object_ref(obj);
+    if (obj->class->unparent) {
+        (obj->class->unparent)(obj);
+    }
+    if (obj->parent) {
+        object_property_del_child(obj->parent, obj, NULL);
+    }
+    object_unref(obj);
+}
+
+static void object_deinit(Object *obj, TypeImpl *type)
+{
+    if (type->instance_finalize) {
+        type->instance_finalize(obj);
+    }
+
+    if (type_has_parent(type)) {
+        object_deinit(obj, type_get_parent(type));
+    }
+}
+
+static void object_finalize(void *data)
+{
+    Object *obj = data;
+    TypeImpl *ti = obj->class->type;
+
+    object_deinit(obj, ti);
+    object_property_del_all(obj);
+
+    g_assert(obj->ref == 0);
+    if (obj->free) {
+        obj->free(obj);
+    }
+}
+
+Object *object_new_with_type(Type type)
+{
+    Object *obj;
+
+    g_assert(type != NULL);
+    type_initialize(type);
+
+    obj = g_malloc(type->instance_size);
+    object_initialize_with_type(obj, type->instance_size, type);
+    obj->free = g_free;
+
+    return obj;
+}
+
+Object *object_new(const char *typename)
+{
+    TypeImpl *ti = type_get_by_name(typename);
+
+    return object_new_with_type(ti);
+}
+
+Object *object_dynamic_cast(Object *obj, const char *typename)
+{
+    if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) {
+        return obj;
+    }
+
+    return NULL;
+}
+
+Object *object_dynamic_cast_assert(Object *obj, const char *typename,
+                                   const char *file, int line, const char *func)
+{
+    trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
+                                     typename, file, line, func);
+
+#ifdef CONFIG_QOM_CAST_DEBUG
+    int i;
+    Object *inst;
+
+    for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
+        if (obj->class->cast_cache[i] == typename) {
+            goto out;
+        }
+    }
+
+    inst = object_dynamic_cast(obj, typename);
+
+    if (!inst && obj) {
+        fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
+                file, line, func, obj, typename);
+        abort();
+    }
+
+    assert(obj == inst);
+
+    if (obj && obj == inst) {
+        for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
+            obj->class->cast_cache[i - 1] = obj->class->cast_cache[i];
+        }
+        obj->class->cast_cache[i - 1] = typename;
+    }
+
+out:
+#endif
+    return obj;
+}
+
+ObjectClass *object_class_dynamic_cast(ObjectClass *class,
+                                       const char *typename)
+{
+    ObjectClass *ret = NULL;
+    TypeImpl *target_type;
+    TypeImpl *type;
+
+    if (!class) {
+        return NULL;
+    }
+
+    /* A simple fast path that can trigger a lot for leaf classes.  */
+    type = class->type;
+    if (type->name == typename) {
+        return class;
+    }
+
+    target_type = type_get_by_name(typename);
+    if (!target_type) {
+        /* target class type unknown, so fail the cast */
+        return NULL;
+    }
+
+    if (type->class->interfaces &&
+            type_is_ancestor(target_type, type_interface)) {
+        int found = 0;
+        GSList *i;
+
+        for (i = class->interfaces; i; i = i->next) {
+            ObjectClass *target_class = i->data;
+
+            if (type_is_ancestor(target_class->type, target_type)) {
+                ret = target_class;
+                found++;
+            }
+         }
+
+        /* The match was ambiguous, don't allow a cast */
+        if (found > 1) {
+            ret = NULL;
+        }
+    } else if (type_is_ancestor(type, target_type)) {
+        ret = class;
+    }
+
+    return ret;
+}
+
+ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
+                                              const char *typename,
+                                              const char *file, int line,
+                                              const char *func)
+{
+    ObjectClass *ret;
+
+    trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
+                                           typename, file, line, func);
+
+#ifdef CONFIG_QOM_CAST_DEBUG
+    int i;
+
+    for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
+        if (class->cast_cache[i] == typename) {
+            ret = class;
+            goto out;
+        }
+    }
+#else
+    if (!class || !class->interfaces) {
+        return class;
+    }
+#endif
+
+    ret = object_class_dynamic_cast(class, typename);
+    if (!ret && class) {
+        fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
+                file, line, func, class, typename);
+        abort();
+    }
+
+#ifdef CONFIG_QOM_CAST_DEBUG
+    if (class && ret == class) {
+        for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
+            class->cast_cache[i - 1] = class->cast_cache[i];
+        }
+        class->cast_cache[i - 1] = typename;
+    }
+out:
+#endif
+    return ret;
+}
+
+const char *object_get_typename(Object *obj)
+{
+    return obj->class->type->name;
+}
+
+ObjectClass *object_get_class(Object *obj)
+{
+    return obj->class;
+}
+
+bool object_class_is_abstract(ObjectClass *klass)
+{
+    return klass->type->abstract;
+}
+
+const char *object_class_get_name(ObjectClass *klass)
+{
+    return klass->type->name;
+}
+
+ObjectClass *object_class_by_name(const char *typename)
+{
+    TypeImpl *type = type_get_by_name(typename);
+
+    if (!type) {
+        return NULL;
+    }
+
+    type_initialize(type);
+
+    return type->class;
+}
+
+ObjectClass *object_class_get_parent(ObjectClass *class)
+{
+    TypeImpl *type = type_get_parent(class->type);
+
+    if (!type) {
+        return NULL;
+    }
+
+    type_initialize(type);
+
+    return type->class;
+}
+
+typedef struct OCFData
+{
+    void (*fn)(ObjectClass *klass, void *opaque);
+    const char *implements_type;
+    bool include_abstract;
+    void *opaque;
+} OCFData;
+
+static void object_class_foreach_tramp(gpointer key, gpointer value,
+                                       gpointer opaque)
+{
+    OCFData *data = opaque;
+    TypeImpl *type = value;
+    ObjectClass *k;
+
+    type_initialize(type);
+    k = type->class;
+
+    if (!data->include_abstract && type->abstract) {
+        return;
+    }
+
+    if (data->implements_type && 
+        !object_class_dynamic_cast(k, data->implements_type)) {
+        return;
+    }
+
+    data->fn(k, data->opaque);
+}
+
+void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
+                          const char *implements_type, bool include_abstract,
+                          void *opaque)
+{
+    OCFData data = { fn, implements_type, include_abstract, opaque };
+
+    g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
+}
+
+int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
+                         void *opaque)
+{
+    ObjectProperty *prop;
+    int ret = 0;
+
+    QTAILQ_FOREACH(prop, &obj->properties, node) {
+        if (object_property_is_child(prop)) {
+            ret = fn(prop->opaque, opaque);
+            if (ret != 0) {
+                break;
+            }
+        }
+    }
+    return ret;
+}
+
+static void object_class_get_list_tramp(ObjectClass *klass, void *opaque)
+{
+    GSList **list = opaque;
+
+    *list = g_slist_prepend(*list, klass);
+}
+
+GSList *object_class_get_list(const char *implements_type,
+                              bool include_abstract)
+{
+    GSList *list = NULL;
+
+    object_class_foreach(object_class_get_list_tramp,
+                         implements_type, include_abstract, &list);
+    return list;
+}
+
+void object_ref(Object *obj)
+{
+     atomic_inc(&obj->ref);
+}
+
+void object_unref(Object *obj)
+{
+    g_assert(obj->ref > 0);
+
+    /* parent always holds a reference to its children */
+    if (atomic_fetch_dec(&obj->ref) == 1) {
+        object_finalize(obj);
+    }
+}
+
+void object_property_add(Object *obj, const char *name, const char *type,
+                         ObjectPropertyAccessor *get,
+                         ObjectPropertyAccessor *set,
+                         ObjectPropertyRelease *release,
+                         void *opaque, Error **errp)
+{
+    ObjectProperty *prop;
+
+    QTAILQ_FOREACH(prop, &obj->properties, node) {
+        if (strcmp(prop->name, name) == 0) {
+            error_setg(errp, "attempt to add duplicate property '%s'"
+                       " to object (type '%s')", name,
+                       object_get_typename(obj));
+            return;
+        }
+    }
+
+    prop = g_malloc0(sizeof(*prop));
+
+    prop->name = g_strdup(name);
+    prop->type = g_strdup(type);
+
+    prop->get = get;
+    prop->set = set;
+    prop->release = release;
+    prop->opaque = opaque;
+
+    QTAILQ_INSERT_TAIL(&obj->properties, prop, node);
+}
+
+ObjectProperty *object_property_find(Object *obj, const char *name,
+                                     Error **errp)
+{
+    ObjectProperty *prop;
+
+    QTAILQ_FOREACH(prop, &obj->properties, node) {
+        if (strcmp(prop->name, name) == 0) {
+            return prop;
+        }
+    }
+
+    error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
+    return NULL;
+}
+
+void object_property_del(Object *obj, const char *name, Error **errp)
+{
+    ObjectProperty *prop = object_property_find(obj, name, errp);
+    if (prop == NULL) {
+        return;
+    }
+
+    if (prop->release) {
+        prop->release(obj, name, prop->opaque);
+    }
+
+    QTAILQ_REMOVE(&obj->properties, prop, node);
+
+    g_free(prop->name);
+    g_free(prop->type);
+    g_free(prop);
+}
+
+void object_property_get(Object *obj, Visitor *v, const char *name,
+                         Error **errp)
+{
+    ObjectProperty *prop = object_property_find(obj, name, errp);
+    if (prop == NULL) {
+        return;
+    }
+
+    if (!prop->get) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+    } else {
+        prop->get(obj, v, prop->opaque, name, errp);
+    }
+}
+
+void object_property_set(Object *obj, Visitor *v, const char *name,
+                         Error **errp)
+{
+    ObjectProperty *prop = object_property_find(obj, name, errp);
+    if (prop == NULL) {
+        return;
+    }
+
+    if (!prop->set) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+    } else {
+        prop->set(obj, v, prop->opaque, name, errp);
+    }
+}
+
+void object_property_set_str(Object *obj, const char *value,
+                             const char *name, Error **errp)
+{
+    QString *qstr = qstring_from_str(value);
+    object_property_set_qobject(obj, QOBJECT(qstr), name, errp);
+
+    QDECREF(qstr);
+}
+
+char *object_property_get_str(Object *obj, const char *name,
+                              Error **errp)
+{
+    QObject *ret = object_property_get_qobject(obj, name, errp);
+    QString *qstring;
+    char *retval;
+
+    if (!ret) {
+        return NULL;
+    }
+    qstring = qobject_to_qstring(ret);
+    if (!qstring) {
+        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
+        retval = NULL;
+    } else {
+        retval = g_strdup(qstring_get_str(qstring));
+    }
+
+    QDECREF(qstring);
+    return retval;
+}
+
+void object_property_set_link(Object *obj, Object *value,
+                              const char *name, Error **errp)
+{
+    gchar *path = object_get_canonical_path(value);
+    object_property_set_str(obj, path, name, errp);
+    g_free(path);
+}
+
+Object *object_property_get_link(Object *obj, const char *name,
+                                 Error **errp)
+{
+    char *str = object_property_get_str(obj, name, errp);
+    Object *target = NULL;
+
+    if (str && *str) {
+        target = object_resolve_path(str, NULL);
+        if (!target) {
+            error_set(errp, QERR_DEVICE_NOT_FOUND, str);
+        }
+    }
+
+    g_free(str);
+    return target;
+}
+
+void object_property_set_bool(Object *obj, bool value,
+                              const char *name, Error **errp)
+{
+    QBool *qbool = qbool_from_int(value);
+    object_property_set_qobject(obj, QOBJECT(qbool), name, errp);
+
+    QDECREF(qbool);
+}
+
+bool object_property_get_bool(Object *obj, const char *name,
+                              Error **errp)
+{
+    QObject *ret = object_property_get_qobject(obj, name, errp);
+    QBool *qbool;
+    bool retval;
+
+    if (!ret) {
+        return false;
+    }
+    qbool = qobject_to_qbool(ret);
+    if (!qbool) {
+        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
+        retval = false;
+    } else {
+        retval = qbool_get_int(qbool);
+    }
+
+    QDECREF(qbool);
+    return retval;
+}
+
+void object_property_set_int(Object *obj, int64_t value,
+                             const char *name, Error **errp)
+{
+    QInt *qint = qint_from_int(value);
+    object_property_set_qobject(obj, QOBJECT(qint), name, errp);
+
+    QDECREF(qint);
+}
+
+int64_t object_property_get_int(Object *obj, const char *name,
+                                Error **errp)
+{
+    QObject *ret = object_property_get_qobject(obj, name, errp);
+    QInt *qint;
+    int64_t retval;
+
+    if (!ret) {
+        return -1;
+    }
+    qint = qobject_to_qint(ret);
+    if (!qint) {
+        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
+        retval = -1;
+    } else {
+        retval = qint_get_int(qint);
+    }
+
+    QDECREF(qint);
+    return retval;
+}
+
+void object_property_parse(Object *obj, const char *string,
+                           const char *name, Error **errp)
+{
+    StringInputVisitor *mi;
+    mi = string_input_visitor_new(string);
+    object_property_set(obj, string_input_get_visitor(mi), name, errp);
+
+    string_input_visitor_cleanup(mi);
+}
+
+char *object_property_print(Object *obj, const char *name,
+                            Error **errp)
+{
+    StringOutputVisitor *mo;
+    char *string;
+
+    mo = string_output_visitor_new();
+    object_property_get(obj, string_output_get_visitor(mo), name, errp);
+    string = string_output_get_string(mo);
+    string_output_visitor_cleanup(mo);
+    return string;
+}
+
+const char *object_property_get_type(Object *obj, const char *name, Error **errp)
+{
+    ObjectProperty *prop = object_property_find(obj, name, errp);
+    if (prop == NULL) {
+        return NULL;
+    }
+
+    return prop->type;
+}
+
+Object *object_get_root(void)
+{
+    static Object *root;
+
+    if (!root) {
+        root = object_new("container");
+    }
+
+    return root;
+}
+
+static void object_get_child_property(Object *obj, Visitor *v, void *opaque,
+                                      const char *name, Error **errp)
+{
+    Object *child = opaque;
+    gchar *path;
+
+    path = object_get_canonical_path(child);
+    visit_type_str(v, &path, name, errp);
+    g_free(path);
+}
+
+static void object_finalize_child_property(Object *obj, const char *name,
+                                           void *opaque)
+{
+    Object *child = opaque;
+
+    object_unref(child);
+}
+
+void object_property_add_child(Object *obj, const char *name,
+                               Object *child, Error **errp)
+{
+    gchar *type;
+
+    type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
+
+    object_property_add(obj, name, type, object_get_child_property,
+                        NULL, object_finalize_child_property, child, errp);
+
+    object_ref(child);
+    g_assert(child->parent == NULL);
+    child->parent = obj;
+
+    g_free(type);
+}
+
+static void object_get_link_property(Object *obj, Visitor *v, void *opaque,
+                                     const char *name, Error **errp)
+{
+    Object **child = opaque;
+    gchar *path;
+
+    if (*child) {
+        path = object_get_canonical_path(*child);
+        visit_type_str(v, &path, name, errp);
+        g_free(path);
+    } else {
+        path = (gchar *)"";
+        visit_type_str(v, &path, name, errp);
+    }
+}
+
+static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
+                                     const char *name, Error **errp)
+{
+    Object **child = opaque;
+    Object *old_target;
+    bool ambiguous = false;
+    const char *type;
+    char *path;
+    gchar *target_type;
+
+    type = object_property_get_type(obj, name, NULL);
+
+    visit_type_str(v, &path, name, errp);
+
+    old_target = *child;
+    *child = NULL;
+
+    if (strcmp(path, "") != 0) {
+        Object *target;
+
+        /* Go from link<FOO> to FOO.  */
+        target_type = g_strndup(&type[5], strlen(type) - 6);
+        target = object_resolve_path_type(path, target_type, &ambiguous);
+
+        if (ambiguous) {
+            error_set(errp, QERR_AMBIGUOUS_PATH, path);
+        } else if (target) {
+            object_ref(target);
+            *child = target;
+        } else {
+            target = object_resolve_path(path, &ambiguous);
+            if (target || ambiguous) {
+                error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
+            } else {
+                error_set(errp, QERR_DEVICE_NOT_FOUND, path);
+            }
+        }
+        g_free(target_type);
+    }
+
+    g_free(path);
+
+    if (old_target != NULL) {
+        object_unref(old_target);
+    }
+}
+
+void object_property_add_link(Object *obj, const char *name,
+                              const char *type, Object **child,
+                              Error **errp)
+{
+    gchar *full_type;
+
+    full_type = g_strdup_printf("link<%s>", type);
+
+    object_property_add(obj, name, full_type,
+                        object_get_link_property,
+                        object_set_link_property,
+                        NULL, child, errp);
+
+    g_free(full_type);
+}
+
+gchar *object_get_canonical_path(Object *obj)
+{
+    Object *root = object_get_root();
+    char *newpath = NULL, *path = NULL;
+
+    while (obj != root) {
+        ObjectProperty *prop = NULL;
+
+        g_assert(obj->parent != NULL);
+
+        QTAILQ_FOREACH(prop, &obj->parent->properties, node) {
+            if (!object_property_is_child(prop)) {
+                continue;
+            }
+
+            if (prop->opaque == obj) {
+                if (path) {
+                    newpath = g_strdup_printf("%s/%s", prop->name, path);
+                    g_free(path);
+                    path = newpath;
+                } else {
+                    path = g_strdup(prop->name);
+                }
+                break;
+            }
+        }
+
+        g_assert(prop != NULL);
+
+        obj = obj->parent;
+    }
+
+    newpath = g_strdup_printf("/%s", path);
+    g_free(path);
+
+    return newpath;
+}
+
+Object *object_resolve_path_component(Object *parent, const gchar *part)
+{
+    ObjectProperty *prop = object_property_find(parent, part, NULL);
+    if (prop == NULL) {
+        return NULL;
+    }
+
+    if (object_property_is_link(prop)) {
+        return *(Object **)prop->opaque;
+    } else if (object_property_is_child(prop)) {
+        return prop->opaque;
+    } else {
+        return NULL;
+    }
+}
+
+static Object *object_resolve_abs_path(Object *parent,
+                                          gchar **parts,
+                                          const char *typename,
+                                          int index)
+{
+    Object *child;
+
+    if (parts[index] == NULL) {
+        return object_dynamic_cast(parent, typename);
+    }
+
+    if (strcmp(parts[index], "") == 0) {
+        return object_resolve_abs_path(parent, parts, typename, index + 1);
+    }
+
+    child = object_resolve_path_component(parent, parts[index]);
+    if (!child) {
+        return NULL;
+    }
+
+    return object_resolve_abs_path(child, parts, typename, index + 1);
+}
+
+static Object *object_resolve_partial_path(Object *parent,
+                                              gchar **parts,
+                                              const char *typename,
+                                              bool *ambiguous)
+{
+    Object *obj;
+    ObjectProperty *prop;
+
+    obj = object_resolve_abs_path(parent, parts, typename, 0);
+
+    QTAILQ_FOREACH(prop, &parent->properties, node) {
+        Object *found;
+
+        if (!object_property_is_child(prop)) {
+            continue;
+        }
+
+        found = object_resolve_partial_path(prop->opaque, parts,
+                                            typename, ambiguous);
+        if (found) {
+            if (obj) {
+                if (ambiguous) {
+                    *ambiguous = true;
+                }
+                return NULL;
+            }
+            obj = found;
+        }
+
+        if (ambiguous && *ambiguous) {
+            return NULL;
+        }
+    }
+
+    return obj;
+}
+
+Object *object_resolve_path_type(const char *path, const char *typename,
+                                 bool *ambiguous)
+{
+    Object *obj;
+    gchar **parts;
+
+    parts = g_strsplit(path, "/", 0);
+    assert(parts);
+
+    if (parts[0] == NULL || strcmp(parts[0], "") != 0) {
+        if (ambiguous) {
+            *ambiguous = false;
+        }
+        obj = object_resolve_partial_path(object_get_root(), parts,
+                                          typename, ambiguous);
+    } else {
+        obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
+    }
+
+    g_strfreev(parts);
+
+    return obj;
+}
+
+Object *object_resolve_path(const char *path, bool *ambiguous)
+{
+    return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
+}
+
+typedef struct StringProperty
+{
+    char *(*get)(Object *, Error **);
+    void (*set)(Object *, const char *, Error **);
+} StringProperty;
+
+static void property_get_str(Object *obj, Visitor *v, void *opaque,
+                             const char *name, Error **errp)
+{
+    StringProperty *prop = opaque;
+    char *value;
+
+    value = prop->get(obj, errp);
+    if (value) {
+        visit_type_str(v, &value, name, errp);
+        g_free(value);
+    }
+}
+
+static void property_set_str(Object *obj, Visitor *v, void *opaque,
+                             const char *name, Error **errp)
+{
+    StringProperty *prop = opaque;
+    char *value;
+    Error *local_err = NULL;
+
+    visit_type_str(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    prop->set(obj, value, errp);
+    g_free(value);
+}
+
+static void property_release_str(Object *obj, const char *name,
+                                 void *opaque)
+{
+    StringProperty *prop = opaque;
+    g_free(prop);
+}
+
+void object_property_add_str(Object *obj, const char *name,
+                           char *(*get)(Object *, Error **),
+                           void (*set)(Object *, const char *, Error **),
+                           Error **errp)
+{
+    StringProperty *prop = g_malloc0(sizeof(*prop));
+
+    prop->get = get;
+    prop->set = set;
+
+    object_property_add(obj, name, "string",
+                        get ? property_get_str : NULL,
+                        set ? property_set_str : NULL,
+                        property_release_str,
+                        prop, errp);
+}
+
+typedef struct BoolProperty
+{
+    bool (*get)(Object *, Error **);
+    void (*set)(Object *, bool, Error **);
+} BoolProperty;
+
+static void property_get_bool(Object *obj, Visitor *v, void *opaque,
+                              const char *name, Error **errp)
+{
+    BoolProperty *prop = opaque;
+    bool value;
+
+    value = prop->get(obj, errp);
+    visit_type_bool(v, &value, name, errp);
+}
+
+static void property_set_bool(Object *obj, Visitor *v, void *opaque,
+                              const char *name, Error **errp)
+{
+    BoolProperty *prop = opaque;
+    bool value;
+    Error *local_err = NULL;
+
+    visit_type_bool(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    prop->set(obj, value, errp);
+}
+
+static void property_release_bool(Object *obj, const char *name,
+                                  void *opaque)
+{
+    BoolProperty *prop = opaque;
+    g_free(prop);
+}
+
+void object_property_add_bool(Object *obj, const char *name,
+                              bool (*get)(Object *, Error **),
+                              void (*set)(Object *, bool, Error **),
+                              Error **errp)
+{
+    BoolProperty *prop = g_malloc0(sizeof(*prop));
+
+    prop->get = get;
+    prop->set = set;
+
+    object_property_add(obj, name, "bool",
+                        get ? property_get_bool : NULL,
+                        set ? property_set_bool : NULL,
+                        property_release_bool,
+                        prop, errp);
+}
+
+static char *qdev_get_type(Object *obj, Error **errp)
+{
+    return g_strdup(object_get_typename(obj));
+}
+
+static void property_get_uint8_ptr(Object *obj, Visitor *v,
+                                   void *opaque, const char *name,
+                                   Error **errp)
+{
+    uint8_t value = *(uint8_t *)opaque;
+    visit_type_uint8(v, &value, name, errp);
+}
+
+static void property_get_uint16_ptr(Object *obj, Visitor *v,
+                                   void *opaque, const char *name,
+                                   Error **errp)
+{
+    uint16_t value = *(uint16_t *)opaque;
+    visit_type_uint16(v, &value, name, errp);
+}
+
+static void property_get_uint32_ptr(Object *obj, Visitor *v,
+                                   void *opaque, const char *name,
+                                   Error **errp)
+{
+    uint32_t value = *(uint32_t *)opaque;
+    visit_type_uint32(v, &value, name, errp);
+}
+
+static void property_get_uint64_ptr(Object *obj, Visitor *v,
+                                   void *opaque, const char *name,
+                                   Error **errp)
+{
+    uint64_t value = *(uint64_t *)opaque;
+    visit_type_uint64(v, &value, name, errp);
+}
+
+void object_property_add_uint8_ptr(Object *obj, const char *name,
+                                   const uint8_t *v, Error **errp)
+{
+    object_property_add(obj, name, "uint8", property_get_uint8_ptr,
+                        NULL, NULL, (void *)v, errp);
+}
+
+void object_property_add_uint16_ptr(Object *obj, const char *name,
+                                    const uint16_t *v, Error **errp)
+{
+    object_property_add(obj, name, "uint16", property_get_uint16_ptr,
+                        NULL, NULL, (void *)v, errp);
+}
+
+void object_property_add_uint32_ptr(Object *obj, const char *name,
+                                    const uint32_t *v, Error **errp)
+{
+    object_property_add(obj, name, "uint32", property_get_uint32_ptr,
+                        NULL, NULL, (void *)v, errp);
+}
+
+void object_property_add_uint64_ptr(Object *obj, const char *name,
+                                    const uint64_t *v, Error **errp)
+{
+    object_property_add(obj, name, "uint64", property_get_uint64_ptr,
+                        NULL, NULL, (void *)v, errp);
+}
+
+static void object_instance_init(Object *obj)
+{
+    object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
+}
+
+static void register_types(void)
+{
+    static TypeInfo interface_info = {
+        .name = TYPE_INTERFACE,
+        .class_size = sizeof(InterfaceClass),
+        .abstract = true,
+    };
+
+    static TypeInfo object_info = {
+        .name = TYPE_OBJECT,
+        .instance_size = sizeof(Object),
+        .instance_init = object_instance_init,
+        .abstract = true,
+    };
+
+    type_interface = type_register_internal(&interface_info);
+    type_register_internal(&object_info);
+}
+
+type_init(register_types)
diff --git a/qom/qom-qobject.c b/qom/qom-qobject.c
new file mode 100644
index 0000000..6384b8e
--- /dev/null
+++ b/qom/qom-qobject.c
@@ -0,0 +1,44 @@
+/*
+ * QEMU Object Model - QObject wrappers
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Author: 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 "qemu-common.h"
+#include "qom/object.h"
+#include "qom/qom-qobject.h"
+#include "qapi/visitor.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/qmp-output-visitor.h"
+
+void object_property_set_qobject(Object *obj, QObject *value,
+                                 const char *name, Error **errp)
+{
+    QmpInputVisitor *mi;
+    mi = qmp_input_visitor_new(value);
+    object_property_set(obj, qmp_input_get_visitor(mi), name, errp);
+
+    qmp_input_visitor_cleanup(mi);
+}
+
+QObject *object_property_get_qobject(Object *obj, const char *name,
+                                     Error **errp)
+{
+    QObject *ret = NULL;
+    Error *local_err = NULL;
+    QmpOutputVisitor *mo;
+
+    mo = qmp_output_visitor_new();
+    object_property_get(obj, qmp_output_get_visitor(mo), name, &local_err);
+    if (!local_err) {
+        ret = qmp_output_get_qobject(mo);
+    }
+    error_propagate(errp, local_err);
+    qmp_output_visitor_cleanup(mo);
+    return ret;
+}
diff --git a/readline.c b/readline.c
deleted file mode 100644
index f493349..0000000
--- a/readline.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * QEMU readline utility
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "monitor/readline.h"
-#include "monitor/monitor.h"
-
-#define IS_NORM 0
-#define IS_ESC  1
-#define IS_CSI  2
-
-#undef printf
-#define printf do_not_use_printf
-
-void readline_show_prompt(ReadLineState *rs)
-{
-    monitor_printf(rs->mon, "%s", rs->prompt);
-    monitor_flush(rs->mon);
-    rs->last_cmd_buf_index = 0;
-    rs->last_cmd_buf_size = 0;
-    rs->esc_state = IS_NORM;
-}
-
-/* update the displayed command line */
-static void readline_update(ReadLineState *rs)
-{
-    int i, delta, len;
-
-    if (rs->cmd_buf_size != rs->last_cmd_buf_size ||
-        memcmp(rs->cmd_buf, rs->last_cmd_buf, rs->cmd_buf_size) != 0) {
-        for(i = 0; i < rs->last_cmd_buf_index; i++) {
-            monitor_printf(rs->mon, "\033[D");
-        }
-        rs->cmd_buf[rs->cmd_buf_size] = '\0';
-        if (rs->read_password) {
-            len = strlen(rs->cmd_buf);
-            for(i = 0; i < len; i++)
-                monitor_printf(rs->mon, "*");
-        } else {
-            monitor_printf(rs->mon, "%s", rs->cmd_buf);
-        }
-        monitor_printf(rs->mon, "\033[K");
-        memcpy(rs->last_cmd_buf, rs->cmd_buf, rs->cmd_buf_size);
-        rs->last_cmd_buf_size = rs->cmd_buf_size;
-        rs->last_cmd_buf_index = rs->cmd_buf_size;
-    }
-    if (rs->cmd_buf_index != rs->last_cmd_buf_index) {
-        delta = rs->cmd_buf_index - rs->last_cmd_buf_index;
-        if (delta > 0) {
-            for(i = 0;i < delta; i++) {
-                monitor_printf(rs->mon, "\033[C");
-            }
-        } else {
-            delta = -delta;
-            for(i = 0;i < delta; i++) {
-                monitor_printf(rs->mon, "\033[D");
-            }
-        }
-        rs->last_cmd_buf_index = rs->cmd_buf_index;
-    }
-    monitor_flush(rs->mon);
-}
-
-static void readline_insert_char(ReadLineState *rs, int ch)
-{
-    if (rs->cmd_buf_index < READLINE_CMD_BUF_SIZE) {
-        memmove(rs->cmd_buf + rs->cmd_buf_index + 1,
-                rs->cmd_buf + rs->cmd_buf_index,
-                rs->cmd_buf_size - rs->cmd_buf_index);
-        rs->cmd_buf[rs->cmd_buf_index] = ch;
-        rs->cmd_buf_size++;
-        rs->cmd_buf_index++;
-    }
-}
-
-static void readline_backward_char(ReadLineState *rs)
-{
-    if (rs->cmd_buf_index > 0) {
-        rs->cmd_buf_index--;
-    }
-}
-
-static void readline_forward_char(ReadLineState *rs)
-{
-    if (rs->cmd_buf_index < rs->cmd_buf_size) {
-        rs->cmd_buf_index++;
-    }
-}
-
-static void readline_delete_char(ReadLineState *rs)
-{
-    if (rs->cmd_buf_index < rs->cmd_buf_size) {
-        memmove(rs->cmd_buf + rs->cmd_buf_index,
-                rs->cmd_buf + rs->cmd_buf_index + 1,
-                rs->cmd_buf_size - rs->cmd_buf_index - 1);
-        rs->cmd_buf_size--;
-    }
-}
-
-static void readline_backspace(ReadLineState *rs)
-{
-    if (rs->cmd_buf_index > 0) {
-        readline_backward_char(rs);
-        readline_delete_char(rs);
-    }
-}
-
-static void readline_backword(ReadLineState *rs)
-{
-    int start;
-
-    if (rs->cmd_buf_index == 0 || rs->cmd_buf_index > rs->cmd_buf_size) {
-        return;
-    }
-
-    start = rs->cmd_buf_index - 1;
-
-    /* find first word (backwards) */
-    while (start > 0) {
-        if (!qemu_isspace(rs->cmd_buf[start])) {
-            break;
-        }
-
-        --start;
-    }
-
-    /* find first space (backwards) */
-    while (start > 0) {
-        if (qemu_isspace(rs->cmd_buf[start])) {
-            ++start;
-            break;
-        }
-
-        --start;
-    }
-
-    /* remove word */
-    if (start < rs->cmd_buf_index) {
-        memmove(rs->cmd_buf + start,
-                rs->cmd_buf + rs->cmd_buf_index,
-                rs->cmd_buf_size - rs->cmd_buf_index);
-        rs->cmd_buf_size -= rs->cmd_buf_index - start;
-        rs->cmd_buf_index = start;
-    }
-}
-
-static void readline_bol(ReadLineState *rs)
-{
-    rs->cmd_buf_index = 0;
-}
-
-static void readline_eol(ReadLineState *rs)
-{
-    rs->cmd_buf_index = rs->cmd_buf_size;
-}
-
-static void readline_up_char(ReadLineState *rs)
-{
-    int idx;
-
-    if (rs->hist_entry == 0)
-	return;
-    if (rs->hist_entry == -1) {
-	/* Find latest entry */
-	for (idx = 0; idx < READLINE_MAX_CMDS; idx++) {
-	    if (rs->history[idx] == NULL)
-		break;
-	}
-	rs->hist_entry = idx;
-    }
-    rs->hist_entry--;
-    if (rs->hist_entry >= 0) {
-	pstrcpy(rs->cmd_buf, sizeof(rs->cmd_buf),
-                rs->history[rs->hist_entry]);
-	rs->cmd_buf_index = rs->cmd_buf_size = strlen(rs->cmd_buf);
-    }
-}
-
-static void readline_down_char(ReadLineState *rs)
-{
-    if (rs->hist_entry == -1)
-        return;
-    if (rs->hist_entry < READLINE_MAX_CMDS - 1 &&
-        rs->history[++rs->hist_entry] != NULL) {
-	pstrcpy(rs->cmd_buf, sizeof(rs->cmd_buf),
-                rs->history[rs->hist_entry]);
-    } else {
-        rs->cmd_buf[0] = 0;
-	rs->hist_entry = -1;
-    }
-    rs->cmd_buf_index = rs->cmd_buf_size = strlen(rs->cmd_buf);
-}
-
-static void readline_hist_add(ReadLineState *rs, const char *cmdline)
-{
-    char *hist_entry, *new_entry;
-    int idx;
-
-    if (cmdline[0] == '\0')
-	return;
-    new_entry = NULL;
-    if (rs->hist_entry != -1) {
-	/* We were editing an existing history entry: replace it */
-	hist_entry = rs->history[rs->hist_entry];
-	idx = rs->hist_entry;
-	if (strcmp(hist_entry, cmdline) == 0) {
-	    goto same_entry;
-	}
-    }
-    /* Search cmdline in history buffers */
-    for (idx = 0; idx < READLINE_MAX_CMDS; idx++) {
-	hist_entry = rs->history[idx];
-	if (hist_entry == NULL)
-	    break;
-	if (strcmp(hist_entry, cmdline) == 0) {
-	same_entry:
-	    new_entry = hist_entry;
-	    /* Put this entry at the end of history */
-	    memmove(&rs->history[idx], &rs->history[idx + 1],
-		    (READLINE_MAX_CMDS - idx + 1) * sizeof(char *));
-	    rs->history[READLINE_MAX_CMDS - 1] = NULL;
-	    for (; idx < READLINE_MAX_CMDS; idx++) {
-		if (rs->history[idx] == NULL)
-		    break;
-	    }
-	    break;
-	}
-    }
-    if (idx == READLINE_MAX_CMDS) {
-	/* Need to get one free slot */
-	free(rs->history[0]);
-	memcpy(rs->history, &rs->history[1],
-	       (READLINE_MAX_CMDS - 1) * sizeof(char *));
-	rs->history[READLINE_MAX_CMDS - 1] = NULL;
-	idx = READLINE_MAX_CMDS - 1;
-    }
-    if (new_entry == NULL)
-	new_entry = strdup(cmdline);
-    rs->history[idx] = new_entry;
-    rs->hist_entry = -1;
-}
-
-/* completion support */
-
-void readline_add_completion(ReadLineState *rs, const char *str)
-{
-    if (rs->nb_completions < READLINE_MAX_COMPLETIONS) {
-        rs->completions[rs->nb_completions++] = g_strdup(str);
-    }
-}
-
-void readline_set_completion_index(ReadLineState *rs, int index)
-{
-    rs->completion_index = index;
-}
-
-static void readline_completion(ReadLineState *rs)
-{
-    Monitor *mon = cur_mon;
-    int len, i, j, max_width, nb_cols, max_prefix;
-    char *cmdline;
-
-    rs->nb_completions = 0;
-
-    cmdline = g_malloc(rs->cmd_buf_index + 1);
-    memcpy(cmdline, rs->cmd_buf, rs->cmd_buf_index);
-    cmdline[rs->cmd_buf_index] = '\0';
-    rs->completion_finder(cmdline);
-    g_free(cmdline);
-
-    /* no completion found */
-    if (rs->nb_completions <= 0)
-        return;
-    if (rs->nb_completions == 1) {
-        len = strlen(rs->completions[0]);
-        for(i = rs->completion_index; i < len; i++) {
-            readline_insert_char(rs, rs->completions[0][i]);
-        }
-        /* extra space for next argument. XXX: make it more generic */
-        if (len > 0 && rs->completions[0][len - 1] != '/')
-            readline_insert_char(rs, ' ');
-    } else {
-        monitor_printf(mon, "\n");
-        max_width = 0;
-        max_prefix = 0;	
-        for(i = 0; i < rs->nb_completions; i++) {
-            len = strlen(rs->completions[i]);
-            if (i==0) {
-                max_prefix = len;
-            } else {
-                if (len < max_prefix)
-                    max_prefix = len;
-                for(j=0; j<max_prefix; j++) {
-                    if (rs->completions[i][j] != rs->completions[0][j])
-                        max_prefix = j;
-                }
-            }
-            if (len > max_width)
-                max_width = len;
-        }
-        if (max_prefix > 0) 
-            for(i = rs->completion_index; i < max_prefix; i++) {
-                readline_insert_char(rs, rs->completions[0][i]);
-            }
-        max_width += 2;
-        if (max_width < 10)
-            max_width = 10;
-        else if (max_width > 80)
-            max_width = 80;
-        nb_cols = 80 / max_width;
-        j = 0;
-        for(i = 0; i < rs->nb_completions; i++) {
-            monitor_printf(rs->mon, "%-*s", max_width, rs->completions[i]);
-            if (++j == nb_cols || i == (rs->nb_completions - 1)) {
-                monitor_printf(rs->mon, "\n");
-                j = 0;
-            }
-        }
-        readline_show_prompt(rs);
-    }
-}
-
-/* return true if command handled */
-void readline_handle_byte(ReadLineState *rs, int ch)
-{
-    switch(rs->esc_state) {
-    case IS_NORM:
-        switch(ch) {
-        case 1:
-            readline_bol(rs);
-            break;
-        case 4:
-            readline_delete_char(rs);
-            break;
-        case 5:
-            readline_eol(rs);
-            break;
-        case 9:
-            readline_completion(rs);
-            break;
-        case 10:
-        case 13:
-            rs->cmd_buf[rs->cmd_buf_size] = '\0';
-            if (!rs->read_password)
-                readline_hist_add(rs, rs->cmd_buf);
-            monitor_printf(rs->mon, "\n");
-            rs->cmd_buf_index = 0;
-            rs->cmd_buf_size = 0;
-            rs->last_cmd_buf_index = 0;
-            rs->last_cmd_buf_size = 0;
-            rs->readline_func(rs->mon, rs->cmd_buf, rs->readline_opaque);
-            break;
-        case 23:
-            /* ^W */
-            readline_backword(rs);
-            break;
-        case 27:
-            rs->esc_state = IS_ESC;
-            break;
-        case 127:
-        case 8:
-            readline_backspace(rs);
-            break;
-	case 155:
-            rs->esc_state = IS_CSI;
-	    break;
-        default:
-            if (ch >= 32) {
-                readline_insert_char(rs, ch);
-            }
-            break;
-        }
-        break;
-    case IS_ESC:
-        if (ch == '[') {
-            rs->esc_state = IS_CSI;
-            rs->esc_param = 0;
-        } else {
-            rs->esc_state = IS_NORM;
-        }
-        break;
-    case IS_CSI:
-        switch(ch) {
-	case 'A':
-	case 'F':
-	    readline_up_char(rs);
-	    break;
-	case 'B':
-	case 'E':
-	    readline_down_char(rs);
-	    break;
-        case 'D':
-            readline_backward_char(rs);
-            break;
-        case 'C':
-            readline_forward_char(rs);
-            break;
-        case '0' ... '9':
-            rs->esc_param = rs->esc_param * 10 + (ch - '0');
-            goto the_end;
-        case '~':
-            switch(rs->esc_param) {
-            case 1:
-                readline_bol(rs);
-                break;
-            case 3:
-                readline_delete_char(rs);
-                break;
-            case 4:
-                readline_eol(rs);
-                break;
-            }
-            break;
-        default:
-            break;
-        }
-        rs->esc_state = IS_NORM;
-    the_end:
-        break;
-    }
-    readline_update(rs);
-}
-
-void readline_start(ReadLineState *rs, const char *prompt, int read_password,
-                    ReadLineFunc *readline_func, void *opaque)
-{
-    pstrcpy(rs->prompt, sizeof(rs->prompt), prompt);
-    rs->readline_func = readline_func;
-    rs->readline_opaque = opaque;
-    rs->read_password = read_password;
-    readline_restart(rs);
-}
-
-void readline_restart(ReadLineState *rs)
-{
-    rs->cmd_buf_index = 0;
-    rs->cmd_buf_size = 0;
-}
-
-const char *readline_get_history(ReadLineState *rs, unsigned int index)
-{
-    if (index >= READLINE_MAX_CMDS)
-        return NULL;
-    return rs->history[index];
-}
-
-ReadLineState *readline_init(Monitor *mon,
-                             ReadLineCompletionFunc *completion_finder)
-{
-    ReadLineState *rs = g_malloc0(sizeof(*rs));
-
-    rs->hist_entry = -1;
-    rs->mon = mon;
-    rs->completion_finder = completion_finder;
-
-    return rs;
-}
-
-void readline_free(ReadLineState *rs)
-{
-    if (rs) {
-        rs->mon = NULL;
-        rs->completion_finder = NULL;
-        g_free(rs);
-    }
-}
diff --git a/savevm.c b/savevm.c
index a81b166..005b0c3 100644
--- a/savevm.c
+++ b/savevm.c
@@ -75,6 +75,7 @@
 #include "net/net.h"
 #include "monitor/monitor.h"
 #include "sysemu/sysemu.h"
+#include "qemu/iov.h"
 #include "qemu/timer.h"
 #include "sysemu/char.h"
 #include "sysemu/blockdev.h"
@@ -160,24 +161,25 @@
 /* savevm/loadvm support */
 
 #define IO_BUF_SIZE 32768
+#define MAX_IOV_SIZE MIN(IOV_MAX, 64)
 
 struct QEMUFile {
-    QEMUFilePutBufferFunc *put_buffer;
-    QEMUFileGetBufferFunc *get_buffer;
-    QEMUFileCloseFunc *close;
-    QEMUFileRateLimit *rate_limit;
-    QEMUFileSetRateLimit *set_rate_limit;
-    QEMUFileGetRateLimit *get_rate_limit;
+    const QEMUFileOps *ops;
     void *opaque;
-    int is_write;
 
-    int64_t buf_offset; /* start of buffer when writing, end of buffer
-                           when reading */
+    int64_t bytes_xfer;
+    int64_t xfer_limit;
+
+    int64_t pos; /* start of buffer when writing, end of buffer
+                    when reading */
     int buf_index;
     int buf_size; /* 0 when writing */
     uint8_t buf[IO_BUF_SIZE];
 
-    int has_error;
+    struct iovec iov[MAX_IOV_SIZE];
+    unsigned int iovcnt;
+
+    int last_error;
 };
 
 typedef struct QEMUFileStdio
@@ -192,28 +194,71 @@
     QEMUFile *file;
 } QEMUFileSocket;
 
+static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
+                                    int64_t pos)
+{
+    QEMUFileSocket *s = opaque;
+    ssize_t len;
+    ssize_t size = iov_size(iov, iovcnt);
+
+    len = iov_send(s->fd, iov, iovcnt, 0, size);
+    if (len < size) {
+        len = -socket_error();
+    }
+    return len;
+}
+
+static int socket_get_fd(void *opaque)
+{
+    QEMUFileSocket *s = opaque;
+
+    return s->fd;
+}
+
 static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
 {
     QEMUFileSocket *s = opaque;
     ssize_t len;
 
-    do {
-        len = recv(s->fd, (void *)buf, size, 0);
-    } while (len == -1 && socket_error() == EINTR);
+    for (;;) {
+        len = qemu_recv(s->fd, buf, size, 0);
+        if (len != -1) {
+            break;
+        }
+#ifndef CONFIG_ANDROID
+        if (socket_error() == EAGAIN) {
+            yield_until_fd_readable(s->fd);
+        } else if (socket_error() != EINTR) {
+            break;
+        }
+#else
+       if (socket_error() != EINTR)
+           break;
+#endif
+    }
 
-    if (len == -1)
+    if (len == -1) {
         len = -socket_error();
-
+    }
     return len;
 }
 
 static int file_socket_close(void *opaque)
 {
     QEMUFileSocket *s = opaque;
+    if (s->fd >= 0)
+        socket_close(s->fd);
     g_free(s);
     return 0;
 }
 
+static int stdio_get_fd(void *opaque)
+{
+    QEMUFileStdio *s = opaque;
+
+    return fileno(s->stdio_file);
+}
+
 static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
 {
     QEMUFileStdio *s = opaque;
@@ -226,10 +271,23 @@
     FILE *fp = s->stdio_file;
     int bytes;
 
-    do {
+    for (;;) {
         clearerr(fp);
         bytes = fread(buf, 1, size, fp);
-    } while ((bytes == 0) && ferror(fp) && (errno == EINTR));
+        if (bytes != 0 || !ferror(fp)) {
+            break;
+        }
+#ifndef CONFIG_ANDROID
+        if (errno == EAGAIN) {
+            yield_until_fd_readable(fileno(fp));
+        } else if (errno != EINTR) {
+            break;
+        }
+#else
+        if (errno != EINTR)
+            break;
+#endif
+    }
     return bytes;
 }
 
@@ -238,6 +296,12 @@
     QEMUFileStdio *s = opaque;
     int ret;
     ret = pclose(s->stdio_file);
+    if (ret == -1) {
+        ret = -errno;
+    } else if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) {
+        /* close succeeded, but non-zero exit code: */
+        ret = -EIO; /* fake errno value */
+    }
     g_free(s);
     return ret;
 }
@@ -245,60 +309,171 @@
 static int stdio_fclose(void *opaque)
 {
     QEMUFileStdio *s = opaque;
-    fclose(s->stdio_file);
+    int ret = 0;
+
+    if (s->file->ops->put_buffer || s->file->ops->writev_buffer) {
+        int fd = fileno(s->stdio_file);
+        struct stat st;
+
+        ret = fstat(fd, &st);
+        if (ret == 0 && S_ISREG(st.st_mode)) {
+            /*
+             * If the file handle is a regular file make sure the
+             * data is flushed to disk before signaling success.
+             */
+            ret = fsync(fd);
+            if (ret != 0) {
+                ret = -errno;
+                return ret;
+            }
+        }
+    }
+    if (fclose(s->stdio_file) == EOF) {
+        ret = -errno;
+    }
     g_free(s);
-    return 0;
+    return ret;
 }
 
-QEMUFile *qemu_popen(FILE *stdio_file, const char *mode)
+static const QEMUFileOps stdio_pipe_read_ops = {
+    .get_fd =     stdio_get_fd,
+    .get_buffer = stdio_get_buffer,
+    .close =      stdio_pclose
+};
+
+static const QEMUFileOps stdio_pipe_write_ops = {
+    .get_fd =     stdio_get_fd,
+    .put_buffer = stdio_put_buffer,
+    .close =      stdio_pclose
+};
+
+QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
 {
+    FILE *stdio_file;
     QEMUFileStdio *s;
 
-    if (stdio_file == NULL || mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
+    if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
         fprintf(stderr, "qemu_popen: Argument validity check failed\n");
         return NULL;
     }
 
+    stdio_file = popen(command, mode);
+    if (stdio_file == NULL) {
+        return NULL;
+    }
+
     s = g_malloc0(sizeof(QEMUFileStdio));
 
     s->stdio_file = stdio_file;
 
     if(mode[0] == 'r') {
-        s->file = qemu_fopen_ops(s, NULL, stdio_get_buffer, stdio_pclose,
-				 NULL, NULL, NULL);
+        s->file = qemu_fopen_ops(s, &stdio_pipe_read_ops);
     } else {
-        s->file = qemu_fopen_ops(s, stdio_put_buffer, NULL, stdio_pclose,
-				 NULL, NULL, NULL);
+        s->file = qemu_fopen_ops(s, &stdio_pipe_write_ops);
     }
     return s->file;
 }
 
-QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
-{
-    FILE *popen_file;
+static const QEMUFileOps stdio_file_read_ops = {
+    .get_fd =     stdio_get_fd,
+    .get_buffer = stdio_get_buffer,
+    .close =      stdio_fclose
+};
 
-    popen_file = popen(command, mode);
-    if(popen_file == NULL) {
-        return NULL;
+static const QEMUFileOps stdio_file_write_ops = {
+    .get_fd =     stdio_get_fd,
+    .put_buffer = stdio_put_buffer,
+    .close =      stdio_fclose
+};
+
+static ssize_t unix_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
+                                  int64_t pos)
+{
+    QEMUFileSocket *s = opaque;
+    ssize_t len, offset;
+    ssize_t size = iov_size(iov, iovcnt);
+    ssize_t total = 0;
+
+    assert(iovcnt > 0);
+    offset = 0;
+    while (size > 0) {
+        /* Find the next start position; skip all full-sized vector elements  */
+        while (offset >= iov[0].iov_len) {
+            offset -= iov[0].iov_len;
+            iov++, iovcnt--;
+        }
+
+        /* skip `offset' bytes from the (now) first element, undo it on exit */
+        assert(iovcnt > 0);
+        iov[0].iov_base += offset;
+        iov[0].iov_len -= offset;
+
+        do {
+            len = writev(s->fd, iov, iovcnt);
+        } while (len == -1 && errno == EINTR);
+        if (len == -1) {
+            return -errno;
+        }
+
+        /* Undo the changes above */
+        iov[0].iov_base -= offset;
+        iov[0].iov_len += offset;
+
+        /* Prepare for the next iteration */
+        offset += len;
+        total += len;
+        size -= len;
     }
 
-    return qemu_popen(popen_file, mode);
+    return total;
 }
 
-int qemu_stdio_fd(QEMUFile *f)
+static int unix_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
 {
-    QEMUFileStdio *p;
-    int fd;
+    QEMUFileSocket *s = opaque;
+    ssize_t len;
 
-    p = (QEMUFileStdio *)f->opaque;
-    fd = fileno(p->stdio_file);
+    for (;;) {
+        len = read(s->fd, buf, size);
+        if (len != -1) {
+            break;
+        }
+        if (errno == EAGAIN) {
+            yield_until_fd_readable(s->fd);
+        } else if (errno != EINTR) {
+            break;
+        }
+    }
 
-    return fd;
+    if (len == -1) {
+        len = -errno;
+    }
+    return len;
 }
 
+static int unix_close(void *opaque)
+{
+    QEMUFileSocket *s = opaque;
+    close(s->fd);
+    g_free(s);
+    return 0;
+}
+
+static const QEMUFileOps unix_read_ops = {
+    .get_fd =     socket_get_fd,
+    .get_buffer = unix_get_buffer,
+    .close =      unix_close
+};
+
+static const QEMUFileOps unix_write_ops = {
+    .get_fd =     socket_get_fd,
+    .writev_buffer = unix_writev_buffer,
+    .close =      unix_close
+};
+
 QEMUFile *qemu_fdopen(int fd, const char *mode)
 {
-    QEMUFileStdio *s;
+    QEMUFileSocket *s;
 
     if (mode == NULL ||
 	(mode[0] != 'r' && mode[0] != 'w') ||
@@ -307,58 +482,65 @@
         return NULL;
     }
 
-    s = g_malloc0(sizeof(QEMUFileStdio));
-    s->stdio_file = fdopen(fd, mode);
-    if (!s->stdio_file)
-        goto fail;
+    s = g_malloc0(sizeof(QEMUFileSocket));
+    s->fd = fd;
 
     if(mode[0] == 'r') {
-        s->file = qemu_fopen_ops(s, NULL, stdio_get_buffer, stdio_fclose,
-				 NULL, NULL, NULL);
+        s->file = qemu_fopen_ops(s, &unix_read_ops);
     } else {
-        s->file = qemu_fopen_ops(s, stdio_put_buffer, NULL, stdio_fclose,
-				 NULL, NULL, NULL);
+        s->file = qemu_fopen_ops(s, &unix_write_ops);
     }
     return s->file;
-
-fail:
-    g_free(s);
-    return NULL;
 }
 
-QEMUFile *qemu_fopen_socket(int fd)
-{
-    QEMUFileSocket *s = g_malloc0(sizeof(QEMUFileSocket));
+static const QEMUFileOps socket_read_ops = {
+    .get_fd =     socket_get_fd,
+    .get_buffer = socket_get_buffer,
+    .close = file_socket_close
+};
 
+static const QEMUFileOps socket_write_ops = {
+    .get_fd =     socket_get_fd,
+    .writev_buffer = socket_writev_buffer,
+    .close = file_socket_close
+};
+
+bool qemu_file_mode_is_not_valid(const char *mode)
+{
+    if (mode == NULL ||
+        (mode[0] != 'r' && mode[0] != 'w') ||
+        mode[1] != 'b' || mode[2] != 0) {
+        fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
+        return true;
+    }
+
+    return false;
+}
+
+QEMUFile *qemu_fopen_socket(int fd, const char *mode)
+{
+    QEMUFileSocket *s;
+
+    if (qemu_file_mode_is_not_valid(mode)) {
+        return NULL;
+    }
+
+    s = g_malloc0(sizeof(QEMUFileSocket));
     s->fd = fd;
-    s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, file_socket_close,
-			     NULL, NULL, NULL);
+    if (mode[0] == 'w') {
+        qemu_set_block(s->fd);
+        s->file = qemu_fopen_ops(s, &socket_write_ops);
+    } else {
+        s->file = qemu_fopen_ops(s, &socket_read_ops);
+    }
     return s->file;
 }
 
-static int file_put_buffer(void *opaque, const uint8_t *buf,
-                            int64_t pos, int size)
-{
-    QEMUFileStdio *s = opaque;
-    fseek(s->stdio_file, pos, SEEK_SET);
-    return fwrite(buf, 1, size, s->stdio_file);
-}
-
-static int file_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
-{
-    QEMUFileStdio *s = opaque;
-    fseek(s->stdio_file, pos, SEEK_SET);
-    return fread(buf, 1, size, s->stdio_file);
-}
-
 QEMUFile *qemu_fopen(const char *filename, const char *mode)
 {
     QEMUFileStdio *s;
 
-    if (mode == NULL ||
-	(mode[0] != 'r' && mode[0] != 'w') ||
-	mode[1] != 'b' || mode[2] != 0) {
-        fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
+    if (qemu_file_mode_is_not_valid(mode)) {
         return NULL;
     }
 
@@ -367,13 +549,11 @@
     s->stdio_file = fopen(filename, mode);
     if (!s->stdio_file)
         goto fail;
-
+    
     if(mode[0] == 'w') {
-        s->file = qemu_fopen_ops(s, file_put_buffer, NULL, stdio_fclose,
-				 NULL, NULL, NULL);
+        s->file = qemu_fopen_ops(s, &stdio_file_write_ops);
     } else {
-        s->file = qemu_fopen_ops(s, NULL, file_get_buffer, stdio_fclose,
-			       NULL, NULL, NULL);
+        s->file = qemu_fopen_ops(s, &stdio_file_read_ops);
     }
     return s->file;
 fail:
@@ -381,6 +561,24 @@
     return NULL;
 }
 
+#ifndef CONFIG_ANDROID
+// TODO(digit): Once bdrv_writev_vmstate() is implemented.
+static ssize_t block_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
+                                   int64_t pos)
+{
+    int ret;
+    QEMUIOVector qiov;
+
+    qemu_iovec_init_external(&qiov, iov, iovcnt);
+    ret = bdrv_writev_vmstate(opaque, &qiov, pos);
+    if (ret < 0) {
+        return ret;
+    }
+
+    return qiov.size;
+}
+#endif
+
 static int block_put_buffer(void *opaque, const uint8_t *buf,
                            int64_t pos, int size)
 {
@@ -395,176 +593,380 @@
 
 static int bdrv_fclose(void *opaque)
 {
+    // TODO(digit): bdrv_flush() should return error code.
+    bdrv_flush(opaque);
     return 0;
 }
 
+static const QEMUFileOps bdrv_read_ops = {
+    .get_buffer = block_get_buffer,
+    .close =      bdrv_fclose
+};
+
+static const QEMUFileOps bdrv_write_ops = {
+    .put_buffer     = block_put_buffer,
+    //.writev_buffer  = block_writev_buffer,
+    .close          = bdrv_fclose
+};
+
 static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
 {
     if (is_writable)
-        return qemu_fopen_ops(bs, block_put_buffer, NULL, bdrv_fclose,
-			      NULL, NULL, NULL);
-    return qemu_fopen_ops(bs, NULL, block_get_buffer, bdrv_fclose, NULL, NULL, NULL);
+        return qemu_fopen_ops(bs, &bdrv_write_ops);
+    return qemu_fopen_ops(bs, &bdrv_read_ops);
 }
 
-QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
-                         QEMUFileGetBufferFunc *get_buffer,
-                         QEMUFileCloseFunc *close,
-                         QEMUFileRateLimit *rate_limit,
-                         QEMUFileSetRateLimit *set_rate_limit,
-                         QEMUFileGetRateLimit *get_rate_limit)
+QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops)
 {
     QEMUFile *f;
 
     f = g_malloc0(sizeof(QEMUFile));
 
     f->opaque = opaque;
-    f->put_buffer = put_buffer;
-    f->get_buffer = get_buffer;
-    f->close = close;
-    f->rate_limit = rate_limit;
-    f->set_rate_limit = set_rate_limit;
-    f->get_rate_limit = get_rate_limit;
-    f->is_write = 0;
-
+    f->ops = ops;
     return f;
 }
 
-int qemu_file_has_error(QEMUFile *f)
+/*
+ * Get last error for stream f
+ *
+ * Return negative error value if there has been an error on previous
+ * operations, return 0 if no error happened.
+ *
+ */
+int qemu_file_get_error(QEMUFile *f)
 {
-    return f->has_error;
+    return f->last_error;
 }
 
-void qemu_file_set_error(QEMUFile *f)
+void qemu_file_set_error(QEMUFile *f, int ret)
 {
-    f->has_error = 1;
-}
-
-void qemu_fflush(QEMUFile *f)
-{
-    if (!f->put_buffer)
-        return;
-
-    if (f->is_write && f->buf_index > 0) {
-        int len;
-
-        len = f->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index);
-        if (len > 0)
-            f->buf_offset += f->buf_index;
-        else
-            f->has_error = 1;
-        f->buf_index = 0;
+    if (f->last_error == 0) {
+        f->last_error = ret;
     }
 }
 
+static inline bool qemu_file_is_writable(QEMUFile *f)
+{
+    return f->ops->writev_buffer || f->ops->put_buffer;
+}
+
+/**
+ * Flushes QEMUFile buffer
+ *
+ * If there is writev_buffer QEMUFileOps it uses it otherwise uses
+ * put_buffer ops.
+ */
+void qemu_fflush(QEMUFile *f)
+{
+    ssize_t ret = 0;
+
+    if (!qemu_file_is_writable(f)) {
+        return;
+    }
+
+    if (f->ops->writev_buffer) {
+        if (f->iovcnt > 0) {
+            ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos);
+        }
+    } else {
+        if (f->buf_index > 0) {
+            ret = f->ops->put_buffer(f->opaque, f->buf, f->pos, f->buf_index);
+        }
+    }
+    if (ret >= 0) {
+        f->pos += ret;
+    }
+    f->buf_index = 0;
+    f->iovcnt = 0;
+    if (ret < 0) {
+        qemu_file_set_error(f, ret);
+    }
+}
+
+#ifndef CONFIG_ANDROID
+// TODO(digit).
+void ram_control_before_iterate(QEMUFile *f, uint64_t flags)
+{
+    int ret = 0;
+
+    if (f->ops->before_ram_iterate) {
+        ret = f->ops->before_ram_iterate(f, f->opaque, flags);
+        if (ret < 0) {
+            qemu_file_set_error(f, ret);
+        }
+    }
+}
+
+void ram_control_after_iterate(QEMUFile *f, uint64_t flags)
+{
+    int ret = 0;
+
+    if (f->ops->after_ram_iterate) {
+        ret = f->ops->after_ram_iterate(f, f->opaque, flags);
+        if (ret < 0) {
+            qemu_file_set_error(f, ret);
+        }
+    }
+}
+
+void ram_control_load_hook(QEMUFile *f, uint64_t flags)
+{
+    int ret = -EINVAL;
+
+    if (f->ops->hook_ram_load) {
+        ret = f->ops->hook_ram_load(f, f->opaque, flags);
+        if (ret < 0) {
+            qemu_file_set_error(f, ret);
+        }
+    } else {
+        qemu_file_set_error(f, ret);
+    }
+}
+
+size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
+                         ram_addr_t offset, size_t size, int *bytes_sent)
+{
+    if (f->ops->save_page) {
+        int ret = f->ops->save_page(f, f->opaque, block_offset,
+                                    offset, size, bytes_sent);
+
+        if (ret != RAM_SAVE_CONTROL_DELAYED) {
+            if (bytes_sent && *bytes_sent > 0) {
+                qemu_update_position(f, *bytes_sent);
+            } else if (ret < 0) {
+                qemu_file_set_error(f, ret);
+            }
+        }
+
+        return ret;
+    }
+
+    return RAM_SAVE_CONTROL_NOT_SUPP;
+}
+#endif  // !CONFIG_ANDROID
+
 static void qemu_fill_buffer(QEMUFile *f)
 {
     int len;
+    int pending;
 
-    if (!f->get_buffer)
-        return;
+    assert(!qemu_file_is_writable(f));
 
-    if (f->is_write)
-        abort();
+    pending = f->buf_size - f->buf_index;
+    if (pending > 0) {
+        memmove(f->buf, f->buf + f->buf_index, pending);
+    }
+    f->buf_index = 0;
+    f->buf_size = pending;
 
-    len = f->get_buffer(f->opaque, f->buf, f->buf_offset, IO_BUF_SIZE);
+    len = f->ops->get_buffer(f->opaque, f->buf + pending, f->pos,
+                        IO_BUF_SIZE - pending);
     if (len > 0) {
-        f->buf_index = 0;
-        f->buf_size = len;
-        f->buf_offset += len;
+        f->buf_size += len;
+        f->pos += len;
+    } else if (len == 0) {
+        qemu_file_set_error(f, -EIO);
     } else if (len != -EAGAIN)
-        f->has_error = 1;
+        qemu_file_set_error(f, len);
 }
 
+int qemu_get_fd(QEMUFile *f)
+{
+    if (f->ops->get_fd) {
+        return f->ops->get_fd(f->opaque);
+    }
+    return -1;
+}
+
+void qemu_update_position(QEMUFile *f, size_t size)
+{
+    f->pos += size;
+}
+
+/** Closes the file
+ *
+ * Returns negative error value if any error happened on previous operations or
+ * while closing the file. Returns 0 or positive number on success.
+ *
+ * The meaning of return value on success depends on the specific backend
+ * being used.
+ */
 int qemu_fclose(QEMUFile *f)
 {
-    int ret = 0;
+    int ret;
     qemu_fflush(f);
-    if (f->close)
-        ret = f->close(f->opaque);
+    ret = qemu_file_get_error(f);
+
+    if (f->ops->close) {
+        int ret2 = f->ops->close(f->opaque);
+        if (ret >= 0) {
+            ret = ret2;
+        }
+    }
+    /* If any error was spotted before closing, we should report it
+     * instead of the close() return value.
+     */
+    if (f->last_error) {
+        ret = f->last_error;
+    }
     g_free(f);
     return ret;
 }
 
-void qemu_file_put_notify(QEMUFile *f)
+static void add_to_iovec(QEMUFile *f, const uint8_t *buf, int size)
 {
-    f->put_buffer(f->opaque, NULL, 0, 0);
+    /* check for adjacent buffer and coalesce them */
+    if (f->iovcnt > 0 && buf == f->iov[f->iovcnt - 1].iov_base +
+        f->iov[f->iovcnt - 1].iov_len) {
+        f->iov[f->iovcnt - 1].iov_len += size;
+    } else {
+        f->iov[f->iovcnt].iov_base = (uint8_t *)buf;
+        f->iov[f->iovcnt++].iov_len = size;
+    }
+
+    if (f->iovcnt >= MAX_IOV_SIZE) {
+        qemu_fflush(f);
+    }
+}
+
+void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size)
+{
+    if (!f->ops->writev_buffer) {
+        qemu_put_buffer(f, buf, size);
+        return;
+    }
+
+    if (f->last_error) {
+        return;
+    }
+
+    f->bytes_xfer += size;
+    add_to_iovec(f, buf, size);
 }
 
 void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
 {
     int l;
 
-    if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {
-        fprintf(stderr,
-                "Attempted to write to buffer while read buffer is not empty\n");
-        abort();
+    if (f->last_error) {
+        return;
     }
 
-    while (!f->has_error && size > 0) {
+    while (size > 0) {
         l = IO_BUF_SIZE - f->buf_index;
         if (l > size)
             l = size;
         memcpy(f->buf + f->buf_index, buf, l);
-        f->is_write = 1;
+        f->bytes_xfer += l;
+        if (f->ops->writev_buffer) {
+            add_to_iovec(f, f->buf + f->buf_index, l);
+        }
         f->buf_index += l;
+        if (f->buf_index == IO_BUF_SIZE) {
+            qemu_fflush(f);
+        }
+        if (qemu_file_get_error(f)) {
+            break;
+        }
         buf += l;
         size -= l;
-        if (f->buf_index >= IO_BUF_SIZE)
-            qemu_fflush(f);
     }
 }
 
 void qemu_put_byte(QEMUFile *f, int v)
 {
-    if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {
-        fprintf(stderr,
-                "Attempted to write to buffer while read buffer is not empty\n");
-        abort();
+    if (f->last_error) {
+        return;
     }
 
-    f->buf[f->buf_index++] = v;
-    f->is_write = 1;
-    if (f->buf_index >= IO_BUF_SIZE)
+    f->buf[f->buf_index] = v;
+    f->bytes_xfer++;
+    if (f->ops->writev_buffer) {
+        add_to_iovec(f, f->buf + f->buf_index, 1);
+    }
+    f->buf_index++;
+    if (f->buf_index == IO_BUF_SIZE) {
         qemu_fflush(f);
+    }
 }
 
-int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
+static void qemu_file_skip(QEMUFile *f, int size)
 {
-    int size, l;
-
-    if (f->is_write)
-        abort();
-
-    size = size1;
-    while (size > 0) {
-        l = f->buf_size - f->buf_index;
-        if (l == 0) {
-            qemu_fill_buffer(f);
-            l = f->buf_size - f->buf_index;
-            if (l == 0)
-                break;
-        }
-        if (l > size)
-            l = size;
-        memcpy(buf, f->buf + f->buf_index, l);
-        f->buf_index += l;
-        buf += l;
-        size -= l;
+    if (f->buf_index + size <= f->buf_size) {
+        f->buf_index += size;
     }
-    return size1 - size;
+}
+
+static int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset)
+{
+    int pending;
+    int index;
+
+    assert(!qemu_file_is_writable(f));
+
+    index = f->buf_index + offset;
+    pending = f->buf_size - index;
+    if (pending < size) {
+        qemu_fill_buffer(f);
+        index = f->buf_index + offset;
+        pending = f->buf_size - index;
+    }
+
+    if (pending <= 0) {
+        return 0;
+    }
+    if (size > pending) {
+        size = pending;
+    }
+
+    memcpy(buf, f->buf + index, size);
+    return size;
+}
+
+int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
+{
+    int pending = size;
+    int done = 0;
+
+    while (pending > 0) {
+        int res;
+
+        res = qemu_peek_buffer(f, buf, pending, 0);
+        if (res == 0) {
+            return done;
+        }
+        qemu_file_skip(f, res);
+        buf += res;
+        pending -= res;
+        done += res;
+    }
+    return done;
+}
+
+static int qemu_peek_byte(QEMUFile *f, int offset)
+{
+    int index = f->buf_index + offset;
+
+    assert(!qemu_file_is_writable(f));
+
+    if (index >= f->buf_size) {
+        qemu_fill_buffer(f);
+        index = f->buf_index + offset;
+        if (index >= f->buf_size) {
+            return 0;
+        }
+    }
+    return f->buf[index];
 }
 
 int qemu_get_byte(QEMUFile *f)
 {
-    if (f->is_write)
-        abort();
+    int result;
 
-    if (f->buf_index >= f->buf_size) {
-        qemu_fill_buffer(f);
-        if (f->buf_index >= f->buf_size)
-            return 0;
-    }
-    return f->buf[f->buf_index++];
+    result = qemu_peek_byte(f, 0);
+    qemu_file_skip(f, 1);
+    return result;
 }
 
 #ifdef CONFIG_ANDROID
@@ -600,54 +1002,34 @@
 
 int64_t qemu_ftell(QEMUFile *f)
 {
-    return f->buf_offset - f->buf_size + f->buf_index;
-}
-
-int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
-{
-    if (whence == SEEK_SET) {
-        /* nothing to do */
-    } else if (whence == SEEK_CUR) {
-        pos += qemu_ftell(f);
-    } else {
-        /* SEEK_END not supported */
-        return -1;
-    }
-    if (f->put_buffer) {
-        qemu_fflush(f);
-        f->buf_offset = pos;
-    } else {
-        f->buf_offset = pos;
-        f->buf_index = 0;
-        f->buf_size = 0;
-    }
-    return pos;
+    qemu_fflush(f);
+    return f->pos;
 }
 
 int qemu_file_rate_limit(QEMUFile *f)
 {
-    if (f->rate_limit)
-        return f->rate_limit(f->opaque);
-
+    if (qemu_file_get_error(f)) {
+        return 1;
+    }
+    if (f->xfer_limit > 0 && f->bytes_xfer > f->xfer_limit) {
+        return 1;
+    }
     return 0;
 }
 
 int64_t qemu_file_get_rate_limit(QEMUFile *f)
 {
-    if (f->get_rate_limit)
-        return f->get_rate_limit(f->opaque);
-
-    return 0;
+    return f->xfer_limit;
 }
 
-int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate)
+void qemu_file_set_rate_limit(QEMUFile *f, int64_t limit)
 {
-    /* any failed or completed migration keeps its state to allow probing of
-     * migration data, but has no associated file anymore */
-    if (f && f->set_rate_limit)
-        return f->set_rate_limit(f->opaque, new_rate);
+    f->xfer_limit = limit;
+}
 
-    return 0;
+void qemu_file_reset_rate_limit(QEMUFile *f)
+{
+    f->bytes_xfer = 0;
 }
 
 void qemu_put_be16(QEMUFile *f, unsigned int v)
@@ -925,10 +1307,7 @@
         se->save_live_state(f, QEMU_VM_SECTION_START, se->opaque);
     }
 
-    if (qemu_file_has_error(f))
-        return -EIO;
-
-    return 0;
+    return qemu_file_get_error(f);
 }
 
 int qemu_savevm_state_iterate(QEMUFile *f)
@@ -950,10 +1329,7 @@
     if (ret)
         return 1;
 
-    if (qemu_file_has_error(f))
-        return -EIO;
-
-    return 0;
+    return qemu_file_get_error(f);
 }
 
 int qemu_savevm_state_complete(QEMUFile *f)
@@ -994,10 +1370,7 @@
 
     qemu_put_byte(f, QEMU_VM_EOF);
 
-    if (qemu_file_has_error(f))
-        return -EIO;
-
-    return 0;
+    return qemu_file_get_error(f);
 }
 
 int qemu_savevm_state(QEMUFile *f)
@@ -1023,8 +1396,7 @@
     ret = qemu_savevm_state_complete(f);
 
 out:
-    if (qemu_file_has_error(f))
-        ret = -EIO;
+    ret = qemu_file_get_error(f);
 
     if (!ret && saved_vm_running)
         vm_start();
@@ -1083,13 +1455,10 @@
             }
         }
         /* always seek to exact end of record */
-        qemu_fseek(f, cur_pos + record_len, SEEK_SET);
+        qemu_file_skip(f, cur_pos + record_len - qemu_ftell(f));
     }
 
-    if (qemu_file_has_error(f))
-        return -EIO;
-
-    return 0;
+    return qemu_file_get_error(f);
 }
 
 int qemu_loadvm_state(QEMUFile *f)
@@ -1192,8 +1561,8 @@
         g_free(le);
     }
 
-    if (qemu_file_has_error(f))
-        ret = -EIO;
+    if (qemu_file_get_error(f))
+      ret = qemu_file_get_error(f);
 
     return ret;
 }
diff --git a/scripts/ordereddict.py b/scripts/ordereddict.py
new file mode 100644
index 0000000..7242b50
--- /dev/null
+++ b/scripts/ordereddict.py
@@ -0,0 +1,127 @@
+# Copyright (c) 2009 Raymond Hettinger
+#
+# 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.
+
+from UserDict import DictMixin
+
+class OrderedDict(dict, DictMixin):
+
+    def __init__(self, *args, **kwds):
+        if len(args) > 1:
+            raise TypeError('expected at most 1 arguments, got %d' % len(args))
+        try:
+            self.__end
+        except AttributeError:
+            self.clear()
+        self.update(*args, **kwds)
+
+    def clear(self):
+        self.__end = end = []
+        end += [None, end, end]         # sentinel node for doubly linked list
+        self.__map = {}                 # key --> [key, prev, next]
+        dict.clear(self)
+
+    def __setitem__(self, key, value):
+        if key not in self:
+            end = self.__end
+            curr = end[1]
+            curr[2] = end[1] = self.__map[key] = [key, curr, end]
+        dict.__setitem__(self, key, value)
+
+    def __delitem__(self, key):
+        dict.__delitem__(self, key)
+        key, prev, next = self.__map.pop(key)
+        prev[2] = next
+        next[1] = prev
+
+    def __iter__(self):
+        end = self.__end
+        curr = end[2]
+        while curr is not end:
+            yield curr[0]
+            curr = curr[2]
+
+    def __reversed__(self):
+        end = self.__end
+        curr = end[1]
+        while curr is not end:
+            yield curr[0]
+            curr = curr[1]
+
+    def popitem(self, last=True):
+        if not self:
+            raise KeyError('dictionary is empty')
+        if last:
+            key = reversed(self).next()
+        else:
+            key = iter(self).next()
+        value = self.pop(key)
+        return key, value
+
+    def __reduce__(self):
+        items = [[k, self[k]] for k in self]
+        tmp = self.__map, self.__end
+        del self.__map, self.__end
+        inst_dict = vars(self).copy()
+        self.__map, self.__end = tmp
+        if inst_dict:
+            return (self.__class__, (items,), inst_dict)
+        return self.__class__, (items,)
+
+    def keys(self):
+        return list(self)
+
+    setdefault = DictMixin.setdefault
+    update = DictMixin.update
+    pop = DictMixin.pop
+    values = DictMixin.values
+    items = DictMixin.items
+    iterkeys = DictMixin.iterkeys
+    itervalues = DictMixin.itervalues
+    iteritems = DictMixin.iteritems
+
+    def __repr__(self):
+        if not self:
+            return '%s()' % (self.__class__.__name__,)
+        return '%s(%r)' % (self.__class__.__name__, self.items())
+
+    def copy(self):
+        return self.__class__(self)
+
+    @classmethod
+    def fromkeys(cls, iterable, value=None):
+        d = cls()
+        for key in iterable:
+            d[key] = value
+        return d
+
+    def __eq__(self, other):
+        if isinstance(other, OrderedDict):
+            if len(self) != len(other):
+                return False
+            for p, q in  zip(self.items(), other.items()):
+                if p != q:
+                    return False
+            return True
+        return dict.__eq__(self, other)
+
+    def __ne__(self, other):
+        return not self == other
diff --git a/scripts/ordereddict.pyc b/scripts/ordereddict.pyc
new file mode 100644
index 0000000..07a8129
--- /dev/null
+++ b/scripts/ordereddict.pyc
Binary files differ
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
new file mode 100644
index 0000000..b12b696
--- /dev/null
+++ b/scripts/qapi-commands.py
@@ -0,0 +1,483 @@
+#
+# QAPI command marshaller generator
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori <aliguori@us.ibm.com>
+#  Michael Roth    <mdroth@linux.vnet.ibm.com>
+#
+# This work is licensed under the terms of the GNU GPLv2.
+# See the COPYING.LIB file in the top-level directory.
+
+from ordereddict import OrderedDict
+from qapi import *
+import sys
+import os
+import getopt
+import errno
+
+def type_visitor(name):
+    if type(name) == list:
+        return 'visit_type_%sList' % name[0]
+    else:
+        return 'visit_type_%s' % name
+
+def generate_decl_enum(name, members, genlist=True):
+    return mcgen('''
+
+void %(visitor)s(Visitor *m, %(name)s * obj, const char *name, Error **errp);
+''',
+                 visitor=type_visitor(name))
+
+def generate_command_decl(name, args, ret_type):
+    arglist=""
+    for argname, argtype, optional, structured in parse_args(args):
+        argtype = c_type(argtype)
+        if argtype == "char *":
+            argtype = "const char *"
+        if optional:
+            arglist += "bool has_%s, " % c_var(argname)
+        arglist += "%s %s, " % (argtype, c_var(argname))
+    return mcgen('''
+%(ret_type)s qmp_%(name)s(%(args)sError **errp);
+''',
+                 ret_type=c_type(ret_type), name=c_fun(name), args=arglist).strip()
+
+def gen_sync_call(name, args, ret_type, indent=0):
+    ret = ""
+    arglist=""
+    retval=""
+    if ret_type:
+        retval = "retval = "
+    for argname, argtype, optional, structured in parse_args(args):
+        if optional:
+            arglist += "has_%s, " % c_var(argname)
+        arglist += "%s, " % (c_var(argname))
+    push_indent(indent)
+    ret = mcgen('''
+%(retval)sqmp_%(name)s(%(args)serrp);
+
+''',
+                name=c_fun(name), args=arglist, retval=retval).rstrip()
+    if ret_type:
+        ret += "\n" + mcgen(''''
+if (!error_is_set(errp)) {
+    %(marshal_output_call)s
+}
+''',
+                            marshal_output_call=gen_marshal_output_call(name, ret_type)).rstrip()
+    pop_indent(indent)
+    return ret.rstrip()
+
+
+def gen_marshal_output_call(name, ret_type):
+    if not ret_type:
+        return ""
+    return "qmp_marshal_output_%s(retval, ret, errp);" % c_fun(name)
+
+def gen_visitor_output_containers_decl(ret_type):
+    ret = ""
+    push_indent()
+    if ret_type:
+        ret += mcgen('''
+QmpOutputVisitor *mo;
+QapiDeallocVisitor *md;
+Visitor *v;
+''')
+    pop_indent()
+
+    return ret
+
+def gen_visitor_input_containers_decl(args):
+    ret = ""
+
+    push_indent()
+    if len(args) > 0:
+        ret += mcgen('''
+QmpInputVisitor *mi;
+QapiDeallocVisitor *md;
+Visitor *v;
+''')
+    pop_indent()
+
+    return ret.rstrip()
+
+def gen_visitor_input_vars_decl(args):
+    ret = ""
+    push_indent()
+    for argname, argtype, optional, structured in parse_args(args):
+        if optional:
+            ret += mcgen('''
+bool has_%(argname)s = false;
+''',
+                         argname=c_var(argname))
+        if c_type(argtype).endswith("*"):
+            ret += mcgen('''
+%(argtype)s %(argname)s = NULL;
+''',
+                         argname=c_var(argname), argtype=c_type(argtype))
+        else:
+            ret += mcgen('''
+%(argtype)s %(argname)s;
+''',
+                         argname=c_var(argname), argtype=c_type(argtype))
+
+    pop_indent()
+    return ret.rstrip()
+
+def gen_visitor_input_block(args, obj, dealloc=False):
+    ret = ""
+    errparg = 'errp'
+
+    if len(args) == 0:
+        return ret
+
+    push_indent()
+
+    if dealloc:
+        errparg = 'NULL'
+        ret += mcgen('''
+md = qapi_dealloc_visitor_new();
+v = qapi_dealloc_get_visitor(md);
+''')
+    else:
+        ret += mcgen('''
+mi = qmp_input_visitor_new_strict(%(obj)s);
+v = qmp_input_get_visitor(mi);
+''',
+                     obj=obj)
+
+    for argname, argtype, optional, structured in parse_args(args):
+        if optional:
+            ret += mcgen('''
+visit_start_optional(v, &has_%(c_name)s, "%(name)s", %(errp)s);
+if (has_%(c_name)s) {
+''',
+                         c_name=c_var(argname), name=argname, errp=errparg)
+            push_indent()
+        ret += mcgen('''
+%(visitor)s(v, &%(c_name)s, "%(name)s", %(errp)s);
+''',
+                     c_name=c_var(argname), name=argname, argtype=argtype,
+                     visitor=type_visitor(argtype), errp=errparg)
+        if optional:
+            pop_indent()
+            ret += mcgen('''
+}
+visit_end_optional(v, %(errp)s);
+''', errp=errparg)
+
+    if dealloc:
+        ret += mcgen('''
+qapi_dealloc_visitor_cleanup(md);
+''')
+    else:
+        ret += mcgen('''
+qmp_input_visitor_cleanup(mi);
+''')
+    pop_indent()
+    return ret.rstrip()
+
+def gen_marshal_output(name, args, ret_type, middle_mode):
+    if not ret_type:
+        return ""
+
+    ret = mcgen('''
+static void qmp_marshal_output_%(c_name)s(%(c_ret_type)s ret_in, QObject **ret_out, Error **errp)
+{
+    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
+    QmpOutputVisitor *mo = qmp_output_visitor_new();
+    Visitor *v;
+
+    v = qmp_output_get_visitor(mo);
+    %(visitor)s(v, &ret_in, "unused", errp);
+    if (!error_is_set(errp)) {
+        *ret_out = qmp_output_get_qobject(mo);
+    }
+    qmp_output_visitor_cleanup(mo);
+    v = qapi_dealloc_get_visitor(md);
+    %(visitor)s(v, &ret_in, "unused", NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+''',
+                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_fun(name)
+    else:
+        return 'static void qmp_marshal_input_%s(QDict *args, QObject **ret, Error **errp)' % c_fun(name)
+
+
+
+def gen_marshal_input(name, args, ret_type, middle_mode):
+    hdr = gen_marshal_input_decl(name, args, ret_type, middle_mode)
+
+    ret = mcgen('''
+%(header)s
+{
+''',
+                header=hdr)
+
+    if middle_mode:
+        ret += mcgen('''
+    Error *local_err = NULL;
+    Error **errp = &local_err;
+    QDict *args = (QDict *)qdict;
+''')
+
+    if ret_type:
+        if c_type(ret_type).endswith("*"):
+            retval = "    %s retval = NULL;" % c_type(ret_type)
+        else:
+            retval = "    %s retval;" % c_type(ret_type)
+        ret += mcgen('''
+%(retval)s
+''',
+                     retval=retval)
+
+    if len(args) > 0:
+        ret += mcgen('''
+%(visitor_input_containers_decl)s
+%(visitor_input_vars_decl)s
+
+%(visitor_input_block)s
+
+''',
+                     visitor_input_containers_decl=gen_visitor_input_containers_decl(args),
+                     visitor_input_vars_decl=gen_visitor_input_vars_decl(args),
+                     visitor_input_block=gen_visitor_input_block(args, "QOBJECT(args)"))
+    else:
+        ret += mcgen('''
+    (void)args;
+''')
+
+    ret += mcgen('''
+    if (error_is_set(errp)) {
+        goto out;
+    }
+%(sync_call)s
+''',
+                 sync_call=gen_sync_call(name, args, ret_type, indent=4))
+    ret += mcgen('''
+
+out:
+''')
+    ret += mcgen('''
+%(visitor_input_block_cleanup)s
+''',
+                 visitor_input_block_cleanup=gen_visitor_input_block(args, None,
+                                                                     dealloc=True))
+
+    if middle_mode:
+        ret += mcgen('''
+
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+''')
+    else:
+        ret += mcgen('''
+    return;
+''')
+
+    ret += mcgen('''
+}
+''')
+
+    return ret
+
+def option_value_matches(opt, val, cmd):
+    if opt in cmd and cmd[opt] == val:
+        return True
+    return False
+
+def gen_registry(commands):
+    registry=""
+    push_indent()
+    for cmd in commands:
+        options = 'QCO_NO_OPTIONS'
+        if option_value_matches('success-response', 'no', cmd):
+            options = 'QCO_NO_SUCCESS_RESP'
+
+        registry += mcgen('''
+qmp_register_command("%(name)s", qmp_marshal_input_%(c_name)s, %(opts)s);
+''',
+                     name=cmd['command'], c_name=c_fun(cmd['command']),
+                     opts=options)
+    pop_indent()
+    ret = mcgen('''
+static void qmp_init_marshal(void)
+{
+%(registry)s
+}
+
+qapi_init(qmp_init_marshal);
+''',
+                registry=registry.rstrip())
+    return ret
+
+def gen_command_decl_prologue(header, guard, prefix=""):
+    ret = mcgen('''
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QAPI function prototypes
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef %(guard)s
+#define %(guard)s
+
+#include "%(prefix)sqapi-types.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/error.h"
+
+''',
+                 header=basename(header), guard=guardname(header), prefix=prefix)
+    return ret
+
+def gen_command_def_prologue(prefix="", proxy=False):
+    ret = mcgen('''
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QMP->QAPI command dispatch
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "qemu/module.h"
+#include "qapi/qmp/qerror.h"
+#include "qapi/qmp/types.h"
+#include "qapi/qmp/dispatch.h"
+#include "qapi/visitor.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/dealloc-visitor.h"
+#include "%(prefix)sqapi-types.h"
+#include "%(prefix)sqapi-visit.h"
+
+''',
+                prefix=prefix)
+    if not proxy:
+        ret += '#include "%sqmp-commands.h"' % prefix
+    return ret + "\n\n"
+
+
+try:
+    opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:m",
+                                   ["source", "header", "prefix=",
+                                    "output-dir=", "type=", "middle"])
+except getopt.GetoptError, err:
+    print str(err)
+    sys.exit(1)
+
+output_dir = ""
+prefix = ""
+dispatch_type = "sync"
+c_file = 'qmp-marshal.c'
+h_file = 'qmp-commands.h'
+middle_mode = False
+
+do_c = False
+do_h = False
+
+for o, a in opts:
+    if o in ("-p", "--prefix"):
+        prefix = a
+    elif o in ("-o", "--output-dir"):
+        output_dir = a + "/"
+    elif o in ("-t", "--type"):
+        dispatch_type = a
+    elif o in ("-m", "--middle"):
+        middle_mode = True
+    elif o in ("-c", "--source"):
+        do_c = True
+    elif o in ("-h", "--header"):
+        do_h = True
+
+if not do_c and not do_h:
+    do_c = True
+    do_h = True
+
+c_file = output_dir + prefix + c_file
+h_file = output_dir + prefix + h_file
+
+def maybe_open(really, name, opt):
+    if really:
+        return open(name, opt)
+    else:
+        import StringIO
+        return StringIO.StringIO()
+
+try:
+    os.makedirs(output_dir)
+except os.error, e:
+    if e.errno != errno.EEXIST:
+        raise
+
+exprs = parse_schema(sys.stdin)
+commands = filter(lambda expr: expr.has_key('command'), exprs)
+commands = filter(lambda expr: not expr.has_key('gen'), commands)
+
+if dispatch_type == "sync":
+    fdecl = maybe_open(do_h, h_file, 'w')
+    fdef = maybe_open(do_c, c_file, 'w')
+    ret = gen_command_decl_prologue(header=basename(h_file), guard=guardname(h_file), prefix=prefix)
+    fdecl.write(ret)
+    ret = gen_command_def_prologue(prefix=prefix)
+    fdef.write(ret)
+
+    for cmd in commands:
+        arglist = []
+        ret_type = None
+        if cmd.has_key('data'):
+            arglist = cmd['data']
+        if cmd.has_key('returns'):
+            ret_type = cmd['returns']
+        ret = generate_command_decl(cmd['command'], arglist, ret_type) + "\n"
+        fdecl.write(ret)
+        if ret_type:
+            ret = gen_marshal_output(cmd['command'], arglist, ret_type, middle_mode) + "\n"
+            fdef.write(ret)
+
+        if middle_mode:
+            fdecl.write('%s;\n' % gen_marshal_input_decl(cmd['command'], arglist, ret_type, middle_mode))
+
+        ret = gen_marshal_input(cmd['command'], arglist, ret_type, middle_mode) + "\n"
+        fdef.write(ret)
+
+    fdecl.write("\n#endif\n");
+
+    if not middle_mode:
+        ret = gen_registry(commands)
+        fdef.write(ret)
+
+    fdef.flush()
+    fdef.close()
+    fdecl.flush()
+    fdecl.close()
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
new file mode 100644
index 0000000..4a1652b
--- /dev/null
+++ b/scripts/qapi-types.py
@@ -0,0 +1,455 @@
+#
+# QAPI types generator
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori <aliguori@us.ibm.com>
+#
+# This work is licensed under the terms of the GNU GPLv2.
+# See the COPYING.LIB file in the top-level directory.
+
+from ordereddict import OrderedDict
+from qapi import *
+import sys
+import os
+import getopt
+import errno
+
+def generate_fwd_struct(name, members, builtin_type=False):
+    if builtin_type:
+        return mcgen('''
+
+typedef struct %(name)sList
+{
+    union {
+        %(type)s value;
+        uint64_t padding;
+    };
+    struct %(name)sList *next;
+} %(name)sList;
+''',
+                     type=c_type(name),
+                     name=name)
+
+    return mcgen('''
+
+typedef struct %(name)s %(name)s;
+
+typedef struct %(name)sList
+{
+    union {
+        %(name)s *value;
+        uint64_t padding;
+    };
+    struct %(name)sList *next;
+} %(name)sList;
+''',
+                 name=name)
+
+def generate_fwd_enum_struct(name, members):
+    return mcgen('''
+typedef struct %(name)sList
+{
+    union {
+        %(name)s value;
+        uint64_t padding;
+    };
+    struct %(name)sList *next;
+} %(name)sList;
+''',
+                 name=name)
+
+def generate_struct_fields(members):
+    ret = ''
+
+    for argname, argentry, optional, structured in parse_args(members):
+        if optional:
+            ret += mcgen('''
+    bool has_%(c_name)s;
+''',
+                         c_name=c_var(argname))
+        if structured:
+            push_indent()
+            ret += generate_struct({ "field": argname, "data": argentry})
+            pop_indent()
+        else:
+            ret += mcgen('''
+    %(c_type)s %(c_name)s;
+''',
+                     c_type=c_type(argentry), c_name=c_var(argname))
+
+    return ret
+
+def generate_struct(expr):
+
+    structname = expr.get('type', "")
+    fieldname = expr.get('field', "")
+    members = expr['data']
+    base = expr.get('base')
+
+    ret = mcgen('''
+struct %(name)s
+{
+''',
+          name=structname)
+
+    if base:
+        ret += generate_struct_fields({'base': base})
+
+    ret += generate_struct_fields(members)
+
+    if len(fieldname):
+        fieldname = " " + fieldname
+    ret += mcgen('''
+}%(field)s;
+''',
+            field=fieldname)
+
+    return ret
+
+def generate_enum_lookup(name, values):
+    ret = mcgen('''
+const char *%(name)s_lookup[] = {
+''',
+                         name=name)
+    i = 0
+    for value in values:
+        ret += mcgen('''
+    "%(value)s",
+''',
+                     value=value)
+
+    ret += mcgen('''
+    NULL,
+};
+
+''')
+    return ret
+
+def generate_enum_name(name):
+    if name.isupper():
+        return c_fun(name, False)
+    new_name = ''
+    for c in c_fun(name, False):
+        if c.isupper():
+            new_name += '_'
+        new_name += c
+    return new_name.lstrip('_').upper()
+
+def generate_enum(name, values):
+    lookup_decl = mcgen('''
+extern const char *%(name)s_lookup[];
+''',
+                name=name)
+
+    enum_decl = mcgen('''
+typedef enum %(name)s
+{
+''',
+                name=name)
+
+    # append automatically generated _MAX value
+    enum_values = values + [ 'MAX' ]
+
+    i = 0
+    for value in enum_values:
+        enum_decl += mcgen('''
+    %(abbrev)s_%(value)s = %(i)d,
+''',
+                     abbrev=de_camel_case(name).upper(),
+                     value=generate_enum_name(value),
+                     i=i)
+        i += 1
+
+    enum_decl += mcgen('''
+} %(name)s;
+''',
+                 name=name)
+
+    return lookup_decl + enum_decl
+
+def generate_anon_union_qtypes(expr):
+
+    name = expr['union']
+    members = expr['data']
+
+    ret = mcgen('''
+const int %(name)s_qtypes[QTYPE_MAX] = {
+''',
+    name=name)
+
+    for key in members:
+        qapi_type = members[key]
+        if builtin_type_qtypes.has_key(qapi_type):
+            qtype = builtin_type_qtypes[qapi_type]
+        elif find_struct(qapi_type):
+            qtype = "QTYPE_QDICT"
+        elif find_union(qapi_type):
+            qtype = "QTYPE_QDICT"
+        else:
+            assert False, "Invalid anonymous union member"
+
+        ret += mcgen('''
+    [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
+''',
+        qtype = qtype,
+        abbrev = de_camel_case(name).upper(),
+        enum = c_fun(de_camel_case(key),False).upper())
+
+    ret += mcgen('''
+};
+''')
+    return ret
+
+
+def generate_union(expr):
+
+    name = expr['union']
+    typeinfo = expr['data']
+
+    base = expr.get('base')
+    discriminator = expr.get('discriminator')
+
+    ret = mcgen('''
+struct %(name)s
+{
+    %(name)sKind kind;
+    union {
+        void *data;
+''',
+                name=name)
+
+    for key in typeinfo:
+        ret += mcgen('''
+        %(c_type)s %(c_name)s;
+''',
+                     c_type=c_type(typeinfo[key]),
+                     c_name=c_fun(key))
+
+    ret += mcgen('''
+    };
+''')
+
+    if base:
+        base_fields = find_struct(base)['data']
+        if discriminator:
+            base_fields = base_fields.copy()
+            del base_fields[discriminator]
+        ret += generate_struct_fields(base_fields)
+    else:
+        assert not discriminator
+
+    ret += mcgen('''
+};
+''')
+    if discriminator == {}:
+        ret += mcgen('''
+extern const int %(name)s_qtypes[];
+''',
+            name=name)
+
+
+    return ret
+
+def generate_type_cleanup_decl(name):
+    ret = mcgen('''
+void qapi_free_%(type)s(%(c_type)s obj);
+''',
+                c_type=c_type(name),type=name)
+    return ret
+
+def generate_type_cleanup(name):
+    ret = mcgen('''
+
+void qapi_free_%(type)s(%(c_type)s obj)
+{
+    QapiDeallocVisitor *md;
+    Visitor *v;
+
+    if (!obj) {
+        return;
+    }
+
+    md = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(md);
+    visit_type_%(type)s(v, &obj, NULL, NULL);
+    qapi_dealloc_visitor_cleanup(md);
+}
+''',
+                c_type=c_type(name),type=name)
+    return ret
+
+
+try:
+    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
+                                   ["source", "header", "builtins",
+                                    "prefix=", "output-dir="])
+except getopt.GetoptError, err:
+    print str(err)
+    sys.exit(1)
+
+output_dir = ""
+prefix = ""
+c_file = 'qapi-types.c'
+h_file = 'qapi-types.h'
+
+do_c = False
+do_h = False
+do_builtins = False
+
+for o, a in opts:
+    if o in ("-p", "--prefix"):
+        prefix = a
+    elif o in ("-o", "--output-dir"):
+        output_dir = a + "/"
+    elif o in ("-c", "--source"):
+        do_c = True
+    elif o in ("-h", "--header"):
+        do_h = True
+    elif o in ("-b", "--builtins"):
+        do_builtins = True
+
+if not do_c and not do_h:
+    do_c = True
+    do_h = True
+
+c_file = output_dir + prefix + c_file
+h_file = output_dir + prefix + h_file
+
+try:
+    os.makedirs(output_dir)
+except os.error, e:
+    if e.errno != errno.EEXIST:
+        raise
+
+def maybe_open(really, name, opt):
+    if really:
+        return open(name, opt)
+    else:
+        import StringIO
+        return StringIO.StringIO()
+
+fdef = maybe_open(do_c, c_file, 'w')
+fdecl = maybe_open(do_h, h_file, 'w')
+
+fdef.write(mcgen('''
+/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * deallocation functions for schema-defined QAPI types
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *  Michael Roth      <mdroth@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qapi/dealloc-visitor.h"
+#include "%(prefix)sqapi-types.h"
+#include "%(prefix)sqapi-visit.h"
+
+''',             prefix=prefix))
+
+fdecl.write(mcgen('''
+/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QAPI types
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef %(guard)s
+#define %(guard)s
+
+#include <stdbool.h>
+#include <stdint.h>
+
+''',
+                  guard=guardname(h_file)))
+
+exprs = parse_schema(sys.stdin)
+exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
+
+fdecl.write(guardstart("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
+for typename in builtin_types:
+    fdecl.write(generate_fwd_struct(typename, None, builtin_type=True))
+fdecl.write(guardend("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
+
+for expr in exprs:
+    ret = "\n"
+    if expr.has_key('type'):
+        ret += generate_fwd_struct(expr['type'], expr['data'])
+    elif expr.has_key('enum'):
+        ret += generate_enum(expr['enum'], expr['data']) + "\n"
+        ret += generate_fwd_enum_struct(expr['enum'], expr['data'])
+        fdef.write(generate_enum_lookup(expr['enum'], expr['data']))
+    elif expr.has_key('union'):
+        ret += generate_fwd_struct(expr['union'], expr['data']) + "\n"
+        ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
+        fdef.write(generate_enum_lookup('%sKind' % expr['union'], expr['data'].keys()))
+        if expr.get('discriminator') == {}:
+            fdef.write(generate_anon_union_qtypes(expr))
+    else:
+        continue
+    fdecl.write(ret)
+
+# to avoid header dependency hell, we always generate declarations
+# for built-in types in our header files and simply guard them
+fdecl.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))
+for typename in builtin_types:
+    fdecl.write(generate_type_cleanup_decl(typename + "List"))
+fdecl.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))
+
+# ...this doesn't work for cases where we link in multiple objects that
+# have the functions defined, so we use -b option to provide control
+# over these cases
+if do_builtins:
+    fdef.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))
+    for typename in builtin_types:
+        fdef.write(generate_type_cleanup(typename + "List"))
+    fdef.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))
+
+for expr in exprs:
+    ret = "\n"
+    if expr.has_key('type'):
+        ret += generate_struct(expr) + "\n"
+        ret += generate_type_cleanup_decl(expr['type'] + "List")
+        fdef.write(generate_type_cleanup(expr['type'] + "List") + "\n")
+        ret += generate_type_cleanup_decl(expr['type'])
+        fdef.write(generate_type_cleanup(expr['type']) + "\n")
+    elif expr.has_key('union'):
+        ret += generate_union(expr)
+        ret += generate_type_cleanup_decl(expr['union'] + "List")
+        fdef.write(generate_type_cleanup(expr['union'] + "List") + "\n")
+        ret += generate_type_cleanup_decl(expr['union'])
+        fdef.write(generate_type_cleanup(expr['union']) + "\n")
+    elif expr.has_key('enum'):
+        ret += generate_type_cleanup_decl(expr['enum'] + "List")
+        fdef.write(generate_type_cleanup(expr['enum'] + "List") + "\n")
+    else:
+        continue
+    fdecl.write(ret)
+
+fdecl.write('''
+#endif
+''')
+
+fdecl.flush()
+fdecl.close()
+
+fdef.flush()
+fdef.close()
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
new file mode 100644
index 0000000..65f1a54
--- /dev/null
+++ b/scripts/qapi-visit.py
@@ -0,0 +1,535 @@
+#
+# QAPI visitor generator
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori <aliguori@us.ibm.com>
+#  Michael Roth    <mdroth@linux.vnet.ibm.com>
+#
+# This work is licensed under the terms of the GNU GPLv2.
+# See the COPYING.LIB file in the top-level directory.
+
+from ordereddict import OrderedDict
+from qapi import *
+import sys
+import os
+import getopt
+import errno
+
+def generate_visit_struct_fields(name, field_prefix, fn_prefix, members, base = None):
+    substructs = []
+    ret = ''
+    if not fn_prefix:
+        full_name = name
+    else:
+        full_name = "%s_%s" % (name, fn_prefix)
+
+    for argname, argentry, optional, structured in parse_args(members):
+        if structured:
+            if not fn_prefix:
+                nested_fn_prefix = argname
+            else:
+                nested_fn_prefix = "%s_%s" % (fn_prefix, argname)
+
+            nested_field_prefix = "%s%s." % (field_prefix, argname)
+            ret += generate_visit_struct_fields(name, nested_field_prefix,
+                                                nested_fn_prefix, argentry)
+
+    ret += mcgen('''
+
+static void visit_type_%(full_name)s_fields(Visitor *m, %(name)s ** obj, Error **errp)
+{
+    Error *err = NULL;
+''',
+        name=name, full_name=full_name)
+    push_indent()
+
+    if base:
+        ret += mcgen('''
+visit_start_implicit_struct(m, obj ? (void**) &(*obj)->%(c_name)s : NULL, sizeof(%(type)s), &err);
+if (!err) {
+    visit_type_%(type)s_fields(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, &err);
+    error_propagate(errp, err);
+    err = NULL;
+    visit_end_implicit_struct(m, &err);
+}
+''',
+                     c_prefix=c_var(field_prefix),
+                     type=type_name(base), c_name=c_var('base'))
+
+    for argname, argentry, optional, structured in parse_args(members):
+        if optional:
+            ret += mcgen('''
+visit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", &err);
+if (obj && (*obj)->%(prefix)shas_%(c_name)s) {
+''',
+                         c_prefix=c_var(field_prefix), prefix=field_prefix,
+                         c_name=c_var(argname), name=argname)
+            push_indent()
+
+        if structured:
+            ret += generate_visit_struct_body(full_name, argname, argentry)
+        else:
+            ret += mcgen('''
+visit_type_%(type)s(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, "%(name)s", &err);
+''',
+                         c_prefix=c_var(field_prefix), prefix=field_prefix,
+                         type=type_name(argentry), c_name=c_var(argname),
+                         name=argname)
+
+        if optional:
+            pop_indent()
+            ret += mcgen('''
+}
+visit_end_optional(m, &err);
+''')
+
+    pop_indent()
+    ret += mcgen('''
+
+    error_propagate(errp, err);
+}
+''')
+    return ret
+
+
+def generate_visit_struct_body(field_prefix, name, members):
+    ret = mcgen('''
+if (!error_is_set(errp)) {
+''')
+    push_indent()
+
+    if not field_prefix:
+        full_name = name
+    else:
+        full_name = "%s_%s" % (field_prefix, name)
+
+    if len(field_prefix):
+        ret += mcgen('''
+Error **errp = &err; /* from outer scope */
+Error *err = NULL;
+visit_start_struct(m, NULL, "", "%(name)s", 0, &err);
+''',
+                name=name)
+    else:
+        ret += mcgen('''
+Error *err = NULL;
+visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
+''',
+                name=name)
+
+    ret += mcgen('''
+if (!err) {
+    if (!obj || *obj) {
+        visit_type_%(name)s_fields(m, obj, &err);
+        error_propagate(errp, err);
+        err = NULL;
+    }
+''',
+        name=full_name)
+
+    pop_indent()
+    ret += mcgen('''
+        /* Always call end_struct if start_struct succeeded.  */
+        visit_end_struct(m, &err);
+    }
+    error_propagate(errp, err);
+}
+''')
+    return ret
+
+def generate_visit_struct(expr):
+
+    name = expr['type']
+    members = expr['data']
+    base = expr.get('base')
+
+    ret = generate_visit_struct_fields(name, "", "", members, base)
+
+    ret += mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
+{
+''',
+                name=name)
+
+    push_indent()
+    ret += generate_visit_struct_body("", name, members)
+    pop_indent()
+
+    ret += mcgen('''
+}
+''')
+    return ret
+
+def generate_visit_list(name, members):
+    return mcgen('''
+
+void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp)
+{
+    GenericList *i, **prev = (GenericList **)obj;
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_list(m, name, &err);
+        if (!err) {
+            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
+                %(name)sList *native_i = (%(name)sList *)i;
+                visit_type_%(name)s(m, &native_i->value, NULL, &err);
+            }
+            error_propagate(errp, err);
+            err = NULL;
+
+            /* Always call end_list if start_list succeeded.  */
+            visit_end_list(m, &err);
+        }
+        error_propagate(errp, err);
+    }
+}
+''',
+                name=name)
+
+def generate_visit_enum(name, members):
+    return mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp)
+{
+    visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp);
+}
+''',
+                 name=name)
+
+def generate_visit_anon_union(name, members):
+    ret = mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
+{
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_implicit_struct(m, (void**) obj, sizeof(%(name)s), &err);
+        visit_get_next_type(m, (int*) &(*obj)->kind, %(name)s_qtypes, name, &err);
+        switch ((*obj)->kind) {
+''',
+    name=name)
+
+    for key in members:
+        assert (members[key] in builtin_types
+            or find_struct(members[key])
+            or find_union(members[key])), "Invalid anonymous union member"
+
+        ret += mcgen('''
+        case %(abbrev)s_KIND_%(enum)s:
+            visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, name, &err);
+            break;
+''',
+                abbrev = de_camel_case(name).upper(),
+                enum = c_fun(de_camel_case(key),False).upper(),
+                c_type = type_name(members[key]),
+                c_name = c_fun(key))
+
+    ret += mcgen('''
+        default:
+            abort();
+        }
+        error_propagate(errp, err);
+        err = NULL;
+        visit_end_implicit_struct(m, &err);
+    }
+}
+''')
+
+    return ret
+
+
+def generate_visit_union(expr):
+
+    name = expr['union']
+    members = expr['data']
+
+    base = expr.get('base')
+    discriminator = expr.get('discriminator')
+
+    if discriminator == {}:
+        assert not base
+        return generate_visit_anon_union(name, members)
+
+    ret = generate_visit_enum('%sKind' % name, members.keys())
+
+    if base:
+        base_fields = find_struct(base)['data']
+        if discriminator:
+            base_fields = base_fields.copy()
+            del base_fields[discriminator]
+        ret += generate_visit_struct_fields(name, "", "", base_fields)
+
+    ret += mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
+{
+    Error *err = NULL;
+
+    if (!error_is_set(errp)) {
+        visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
+        if (!err) {
+            if (obj && *obj) {
+''',
+                 name=name)
+
+
+    push_indent()
+    push_indent()
+    push_indent()
+
+    if base:
+        ret += mcgen('''
+    visit_type_%(name)s_fields(m, obj, &err);
+''',
+            name=name)
+
+    pop_indent()
+
+    if not discriminator:
+        desc_type = "type"
+    else:
+        desc_type = discriminator
+    ret += mcgen('''
+        visit_type_%(name)sKind(m, &(*obj)->kind, "%(type)s", &err);
+        if (!err) {
+            switch ((*obj)->kind) {
+''',
+                 name=name, type=desc_type)
+
+    for key in members:
+        if not discriminator:
+            fmt = 'visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "data", &err);'
+        else:
+            fmt = '''visit_start_implicit_struct(m, (void**) &(*obj)->%(c_name)s, sizeof(%(c_type)s), &err);
+                if (!err) {
+                    visit_type_%(c_type)s_fields(m, &(*obj)->%(c_name)s, &err);
+                    error_propagate(errp, err);
+                    err = NULL;
+                    visit_end_implicit_struct(m, &err);
+                }'''
+
+        ret += mcgen('''
+            case %(abbrev)s_KIND_%(enum)s:
+                ''' + fmt + '''
+                break;
+''',
+                abbrev = de_camel_case(name).upper(),
+                enum = c_fun(de_camel_case(key),False).upper(),
+                c_type=type_name(members[key]),
+                c_name=c_fun(key))
+
+    ret += mcgen('''
+            default:
+                abort();
+            }
+        }
+        error_propagate(errp, err);
+        err = NULL;
+    }
+''')
+    pop_indent()
+    ret += mcgen('''
+        /* Always call end_struct if start_struct succeeded.  */
+        visit_end_struct(m, &err);
+    }
+    error_propagate(errp, err);
+}
+''')
+
+    pop_indent();
+    ret += mcgen('''
+}
+''')
+
+    return ret
+
+def generate_declaration(name, members, genlist=True, builtin_type=False):
+    ret = ""
+    if not builtin_type:
+        ret += mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp);
+''',
+                    name=name)
+
+    if genlist:
+        ret += mcgen('''
+void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp);
+''',
+                 name=name)
+
+    return ret
+
+def generate_enum_declaration(name, members, genlist=True):
+    ret = ""
+    if genlist:
+        ret += mcgen('''
+void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp);
+''',
+                     name=name)
+
+    return ret
+
+def generate_decl_enum(name, members, genlist=True):
+    return mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp);
+''',
+                name=name)
+
+try:
+    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
+                                   ["source", "header", "builtins", "prefix=",
+                                    "output-dir="])
+except getopt.GetoptError, err:
+    print str(err)
+    sys.exit(1)
+
+output_dir = ""
+prefix = ""
+c_file = 'qapi-visit.c'
+h_file = 'qapi-visit.h'
+
+do_c = False
+do_h = False
+do_builtins = False
+
+for o, a in opts:
+    if o in ("-p", "--prefix"):
+        prefix = a
+    elif o in ("-o", "--output-dir"):
+        output_dir = a + "/"
+    elif o in ("-c", "--source"):
+        do_c = True
+    elif o in ("-h", "--header"):
+        do_h = True
+    elif o in ("-b", "--builtins"):
+        do_builtins = True
+
+if not do_c and not do_h:
+    do_c = True
+    do_h = True
+
+c_file = output_dir + prefix + c_file
+h_file = output_dir + prefix + h_file
+
+try:
+    os.makedirs(output_dir)
+except os.error, e:
+    if e.errno != errno.EEXIST:
+        raise
+
+def maybe_open(really, name, opt):
+    if really:
+        return open(name, opt)
+    else:
+        import StringIO
+        return StringIO.StringIO()
+
+fdef = maybe_open(do_c, c_file, 'w')
+fdecl = maybe_open(do_h, h_file, 'w')
+
+fdef.write(mcgen('''
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QAPI visitor functions
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "%(header)s"
+''',
+                 header=basename(h_file)))
+
+fdecl.write(mcgen('''
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QAPI visitor function
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef %(guard)s
+#define %(guard)s
+
+#include "qapi/visitor.h"
+#include "%(prefix)sqapi-types.h"
+
+''',
+                  prefix=prefix, guard=guardname(h_file)))
+
+exprs = parse_schema(sys.stdin)
+
+# to avoid header dependency hell, we always generate declarations
+# for built-in types in our header files and simply guard them
+fdecl.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
+for typename in builtin_types:
+    fdecl.write(generate_declaration(typename, None, genlist=True,
+                                     builtin_type=True))
+fdecl.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
+
+# ...this doesn't work for cases where we link in multiple objects that
+# have the functions defined, so we use -b option to provide control
+# over these cases
+if do_builtins:
+    fdef.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
+    for typename in builtin_types:
+        fdef.write(generate_visit_list(typename, None))
+    fdef.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
+
+for expr in exprs:
+    if expr.has_key('type'):
+        ret = generate_visit_struct(expr)
+        ret += generate_visit_list(expr['type'], expr['data'])
+        fdef.write(ret)
+
+        ret = generate_declaration(expr['type'], expr['data'])
+        fdecl.write(ret)
+    elif expr.has_key('union'):
+        ret = generate_visit_union(expr)
+        ret += generate_visit_list(expr['union'], expr['data'])
+        fdef.write(ret)
+
+        ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys())
+        ret += generate_declaration(expr['union'], expr['data'])
+        fdecl.write(ret)
+    elif expr.has_key('enum'):
+        ret = generate_visit_list(expr['enum'], expr['data'])
+        ret += generate_visit_enum(expr['enum'], expr['data'])
+        fdef.write(ret)
+
+        ret = generate_decl_enum(expr['enum'], expr['data'])
+        ret += generate_enum_declaration(expr['enum'], expr['data'])
+        fdecl.write(ret)
+
+fdecl.write('''
+#endif
+''')
+
+fdecl.flush()
+fdecl.close()
+
+fdef.flush()
+fdef.close()
diff --git a/scripts/qapi.py b/scripts/qapi.py
new file mode 100644
index 0000000..750e9fb
--- /dev/null
+++ b/scripts/qapi.py
@@ -0,0 +1,375 @@
+#
+# QAPI helper library
+#
+# Copyright IBM, Corp. 2011
+# Copyright (c) 2013 Red Hat Inc.
+#
+# Authors:
+#  Anthony Liguori <aliguori@us.ibm.com>
+#  Markus Armbruster <armbru@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPLv2.
+# See the COPYING.LIB file in the top-level directory.
+
+from ordereddict import OrderedDict
+import sys
+
+builtin_types = [
+    'str', 'int', 'number', 'bool',
+    'int8', 'int16', 'int32', 'int64',
+    'uint8', 'uint16', 'uint32', 'uint64'
+]
+
+builtin_type_qtypes = {
+    'str':      'QTYPE_QSTRING',
+    'int':      'QTYPE_QINT',
+    'number':   'QTYPE_QFLOAT',
+    'bool':     'QTYPE_QBOOL',
+    'int8':     'QTYPE_QINT',
+    'int16':    'QTYPE_QINT',
+    'int32':    'QTYPE_QINT',
+    'int64':    'QTYPE_QINT',
+    'uint8':    'QTYPE_QINT',
+    'uint16':   'QTYPE_QINT',
+    'uint32':   'QTYPE_QINT',
+    'uint64':   'QTYPE_QINT',
+}
+
+class QAPISchemaError(Exception):
+    def __init__(self, schema, msg):
+        self.fp = schema.fp
+        self.msg = msg
+        self.line = self.col = 1
+        for ch in schema.src[0:schema.pos]:
+            if ch == '\n':
+                self.line += 1
+                self.col = 1
+            elif ch == '\t':
+                self.col = (self.col + 7) % 8 + 1
+            else:
+                self.col += 1
+
+    def __str__(self):
+        return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col, self.msg)
+
+class QAPISchema:
+
+    def __init__(self, fp):
+        self.fp = fp
+        self.src = fp.read()
+        if self.src == '' or self.src[-1] != '\n':
+            self.src += '\n'
+        self.cursor = 0
+        self.exprs = []
+        self.accept()
+
+        while self.tok != None:
+            self.exprs.append(self.get_expr(False))
+
+    def accept(self):
+        while True:
+            self.tok = self.src[self.cursor]
+            self.pos = self.cursor
+            self.cursor += 1
+            self.val = None
+
+            if self.tok == '#':
+                self.cursor = self.src.find('\n', self.cursor)
+            elif self.tok in ['{', '}', ':', ',', '[', ']']:
+                return
+            elif self.tok == "'":
+                string = ''
+                esc = False
+                while True:
+                    ch = self.src[self.cursor]
+                    self.cursor += 1
+                    if ch == '\n':
+                        raise QAPISchemaError(self,
+                                              'Missing terminating "\'"')
+                    if esc:
+                        string += ch
+                        esc = False
+                    elif ch == "\\":
+                        esc = True
+                    elif ch == "'":
+                        self.val = string
+                        return
+                    else:
+                        string += ch
+            elif self.tok == '\n':
+                if self.cursor == len(self.src):
+                    self.tok = None
+                    return
+            elif not self.tok.isspace():
+                raise QAPISchemaError(self, 'Stray "%s"' % self.tok)
+
+    def get_members(self):
+        expr = OrderedDict()
+        if self.tok == '}':
+            self.accept()
+            return expr
+        if self.tok != "'":
+            raise QAPISchemaError(self, 'Expected string or "}"')
+        while True:
+            key = self.val
+            self.accept()
+            if self.tok != ':':
+                raise QAPISchemaError(self, 'Expected ":"')
+            self.accept()
+            expr[key] = self.get_expr(True)
+            if self.tok == '}':
+                self.accept()
+                return expr
+            if self.tok != ',':
+                raise QAPISchemaError(self, 'Expected "," or "}"')
+            self.accept()
+            if self.tok != "'":
+                raise QAPISchemaError(self, 'Expected string')
+
+    def get_values(self):
+        expr = []
+        if self.tok == ']':
+            self.accept()
+            return expr
+        if not self.tok in [ '{', '[', "'" ]:
+            raise QAPISchemaError(self, 'Expected "{", "[", "]" or string')
+        while True:
+            expr.append(self.get_expr(True))
+            if self.tok == ']':
+                self.accept()
+                return expr
+            if self.tok != ',':
+                raise QAPISchemaError(self, 'Expected "," or "]"')
+            self.accept()
+
+    def get_expr(self, nested):
+        if self.tok != '{' and not nested:
+            raise QAPISchemaError(self, 'Expected "{"')
+        if self.tok == '{':
+            self.accept()
+            expr = self.get_members()
+        elif self.tok == '[':
+            self.accept()
+            expr = self.get_values()
+        elif self.tok == "'":
+            expr = self.val
+            self.accept()
+        else:
+            raise QAPISchemaError(self, 'Expected "{", "[" or string')
+        return expr
+
+def parse_schema(fp):
+    try:
+        schema = QAPISchema(fp)
+    except QAPISchemaError, e:
+        print >>sys.stderr, e
+        exit(1)
+
+    exprs = []
+
+    for expr in schema.exprs:
+        if expr.has_key('enum'):
+            add_enum(expr['enum'])
+        elif expr.has_key('union'):
+            add_union(expr)
+            add_enum('%sKind' % expr['union'])
+        elif expr.has_key('type'):
+            add_struct(expr)
+        exprs.append(expr)
+
+    return exprs
+
+def parse_args(typeinfo):
+    if isinstance(typeinfo, basestring):
+        struct = find_struct(typeinfo)
+        assert struct != None
+        typeinfo = struct['data']
+
+    for member in typeinfo:
+        argname = member
+        argentry = typeinfo[member]
+        optional = False
+        structured = False
+        if member.startswith('*'):
+            argname = member[1:]
+            optional = True
+        if isinstance(argentry, OrderedDict):
+            structured = True
+        yield (argname, argentry, optional, structured)
+
+def de_camel_case(name):
+    new_name = ''
+    for ch in name:
+        if ch.isupper() and new_name:
+            new_name += '_'
+        if ch == '-':
+            new_name += '_'
+        else:
+            new_name += ch.lower()
+    return new_name
+
+def camel_case(name):
+    new_name = ''
+    first = True
+    for ch in name:
+        if ch in ['_', '-']:
+            first = True
+        elif first:
+            new_name += ch.upper()
+            first = False
+        else:
+            new_name += ch.lower()
+    return new_name
+
+def c_var(name, protect=True):
+    # ANSI X3J11/88-090, 3.1.1
+    c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
+                     'default', 'do', 'double', 'else', 'enum', 'extern', 'float',
+                     'for', 'goto', 'if', 'int', 'long', 'register', 'return',
+                     'short', 'signed', 'sizeof', 'static', 'struct', 'switch',
+                     'typedef', 'union', 'unsigned', 'void', 'volatile', 'while'])
+    # ISO/IEC 9899:1999, 6.4.1
+    c99_words = set(['inline', 'restrict', '_Bool', '_Complex', '_Imaginary'])
+    # ISO/IEC 9899:2011, 6.4.1
+    c11_words = set(['_Alignas', '_Alignof', '_Atomic', '_Generic', '_Noreturn',
+                     '_Static_assert', '_Thread_local'])
+    # GCC http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/C-Extensions.html
+    # excluding _.*
+    gcc_words = set(['asm', 'typeof'])
+    # C++ ISO/IEC 14882:2003 2.11
+    cpp_words = set(['bool', 'catch', 'class', 'const_cast', 'delete',
+                     'dynamic_cast', 'explicit', 'false', 'friend', 'mutable',
+                     'namespace', 'new', 'operator', 'private', 'protected',
+                     'public', 'reinterpret_cast', 'static_cast', 'template',
+                     'this', 'throw', 'true', 'try', 'typeid', 'typename',
+                     'using', 'virtual', 'wchar_t',
+                     # alternative representations
+                     'and', 'and_eq', 'bitand', 'bitor', 'compl', 'not',
+                     'not_eq', 'or', 'or_eq', 'xor', 'xor_eq'])
+    # namespace pollution:
+    polluted_words = set(['unix'])
+    if protect and (name in c89_words | c99_words | c11_words | gcc_words | cpp_words | polluted_words):
+        return "q_" + name
+    return name.replace('-', '_').lstrip("*")
+
+def c_fun(name, protect=True):
+    return c_var(name, protect).replace('.', '_')
+
+def c_list_type(name):
+    return '%sList' % name
+
+def type_name(name):
+    if type(name) == list:
+        return c_list_type(name[0])
+    return name
+
+enum_types = []
+struct_types = []
+union_types = []
+
+def add_struct(definition):
+    global struct_types
+    struct_types.append(definition)
+
+def find_struct(name):
+    global struct_types
+    for struct in struct_types:
+        if struct['type'] == name:
+            return struct
+    return None
+
+def add_union(definition):
+    global union_types
+    union_types.append(definition)
+
+def find_union(name):
+    global union_types
+    for union in union_types:
+        if union['union'] == name:
+            return union
+    return None
+
+def add_enum(name):
+    global enum_types
+    enum_types.append(name)
+
+def is_enum(name):
+    global enum_types
+    return (name in enum_types)
+
+def c_type(name):
+    if name == 'str':
+        return 'char *'
+    elif name == 'int':
+        return 'int64_t'
+    elif (name == 'int8' or name == 'int16' or name == 'int32' or
+          name == 'int64' or name == 'uint8' or name == 'uint16' or
+          name == 'uint32' or name == 'uint64'):
+        return name + '_t'
+    elif name == 'size':
+        return 'uint64_t'
+    elif name == 'bool':
+        return 'bool'
+    elif name == 'number':
+        return 'double'
+    elif type(name) == list:
+        return '%s *' % c_list_type(name[0])
+    elif is_enum(name):
+        return name
+    elif name == None or len(name) == 0:
+        return 'void'
+    elif name == name.upper():
+        return '%sEvent *' % camel_case(name)
+    else:
+        return '%s *' % name
+
+def genindent(count):
+    ret = ""
+    for i in range(count):
+        ret += " "
+    return ret
+
+indent_level = 0
+
+def push_indent(indent_amount=4):
+    global indent_level
+    indent_level += indent_amount
+
+def pop_indent(indent_amount=4):
+    global indent_level
+    indent_level -= indent_amount
+
+def cgen(code, **kwds):
+    indent = genindent(indent_level)
+    lines = code.split('\n')
+    lines = map(lambda x: indent + x, lines)
+    return '\n'.join(lines) % kwds + '\n'
+
+def mcgen(code, **kwds):
+    return cgen('\n'.join(code.split('\n')[1:-1]), **kwds)
+
+def basename(filename):
+    return filename.split("/")[-1]
+
+def guardname(filename):
+    guard = basename(filename).rsplit(".", 1)[0]
+    for substr in [".", " ", "-"]:
+        guard = guard.replace(substr, "_")
+    return guard.upper() + '_H'
+
+def guardstart(name):
+    return mcgen('''
+
+#ifndef %(name)s
+#define %(name)s
+
+''',
+                 name=guardname(name))
+
+def guardend(name):
+    return mcgen('''
+
+#endif /* %(name)s */
+
+''',
+                 name=guardname(name))
diff --git a/scripts/qapi.pyc b/scripts/qapi.pyc
new file mode 100644
index 0000000..9c6f775
--- /dev/null
+++ b/scripts/qapi.pyc
Binary files differ
diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index a3eafa5..f3726e3 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -34,28 +34,29 @@
 #else
 #include "qemu-common.h"
 #include "exec/gdbstub.h"
+#include "hw/arm/arm.h"
 #endif
 
-#define SYS_OPEN        0x01
-#define SYS_CLOSE       0x02
-#define SYS_WRITEC      0x03
-#define SYS_WRITE0      0x04
-#define SYS_WRITE       0x05
-#define SYS_READ        0x06
-#define SYS_READC       0x07
-#define SYS_ISTTY       0x09
-#define SYS_SEEK        0x0a
-#define SYS_FLEN        0x0c
-#define SYS_TMPNAM      0x0d
-#define SYS_REMOVE      0x0e
-#define SYS_RENAME      0x0f
-#define SYS_CLOCK       0x10
-#define SYS_TIME        0x11
-#define SYS_SYSTEM      0x12
-#define SYS_ERRNO       0x13
-#define SYS_GET_CMDLINE 0x15
-#define SYS_HEAPINFO    0x16
-#define SYS_EXIT        0x18
+#define TARGET_SYS_OPEN        0x01
+#define TARGET_SYS_CLOSE       0x02
+#define TARGET_SYS_WRITEC      0x03
+#define TARGET_SYS_WRITE0      0x04
+#define TARGET_SYS_WRITE       0x05
+#define TARGET_SYS_READ        0x06
+#define TARGET_SYS_READC       0x07
+#define TARGET_SYS_ISTTY       0x09
+#define TARGET_SYS_SEEK        0x0a
+#define TARGET_SYS_FLEN        0x0c
+#define TARGET_SYS_TMPNAM      0x0d
+#define TARGET_SYS_REMOVE      0x0e
+#define TARGET_SYS_RENAME      0x0f
+#define TARGET_SYS_CLOCK       0x10
+#define TARGET_SYS_TIME        0x11
+#define TARGET_SYS_SYSTEM      0x12
+#define TARGET_SYS_ERRNO       0x13
+#define TARGET_SYS_GET_CMDLINE 0x15
+#define TARGET_SYS_HEAPINFO    0x16
+#define TARGET_SYS_EXIT        0x18
 
 #ifndef O_BINARY
 #define O_BINARY 0
@@ -107,7 +108,7 @@
     return code;
 }
 #else
-static inline uint32_t set_swi_errno(CPUState *env, uint32_t code)
+static inline uint32_t set_swi_errno(CPUARMState *env, uint32_t code)
 {
     return code;
 }
@@ -121,7 +122,7 @@
 static target_ulong syscall_err;
 #endif
 
-static void arm_semi_cb(CPUState *env, target_ulong ret, target_ulong err)
+static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err)
 {
 #ifdef CONFIG_USER_ONLY
     TaskState *ts = env->opaque;
@@ -137,11 +138,11 @@
     } else {
         /* Fixup syscalls that use nonstardard return conventions.  */
         switch (env->regs[0]) {
-        case SYS_WRITE:
-        case SYS_READ:
+        case TARGET_SYS_WRITE:
+        case TARGET_SYS_READ:
             env->regs[0] = arm_semi_syscall_len - ret;
             break;
-        case SYS_SEEK:
+        case TARGET_SYS_SEEK:
             env->regs[0] = 0;
             break;
         default:
@@ -151,7 +152,7 @@
     }
 }
 
-static void arm_semi_flen_cb(CPUState *env, target_ulong ret, target_ulong err)
+static void arm_semi_flen_cb(CPUARMState *env, target_ulong ret, target_ulong err)
 {
     /* The size is always stored in big-endian order, extract
        the value. We assume the size always fit in 32 bits.  */
@@ -165,17 +166,20 @@
 #endif
 }
 
-#define ARG(n)					\
-({						\
-    target_ulong __arg;				\
-    /* FIXME - handle get_user() failure */	\
-    get_user_ual(__arg, args + (n) * 4);	\
-    __arg;					\
-})
+/* Read the input value from the argument block; fail the semihosting
+ * call if the memory read fails.
+ */
+#define GET_ARG(n) do {                                 \
+    if (get_user_ual(arg ## n, args + (n) * 4)) {       \
+        return (uint32_t)-1;                            \
+    }                                                   \
+} while (0)
+
 #define SET_ARG(n, val) put_user_ual(val, args + (n) * 4)
-uint32_t do_arm_semihosting(CPUState *env)
+uint32_t do_arm_semihosting(CPUARMState *env)
 {
     target_ulong args;
+    target_ulong arg0, arg1, arg2, arg3;
     char * s;
     int nr;
     uint32_t ret;
@@ -183,41 +187,48 @@
 #ifdef CONFIG_USER_ONLY
     TaskState *ts = env->opaque;
 #else
-    CPUState *ts = env;
+    CPUARMState *ts = env;
 #endif
 
     nr = env->regs[0];
     args = env->regs[1];
     switch (nr) {
-    case SYS_OPEN:
-        if (!(s = lock_user_string(ARG(0))))
+    case TARGET_SYS_OPEN:
+        GET_ARG(0);
+        GET_ARG(1);
+        GET_ARG(2);
+        s = lock_user_string(arg0);
+        if (!s) {
             /* FIXME - should this error code be -TARGET_EFAULT ? */
             return (uint32_t)-1;
-        if (ARG(1) >= 12)
+        }
+        if (arg1 >= 12) {
+            unlock_user(s, arg0, 0);
             return (uint32_t)-1;
+        }
         if (strcmp(s, ":tt") == 0) {
-            if (ARG(1) < 4)
-                return STDIN_FILENO;
-            else
-                return STDOUT_FILENO;
+            int result_fileno = arg1 < 4 ? STDIN_FILENO : STDOUT_FILENO;
+            unlock_user(s, arg0, 0);
+            return result_fileno;
         }
         if (use_gdb_syscalls()) {
-            gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0),
-			   (int)ARG(2)+1, gdb_open_modeflags[ARG(1)]);
-            return env->regs[0];
+            gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", arg0,
+                           (int)arg2+1, gdb_open_modeflags[arg1]);
+            ret = env->regs[0];
         } else {
-            ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644));
+            ret = set_swi_errno(ts, open(s, open_modeflags[arg1], 0644));
         }
-        unlock_user(s, ARG(0), 0);
+        unlock_user(s, arg0, 0);
         return ret;
-    case SYS_CLOSE:
+    case TARGET_SYS_CLOSE:
+        GET_ARG(0);
         if (use_gdb_syscalls()) {
-            gdb_do_syscall(arm_semi_cb, "close,%x", ARG(0));
+            gdb_do_syscall(arm_semi_cb, "close,%x", arg0);
             return env->regs[0];
         } else {
-            return set_swi_errno(ts, close(ARG(0)));
+            return set_swi_errno(ts, close(arg0));
         }
-    case SYS_WRITEC:
+    case TARGET_SYS_WRITEC:
         {
           char c;
 
@@ -232,7 +243,7 @@
                 return write(STDERR_FILENO, &c, 1);
           }
         }
-    case SYS_WRITE0:
+    case TARGET_SYS_WRITE0:
         if (!(s = lock_user_string(args)))
             /* FIXME - should this error code be -TARGET_EFAULT ? */
             return (uint32_t)-1;
@@ -245,238 +256,295 @@
         }
         unlock_user(s, args, 0);
         return ret;
-    case SYS_WRITE:
-        len = ARG(2);
+    case TARGET_SYS_WRITE:
+        GET_ARG(0);
+        GET_ARG(1);
+        GET_ARG(2);
+        len = arg2;
         if (use_gdb_syscalls()) {
             arm_semi_syscall_len = len;
-            gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", ARG(0), ARG(1), len);
+            gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", arg0, arg1, len);
             return env->regs[0];
         } else {
-            if (!(s = lock_user(VERIFY_READ, ARG(1), len, 1)))
+            s = lock_user(VERIFY_READ, arg1, len, 1);
+            if (!s) {
                 /* FIXME - should this error code be -TARGET_EFAULT ? */
                 return (uint32_t)-1;
-            ret = set_swi_errno(ts, write(ARG(0), s, len));
-            unlock_user(s, ARG(1), 0);
+            }
+            ret = set_swi_errno(ts, write(arg0, s, len));
+            unlock_user(s, arg1, 0);
             if (ret == (uint32_t)-1)
                 return -1;
             return len - ret;
         }
-    case SYS_READ:
-        len = ARG(2);
+    case TARGET_SYS_READ:
+        GET_ARG(0);
+        GET_ARG(1);
+        GET_ARG(2);
+        len = arg2;
         if (use_gdb_syscalls()) {
             arm_semi_syscall_len = len;
-            gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", ARG(0), ARG(1), len);
+            gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", arg0, arg1, len);
             return env->regs[0];
         } else {
-            if (!(s = lock_user(VERIFY_WRITE, ARG(1), len, 0)))
+            s = lock_user(VERIFY_WRITE, arg1, len, 0);
+            if (!s) {
                 /* FIXME - should this error code be -TARGET_EFAULT ? */
                 return (uint32_t)-1;
-            do
-              ret = set_swi_errno(ts, read(ARG(0), s, len));
-            while (ret == -1 && errno == EINTR);
-            unlock_user(s, ARG(1), len);
+            }
+            do {
+                ret = set_swi_errno(ts, read(arg0, s, len));
+            } while (ret == -1 && errno == EINTR);
+            unlock_user(s, arg1, len);
             if (ret == (uint32_t)-1)
                 return -1;
             return len - ret;
         }
-    case SYS_READC:
-       /* XXX: Read from debug cosole. Not implemented.  */
+    case TARGET_SYS_READC:
+       /* XXX: Read from debug console. Not implemented.  */
         return 0;
-    case SYS_ISTTY:
+    case TARGET_SYS_ISTTY:
+        GET_ARG(0);
         if (use_gdb_syscalls()) {
-            gdb_do_syscall(arm_semi_cb, "isatty,%x", ARG(0));
+            gdb_do_syscall(arm_semi_cb, "isatty,%x", arg0);
             return env->regs[0];
         } else {
-            return isatty(ARG(0));
+            return isatty(arg0);
         }
-    case SYS_SEEK:
+    case TARGET_SYS_SEEK:
+        GET_ARG(0);
+        GET_ARG(1);
         if (use_gdb_syscalls()) {
-            gdb_do_syscall(arm_semi_cb, "lseek,%x,%x,0", ARG(0), ARG(1));
+            gdb_do_syscall(arm_semi_cb, "lseek,%x,%x,0", arg0, arg1);
             return env->regs[0];
         } else {
-            ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET));
+            ret = set_swi_errno(ts, lseek(arg0, arg1, SEEK_SET));
             if (ret == (uint32_t)-1)
               return -1;
             return 0;
         }
-    case SYS_FLEN:
+    case TARGET_SYS_FLEN:
+        GET_ARG(0);
         if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_flen_cb, "fstat,%x,%x",
-			   ARG(0), env->regs[13]-64);
+                           arg0, env->regs[13]-64);
             return env->regs[0];
         } else {
             struct stat buf;
-            ret = set_swi_errno(ts, fstat(ARG(0), &buf));
+            ret = set_swi_errno(ts, fstat(arg0, &buf));
             if (ret == (uint32_t)-1)
                 return -1;
             return buf.st_size;
         }
-    case SYS_TMPNAM:
+    case TARGET_SYS_TMPNAM:
         /* XXX: Not implemented.  */
         return -1;
-    case SYS_REMOVE:
+    case TARGET_SYS_REMOVE:
+        GET_ARG(0);
+        GET_ARG(1);
         if (use_gdb_syscalls()) {
-            gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1);
+            gdb_do_syscall(arm_semi_cb, "unlink,%s", arg0, (int)arg1+1);
             ret = env->regs[0];
         } else {
-            if (!(s = lock_user_string(ARG(0))))
+            s = lock_user_string(arg0);
+            if (!s) {
                 /* FIXME - should this error code be -TARGET_EFAULT ? */
                 return (uint32_t)-1;
+            }
             ret =  set_swi_errno(ts, remove(s));
-            unlock_user(s, ARG(0), 0);
+            unlock_user(s, arg0, 0);
         }
         return ret;
-    case SYS_RENAME:
+    case TARGET_SYS_RENAME:
+        GET_ARG(0);
+        GET_ARG(1);
+        GET_ARG(2);
+        GET_ARG(3);
         if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "rename,%s,%s",
-                           ARG(0), (int)ARG(1)+1, ARG(2), (int)ARG(3)+1);
+                           arg0, (int)arg1+1, arg2, (int)arg3+1);
             return env->regs[0];
         } else {
             char *s2;
-            s = lock_user_string(ARG(0));
-            s2 = lock_user_string(ARG(2));
+            s = lock_user_string(arg0);
+            s2 = lock_user_string(arg2);
             if (!s || !s2)
                 /* FIXME - should this error code be -TARGET_EFAULT ? */
                 ret = (uint32_t)-1;
             else
                 ret = set_swi_errno(ts, rename(s, s2));
             if (s2)
-                unlock_user(s2, ARG(2), 0);
+                unlock_user(s2, arg2, 0);
             if (s)
-                unlock_user(s, ARG(0), 0);
+                unlock_user(s, arg0, 0);
             return ret;
         }
-    case SYS_CLOCK:
+    case TARGET_SYS_CLOCK:
         return clock() / (CLOCKS_PER_SEC / 100);
-    case SYS_TIME:
+    case TARGET_SYS_TIME:
         return set_swi_errno(ts, time(NULL));
-    case SYS_SYSTEM:
+    case TARGET_SYS_SYSTEM:
+        GET_ARG(0);
+        GET_ARG(1);
         if (use_gdb_syscalls()) {
-            gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1);
+            gdb_do_syscall(arm_semi_cb, "system,%s", arg0, (int)arg1+1);
             return env->regs[0];
         } else {
-            if (!(s = lock_user_string(ARG(0))))
+            s = lock_user_string(arg0);
+            if (!s) {
                 /* FIXME - should this error code be -TARGET_EFAULT ? */
                 return (uint32_t)-1;
+            }
             ret = set_swi_errno(ts, system(s));
-            unlock_user(s, ARG(0), 0);
+            unlock_user(s, arg0, 0);
             return ret;
         }
-    case SYS_ERRNO:
+    case TARGET_SYS_ERRNO:
 #ifdef CONFIG_USER_ONLY
         return ts->swi_errno;
 #else
         return syscall_err;
 #endif
-    case SYS_GET_CMDLINE:
-#ifdef CONFIG_USER_ONLY
-        /* Build a commandline from the original argv.  */
+    case TARGET_SYS_GET_CMDLINE:
         {
-            char *arm_cmdline_buffer;
-            const char *host_cmdline_buffer;
+            /* Build a command-line from the original argv.
+             *
+             * The inputs are:
+             *     * arg0, pointer to a buffer of at least the size
+             *               specified in arg1.
+             *     * arg1, size of the buffer pointed to by arg0 in
+             *               bytes.
+             *
+             * The outputs are:
+             *     * arg0, pointer to null-terminated string of the
+             *               command line.
+             *     * arg1, length of the string pointed to by arg0.
+             */
 
+            char *output_buffer;
+            size_t input_size;
+            size_t output_size;
+            int status = 0;
+            GET_ARG(0);
+            GET_ARG(1);
+            input_size = arg1;
+            /* Compute the size of the output string.  */
+#if !defined(CONFIG_USER_ONLY)
+            output_size = strlen(ts->boot_info->kernel_filename)
+                        + 1  /* Separating space.  */
+                        + strlen(ts->boot_info->kernel_cmdline)
+                        + 1; /* Terminating null byte.  */
+#else
             unsigned int i;
-            unsigned int arm_cmdline_len = ARG(1);
-            unsigned int host_cmdline_len =
-                ts->info->arg_end-ts->info->arg_start;
 
-            if (!arm_cmdline_len || host_cmdline_len > arm_cmdline_len) {
-                return -1; /* not enough space to store command line */
-            }
-
-            if (!host_cmdline_len) {
+            output_size = ts->info->arg_end - ts->info->arg_start;
+            if (!output_size) {
                 /* We special-case the "empty command line" case (argc==0).
                    Just provide the terminating 0. */
-                arm_cmdline_buffer = lock_user(VERIFY_WRITE, ARG(0), 1, 0);
-                arm_cmdline_buffer[0] = 0;
-                unlock_user(arm_cmdline_buffer, ARG(0), 1);
-
-                /* Adjust the commandline length argument. */
-                SET_ARG(1, 0);
-                return 0;
+                output_size = 1;
             }
-
-            /* lock the buffers on the ARM side */
-            arm_cmdline_buffer =
-                lock_user(VERIFY_WRITE, ARG(0), host_cmdline_len, 0);
-            host_cmdline_buffer =
-                lock_user(VERIFY_READ, ts->info->arg_start,
-                                       host_cmdline_len, 1);
-
-            if (arm_cmdline_buffer && host_cmdline_buffer)
-            {
-                /* the last argument is zero-terminated;
-                   no need for additional termination */
-                memcpy(arm_cmdline_buffer, host_cmdline_buffer,
-                       host_cmdline_len);
-
-                /* separate arguments by white spaces */
-                for (i = 0; i < host_cmdline_len-1; i++) {
-                    if (arm_cmdline_buffer[i] == 0) {
-                        arm_cmdline_buffer[i] = ' ';
-                    }
-                }
-
-                /* Adjust the commandline length argument. */
-                SET_ARG(1, host_cmdline_len-1);
-            }
-
-            /* Unlock the buffers on the ARM side.  */
-            unlock_user(arm_cmdline_buffer, ARG(0), host_cmdline_len);
-            unlock_user((void*)host_cmdline_buffer, ts->info->arg_start, 0);
-
-            /* Return success if we could return a commandline.  */
-            return (arm_cmdline_buffer && host_cmdline_buffer) ? 0 : -1;
-        }
-#else
-        return -1;
 #endif
-    case SYS_HEAPINFO:
+
+            if (output_size > input_size) {
+                 /* Not enough space to store command-line arguments.  */
+                return -1;
+            }
+
+            /* Adjust the command-line length.  */
+            if (SET_ARG(1, output_size - 1)) {
+                /* Couldn't write back to argument block */
+                return -1;
+            }
+
+            /* Lock the buffer on the ARM side.  */
+            output_buffer = lock_user(VERIFY_WRITE, arg0, output_size, 0);
+            if (!output_buffer) {
+                return -1;
+            }
+
+            /* Copy the command-line arguments.  */
+#if !defined(CONFIG_USER_ONLY)
+            pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename);
+            pstrcat(output_buffer, output_size, " ");
+            pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline);
+#else
+            if (output_size == 1) {
+                /* Empty command-line.  */
+                output_buffer[0] = '\0';
+                goto out;
+            }
+
+            if (copy_from_user(output_buffer, ts->info->arg_start,
+                               output_size)) {
+                status = -1;
+                goto out;
+            }
+
+            /* Separate arguments by white spaces.  */
+            for (i = 0; i < output_size - 1; i++) {
+                if (output_buffer[i] == 0) {
+                    output_buffer[i] = ' ';
+                }
+            }
+        out:
+#endif
+            /* Unlock the buffer on the ARM side.  */
+            unlock_user(output_buffer, arg0, output_size);
+
+            return status;
+        }
+    case TARGET_SYS_HEAPINFO:
         {
             uint32_t *ptr;
             uint32_t limit;
+            GET_ARG(0);
 
 #ifdef CONFIG_USER_ONLY
             /* Some C libraries assume the heap immediately follows .bss, so
                allocate it using sbrk.  */
             if (!ts->heap_limit) {
-                long ret;
+                abi_ulong ret;
 
                 ts->heap_base = do_brk(0);
                 limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
                 /* Try a big heap, and reduce the size if that fails.  */
                 for (;;) {
                     ret = do_brk(limit);
-                    if (ret != -1)
+                    if (ret >= limit) {
                         break;
+                    }
                     limit = (ts->heap_base >> 1) + (limit >> 1);
                 }
                 ts->heap_limit = limit;
             }
 
-            if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0)))
+            ptr = lock_user(VERIFY_WRITE, arg0, 16, 0);
+            if (!ptr) {
                 /* FIXME - should this error code be -TARGET_EFAULT ? */
                 return (uint32_t)-1;
+            }
             ptr[0] = tswap32(ts->heap_base);
             ptr[1] = tswap32(ts->heap_limit);
             ptr[2] = tswap32(ts->stack_base);
             ptr[3] = tswap32(0); /* Stack limit.  */
-            unlock_user(ptr, ARG(0), 16);
+            unlock_user(ptr, arg0, 16);
 #else
             limit = ram_size;
-            if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0)))
+            ptr = lock_user(VERIFY_WRITE, arg0, 16, 0);
+            if (!ptr) {
                 /* FIXME - should this error code be -TARGET_EFAULT ? */
                 return (uint32_t)-1;
+            }
             /* TODO: Make this use the limit of the loaded application.  */
             ptr[0] = tswap32(limit / 2);
             ptr[1] = tswap32(limit);
             ptr[2] = tswap32(limit); /* Stack base */
             ptr[3] = tswap32(0); /* Stack limit.  */
-            unlock_user(ptr, ARG(0), 16);
+            unlock_user(ptr, arg0, 16);
 #endif
             return 0;
         }
-    case SYS_EXIT:
+    case TARGET_SYS_EXIT:
         //gdb_exit(env, 0);
         exit(0);
     default:
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 1941c9e..35b802c 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -19,13 +19,24 @@
 #ifndef CPU_ARM_H
 #define CPU_ARM_H
 
-#define TARGET_LONG_BITS 32
-
-#define ELF_MACHINE	EM_ARM
-
-#define CPUState struct CPUARMState
-
 #include "config.h"
+
+#include "kvm-consts.h"
+
+#if defined(TARGET_AARCH64)
+  /* AArch64 definitions */
+#  define TARGET_LONG_BITS 64
+#  define ELF_MACHINE EM_AARCH64
+#else
+#  define TARGET_LONG_BITS 32
+#  define ELF_MACHINE EM_ARM
+#endif
+
+// TODO(digit): Remove this line.
+#define CPUOldState struct CPUARMState
+
+#define CPUArchState struct CPUARMState
+
 #include "qemu-common.h"
 #include "exec/cpu-defs.h"
 
@@ -59,6 +70,9 @@
 /* ARM-specific interrupt pending bits.  */
 #define CPU_INTERRUPT_FIQ   CPU_INTERRUPT_TGT_EXT_1
 
+/* Meanings of the ARMCPU object's two inbound GPIO lines */
+#define ARM_CPU_IRQ 0
+#define ARM_CPU_FIQ 1
 
 typedef void ARMWriteCPFunc(void *opaque, int cp_info,
                             int srcreg, int operand, uint32_t value,
@@ -79,6 +93,21 @@
    s<2n+1> maps to the most significant half of d<n>
  */
 
+/* CPU state for each instance of a generic timer (in cp15 c14) */
+typedef struct ARMGenericTimer {
+    uint64_t cval; /* Timer CompareValue register */
+    uint32_t ctl; /* Timer Control register */
+} ARMGenericTimer;
+
+#define GTIMER_PHYS 0
+#define GTIMER_VIRT 1
+#define NUM_GTIMERS 2
+
+/* Scale factor for generic timers, ie number of ns per tick.
+ * This gives a 62.5MHz timer.
+ */
+#define GTIMER_SCALE 16
+
 typedef struct CPUARMState {
     /* Regs for current mode.  */
     uint32_t regs[16];
@@ -246,6 +275,24 @@
 void switch_mode(CPUARMState *, int);
 uint32_t do_arm_semihosting(CPUARMState *env);
 
+static inline bool is_a64(CPUARMState *env)
+{
+#ifdef CONFIG_ANDROID // TODO(digit)
+    return 0;
+#else
+    return env->aarch64;
+#endif
+}
+
+#define PSTATE_N_SHIFT 3
+#define PSTATE_N  (1 << PSTATE_N_SHIFT)
+#define PSTATE_Z_SHIFT 2
+#define PSTATE_Z  (1 << PSTATE_Z_SHIFT)
+#define PSTATE_C_SHIFT 1
+#define PSTATE_C  (1 << PSTATE_C_SHIFT)
+#define PSTATE_V_SHIFT 0
+#define PSTATE_V  (1 << PSTATE_V_SHIFT)
+
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -260,22 +307,22 @@
   env->cp15.c13_tls2 = newtls;
 }
 
-#define CPSR_M (0x1f)
-#define CPSR_T (1 << 5)
-#define CPSR_F (1 << 6)
-#define CPSR_I (1 << 7)
-#define CPSR_A (1 << 8)
-#define CPSR_E (1 << 9)
-#define CPSR_IT_2_7 (0xfc00)
-#define CPSR_GE (0xf << 16)
-#define CPSR_RESERVED (0xf << 20)
-#define CPSR_J (1 << 24)
-#define CPSR_IT_0_1 (3 << 25)
-#define CPSR_Q (1 << 27)
-#define CPSR_V (1 << 28)
-#define CPSR_C (1 << 29)
-#define CPSR_Z (1 << 30)
-#define CPSR_N (1 << 31)
+#define CPSR_M (0x1fU)
+#define CPSR_T (1U << 5)
+#define CPSR_F (1U << 6)
+#define CPSR_I (1U << 7)
+#define CPSR_A (1U << 8)
+#define CPSR_E (1U << 9)
+#define CPSR_IT_2_7 (0xfc00U)
+#define CPSR_GE (0xfU << 16)
+#define CPSR_RESERVED (0xfU << 20)
+#define CPSR_J (1U << 24)
+#define CPSR_IT_0_1 (3U << 25)
+#define CPSR_Q (1U << 27)
+#define CPSR_V (1U << 28)
+#define CPSR_C (1U << 29)
+#define CPSR_Z (1U << 30)
+#define CPSR_N (1U << 31)
 #define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V)
 
 #define CPSR_IT (CPSR_IT_0_1 | CPSR_IT_2_7)
@@ -362,6 +409,10 @@
 #define ARM_IWMMXT_wCGR2	10
 #define ARM_IWMMXT_wCGR3	11
 
+/* If adding a feature bit which corresponds to a Linux ELF
+ * HWCAP bit, remember to update the feature-bit-to-hwcap
+ * mapping in linux-user/elfload.c:get_elf_hwcap().
+ */
 enum arm_features {
     ARM_FEATURE_VFP,
     ARM_FEATURE_AUXCR,  /* ARM1026 Auxiliary control register.  */
@@ -388,7 +439,7 @@
 
 static inline int arm_feature(CPUARMState *env, int feature)
 {
-    return (env->features & (1u << feature)) != 0;
+    return (env->features & (1ULL << feature)) != 0;
 }
 
 void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf);
@@ -398,6 +449,287 @@
 int armv7m_nvic_acknowledge_irq(void *opaque);
 void armv7m_nvic_complete_irq(void *opaque, int irq);
 
+/* Interface for defining coprocessor registers.
+ * Registers are defined in tables of arm_cp_reginfo structs
+ * which are passed to define_arm_cp_regs().
+ */
+
+/* When looking up a coprocessor register we look for it
+ * via an integer which encodes all of:
+ *  coprocessor number
+ *  Crn, Crm, opc1, opc2 fields
+ *  32 or 64 bit register (ie is it accessed via MRC/MCR
+ *    or via MRRC/MCRR?)
+ * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
+ * (In this case crn and opc2 should be zero.)
+ */
+#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2)   \
+    (((cp) << 16) | ((is64) << 15) | ((crn) << 11) |    \
+     ((crm) << 7) | ((opc1) << 3) | (opc2))
+
+/* Convert a full 64 bit KVM register ID to the truncated 32 bit
+ * version used as a key for the coprocessor register hashtable
+ */
+static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
+{
+    uint32_t cpregid = kvmid;
+    if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
+        cpregid |= (1 << 15);
+    }
+    return cpregid;
+}
+
+/* Convert a truncated 32 bit hashtable key into the full
+ * 64 bit KVM register ID.
+ */
+static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
+{
+    uint64_t kvmid = cpregid & ~(1 << 15);
+    if (cpregid & (1 << 15)) {
+        kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
+    } else {
+        kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
+    }
+    return kvmid;
+}
+
+/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
+ * special-behaviour cp reg and bits [15..8] indicate what behaviour
+ * it has. Otherwise it is a simple cp reg, where CONST indicates that
+ * TCG can assume the value to be constant (ie load at translate time)
+ * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
+ * indicates that the TB should not be ended after a write to this register
+ * (the default is that the TB ends after cp writes). OVERRIDE permits
+ * a register definition to override a previous definition for the
+ * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
+ * old must have the OVERRIDE bit set.
+ * NO_MIGRATE indicates that this register should be ignored for migration;
+ * (eg because any state is accessed via some other coprocessor register).
+ * IO indicates that this register does I/O and therefore its accesses
+ * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
+ * registers which implement clocks or timers require this.
+ */
+#define ARM_CP_SPECIAL 1
+#define ARM_CP_CONST 2
+#define ARM_CP_64BIT 4
+#define ARM_CP_SUPPRESS_TB_END 8
+#define ARM_CP_OVERRIDE 16
+#define ARM_CP_NO_MIGRATE 32
+#define ARM_CP_IO 64
+#define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
+#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
+#define ARM_LAST_SPECIAL ARM_CP_WFI
+/* Used only as a terminator for ARMCPRegInfo lists */
+#define ARM_CP_SENTINEL 0xffff
+/* Mask of only the flag bits in a type field */
+#define ARM_CP_FLAG_MASK 0x7f
+
+/* Return true if cptype is a valid type field. This is used to try to
+ * catch errors where the sentinel has been accidentally left off the end
+ * of a list of registers.
+ */
+static inline bool cptype_valid(int cptype)
+{
+    return ((cptype & ~ARM_CP_FLAG_MASK) == 0)
+        || ((cptype & ARM_CP_SPECIAL) &&
+            ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL));
+}
+
+/* Access rights:
+ * We define bits for Read and Write access for what rev C of the v7-AR ARM ARM
+ * defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and
+ * PL2 (hyp). The other level which has Read and Write bits is Secure PL1
+ * (ie any of the privileged modes in Secure state, or Monitor mode).
+ * If a register is accessible in one privilege level it's always accessible
+ * in higher privilege levels too. Since "Secure PL1" also follows this rule
+ * (ie anything visible in PL2 is visible in S-PL1, some things are only
+ * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the
+ * terminology a little and call this PL3.
+ *
+ * If access permissions for a register are more complex than can be
+ * described with these bits, then use a laxer set of restrictions, and
+ * do the more restrictive/complex check inside a helper function.
+ */
+#define PL3_R 0x80
+#define PL3_W 0x40
+#define PL2_R (0x20 | PL3_R)
+#define PL2_W (0x10 | PL3_W)
+#define PL1_R (0x08 | PL2_R)
+#define PL1_W (0x04 | PL2_W)
+#define PL0_R (0x02 | PL1_R)
+#define PL0_W (0x01 | PL1_W)
+
+#define PL3_RW (PL3_R | PL3_W)
+#define PL2_RW (PL2_R | PL2_W)
+#define PL1_RW (PL1_R | PL1_W)
+#define PL0_RW (PL0_R | PL0_W)
+
+static inline int arm_current_pl(CPUARMState *env)
+{
+    if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
+        return 0;
+    }
+    /* We don't currently implement the Virtualization or TrustZone
+     * extensions, so PL2 and PL3 don't exist for us.
+     */
+    return 1;
+}
+
+typedef struct ARMCPRegInfo ARMCPRegInfo;
+
+/* Access functions for coprocessor registers. These should return
+ * 0 on success, or one of the EXCP_* constants if access should cause
+ * an exception (in which case *value is not written).
+ */
+typedef int CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque,
+                     uint64_t *value);
+typedef int CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
+                      uint64_t value);
+/* Hook function for register reset */
+typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
+
+#define CP_ANY 0xff
+
+/* Definition of an ARM coprocessor register */
+struct ARMCPRegInfo {
+    /* Name of register (useful mainly for debugging, need not be unique) */
+    const char *name;
+    /* Location of register: coprocessor number and (crn,crm,opc1,opc2)
+     * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a
+     * 'wildcard' field -- any value of that field in the MRC/MCR insn
+     * will be decoded to this register. The register read and write
+     * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2
+     * used by the program, so it is possible to register a wildcard and
+     * then behave differently on read/write if necessary.
+     * For 64 bit registers, only crm and opc1 are relevant; crn and opc2
+     * must both be zero.
+     */
+    uint8_t cp;
+    uint8_t crn;
+    uint8_t crm;
+    uint8_t opc1;
+    uint8_t opc2;
+    /* Register type: ARM_CP_* bits/values */
+    int type;
+    /* Access rights: PL*_[RW] */
+    int access;
+    /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
+     * this register was defined: can be used to hand data through to the
+     * register read/write functions, since they are passed the ARMCPRegInfo*.
+     */
+    void *opaque;
+    /* Value of this register, if it is ARM_CP_CONST. Otherwise, if
+     * fieldoffset is non-zero, the reset value of the register.
+     */
+    uint64_t resetvalue;
+    /* Offset of the field in CPUARMState for this register. This is not
+     * needed if either:
+     *  1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
+     *  2. both readfn and writefn are specified
+     */
+    ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
+    /* Function for handling reads of this register. If NULL, then reads
+     * will be done by loading from the offset into CPUARMState specified
+     * by fieldoffset.
+     */
+    CPReadFn *readfn;
+    /* Function for handling writes of this register. If NULL, then writes
+     * will be done by writing to the offset into CPUARMState specified
+     * by fieldoffset.
+     */
+    CPWriteFn *writefn;
+    /* Function for doing a "raw" read; used when we need to copy
+     * coprocessor state to the kernel for KVM or out for
+     * migration. This only needs to be provided if there is also a
+     * readfn and it makes an access permission check.
+     */
+    CPReadFn *raw_readfn;
+    /* Function for doing a "raw" write; used when we need to copy KVM
+     * kernel coprocessor state into userspace, or for inbound
+     * migration. This only needs to be provided if there is also a
+     * writefn and it makes an access permission check or masks out
+     * "unwritable" bits or has write-one-to-clear or similar behaviour.
+     */
+    CPWriteFn *raw_writefn;
+    /* Function for resetting the register. If NULL, then reset will be done
+     * by writing resetvalue to the field specified in fieldoffset. If
+     * fieldoffset is 0 then no reset will be done.
+     */
+    CPResetFn *resetfn;
+};
+
+/* Macros which are lvalues for the field in CPUARMState for the
+ * ARMCPRegInfo *ri.
+ */
+#define CPREG_FIELD32(env, ri) \
+    (*(uint32_t *)((char *)(env) + (ri)->fieldoffset))
+#define CPREG_FIELD64(env, ri) \
+    (*(uint64_t *)((char *)(env) + (ri)->fieldoffset))
+
+#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
+
+#ifndef CONFIG_ANDROID  // TODO(digit): Implement ARMCPU
+void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
+                                    const ARMCPRegInfo *regs, void *opaque);
+void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
+                                       const ARMCPRegInfo *regs, void *opaque);
+static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
+{
+    define_arm_cp_regs_with_opaque(cpu, regs, 0);
+}
+static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
+{
+    define_one_arm_cp_reg_with_opaque(cpu, regs, 0);
+}
+const ARMCPRegInfo *get_arm_cp_reginfo(ARMCPU *cpu, uint32_t encoded_cp);
+#endif  // !CONFIG_ANDROID
+
+/* CPWriteFn that can be used to implement writes-ignored behaviour */
+int arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
+                        uint64_t value);
+/* CPReadFn that can be used for read-as-zero behaviour */
+int arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value);
+
+static inline bool cp_access_ok(CPUARMState *env,
+                                const ARMCPRegInfo *ri, int isread)
+{
+    return (ri->access >> ((arm_current_pl(env) * 2) + isread)) & 1;
+}
+
+#ifndef CONFIG_ANDROID  // TODO(digit): Implement ARMCPU
+/**
+ * write_list_to_cpustate
+ * @cpu: ARMCPU
+ *
+ * For each register listed in the ARMCPU cpreg_indexes list, write
+ * its value from the cpreg_values list into the ARMCPUARMState structure.
+ * This updates TCG's working data structures from KVM data or
+ * from incoming migration state.
+ *
+ * Returns: true if all register values were updated correctly,
+ * false if some register was unknown or could not be written.
+ * Note that we do not stop early on failure -- we will attempt
+ * writing all registers in the list.
+ */
+bool write_list_to_cpustate(ARMCPU *cpu);
+
+/**
+ * write_cpustate_to_list:
+ * @cpu: ARMCPU
+ *
+ * For each register listed in the ARMCPU cpreg_indexes list, write
+ * its value from the ARMCPUARMState structure into the cpreg_values list.
+ * This is used to copy info from TCG's working data structures into
+ * KVM or for outbound migration.
+ *
+ * Returns: true if all register values were read correctly,
+ * false if some register was unknown or could not be read.
+ * Note that we do not stop early on failure -- we will attempt
+ * reading all registers in the list.
+ */
+bool write_cpustate_to_list(ARMCPU *cpu);
+#endif  // !CONFIG_ANDROID
+
 void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
                        ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
                        void *opaque);
@@ -446,8 +778,13 @@
 #define TARGET_PAGE_BITS 10
 #endif
 
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
+#if defined(TARGET_AARCH64)
+#  define TARGET_PHYS_ADDR_SPACE_BITS 48
+#  define TARGET_VIRT_ADDR_SPACE_BITS 64
+#else
+#  define TARGET_PHYS_ADDR_SPACE_BITS 40
+#  define TARGET_VIRT_ADDR_SPACE_BITS 32
+#endif
 
 #define cpu_init cpu_arm_init
 #define cpu_exec cpu_arm_exec
@@ -461,12 +798,12 @@
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _user
 #define MMU_USER_IDX 1
-static inline int cpu_mmu_index (CPUState *env)
+static inline int cpu_mmu_index (CPUARMState *env)
 {
     return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
 }
 
-static inline int is_cpu_user (CPUState *env)
+static inline int is_cpu_user (CPUARMState *env)
 {
 #ifdef CONFIG_USER_ONLY
     return 1;
@@ -476,7 +813,7 @@
 }
 
 #if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
 {
     if (newsp)
         env->regs[13] = newsp;
@@ -486,7 +823,13 @@
 
 #include "exec/cpu-all.h"
 
-/* Bit usage in the TB flags field: */
+/* Bit usage in the TB flags field: bit 31 indicates whether we are
+ * in 32 or 64 bit mode. The meaning of the other bits depends on that.
+ */
+#define ARM_TBFLAG_AARCH64_STATE_SHIFT 31
+#define ARM_TBFLAG_AARCH64_STATE_MASK  (1U << ARM_TBFLAG_AARCH64_STATE_SHIFT)
+
+/* Bit usage when in AArch32 state: */
 #define ARM_TBFLAG_THUMB_SHIFT      0
 #define ARM_TBFLAG_THUMB_MASK       (1 << ARM_TBFLAG_THUMB_SHIFT)
 #define ARM_TBFLAG_VECLEN_SHIFT     1
@@ -499,9 +842,14 @@
 #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)
+
+/* Bit usage when in AArch64 state: currently no bits defined */
 
 /* some convenience accessor macros */
+#define ARM_TBFLAG_AARCH64_STATE(F) \
+    (((F) & ARM_TBFLAG_AARCH64_STATE_MASK) >> ARM_TBFLAG_AARCH64_STATE_SHIFT)
 #define ARM_TBFLAG_THUMB(F) \
     (((F) & ARM_TBFLAG_THUMB_MASK) >> ARM_TBFLAG_THUMB_SHIFT)
 #define ARM_TBFLAG_VECLEN(F) \
@@ -514,28 +862,37 @@
     (((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(CPUState *env, target_ulong *pc,
+static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
-    int privmode;
-    *pc = env->regs[15];
-    *cs_base = 0;
-    *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);
-    if (arm_feature(env, ARM_FEATURE_M)) {
-        privmode = !((env->v7m.exception == 0) && (env->v7m.control & 1));
+    if (is_a64(env)) {
+        *pc = env->regs[15];
+        *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
     } else {
-        privmode = (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR;
+        int privmode;
+        *pc = env->regs[15];
+        *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->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT);
+        if (arm_feature(env, ARM_FEATURE_M)) {
+            privmode = !((env->v7m.exception == 0) && (env->v7m.control & 1));
+        } else {
+            privmode = (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR;
+        }
+        if (privmode) {
+            *flags |= ARM_TBFLAG_PRIV_MASK;
+        }
+        if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
+            *flags |= ARM_TBFLAG_VFPEN_MASK;
+        }
     }
-    if (privmode) {
-        *flags |= ARM_TBFLAG_PRIV_MASK;
-    }
-    if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
-        *flags |= ARM_TBFLAG_VFPEN_MASK;
-    }
+
+    *cs_base = 0;
 }
 
 #endif
diff --git a/target-arm/exec.h b/target-arm/exec.h
index 400d133..664ae86 100644
--- a/target-arm/exec.h
+++ b/target-arm/exec.h
@@ -32,13 +32,13 @@
 {
 }
 
-static inline int cpu_has_work(CPUState *env)
+static inline int cpu_has_work(CPUARMState *env)
 {
     return (env->interrupt_request &
             (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB));
 }
 
-static inline int cpu_halted(CPUState *env) {
+static inline int cpu_halted(CPUARMState *env) {
     if (!env->halted)
         return 0;
     /* An interrupt wakes the CPU even if the I and F CPSR bits are
@@ -56,7 +56,7 @@
 #endif
 
 void raise_exception(int);
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb)
 {
     env->regs[15] = tb->pc;
 }
diff --git a/target-arm/helper-android.c b/target-arm/helper-android.c
index f0450cf..809e8f4 100644
--- a/target-arm/helper-android.c
+++ b/target-arm/helper-android.c
@@ -23,35 +23,6 @@
     }
 }
 
-#ifdef CONFIG_TRACE
-#include "android/trace.h"
-
-void  HELPER(traceTicks)(uint32_t  ticks)
-{
-    sim_time += ticks;
-}
-
-void  HELPER(traceInsn)(void)
-{
-    trace_insn_helper();
-}
-
-#if HOST_LONG_BITS == 32
-void HELPER(traceBB32)(uint64_t  bb_num, uint32_t  tb)
-{
-    trace_bb_helper(bb_num, (void*)tb);
-}
-#endif
-
-#if HOST_LONG_BITS == 64
-void HELPER(traceBB64)(uint64_t  bb_num, uint64_t  tb)
-{
-    trace_bb_helper(bb_num, (void*)tb);
-}
-#endif
-
-#endif /* CONFIG_TRACE */
-
 #ifdef CONFIG_MEMCHECK
 #include "memcheck/memcheck_api.h"
 
diff --git a/target-arm/helper-android.h b/target-arm/helper-android.h
index 9e3f055..a13b39c 100644
--- a/target-arm/helper-android.h
+++ b/target-arm/helper-android.h
@@ -1,15 +1,4 @@
 /* This file must be included from helper.h */
-#ifdef CONFIG_TRACE
-DEF_HELPER_1(traceTicks, void, i32)
-DEF_HELPER_0(traceInsn, void)
-#if HOST_LONG_BITS == 32
-DEF_HELPER_2(traceBB32, void, i64, i32)
-#endif
-#if HOST_LONG_BITS == 64
-DEF_HELPER_2(traceBB64, void, i64, i64)
-#endif
-#endif
-
 #ifdef CONFIG_MEMCHECK
 /* Hooks to translated BL/BLX. This callback is used to build thread's
  * calling stack.
diff --git a/target-arm/helper.c b/target-arm/helper.c
index d4d7612..6cbdcd4 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -10,9 +10,6 @@
 #include "qemu/host-utils.h"
 #if !defined(CONFIG_USER_ONLY)
 //#include "hw/loader.h"
-#ifdef CONFIG_TRACE
-#include "android/trace.h"
-#endif
 #endif
 
 static uint32_t cortexa9_cp15_c0_c1[8] =
@@ -320,7 +317,7 @@
     tlb_flush(env, 1);
 }
 
-static int vfp_gdb_get_reg(CPUState *env, uint8_t *buf, int reg)
+static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
 {
     int nregs;
 
@@ -347,7 +344,7 @@
     return 0;
 }
 
-static int vfp_gdb_set_reg(CPUState *env, uint8_t *buf, int reg)
+static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
 {
     int nregs;
 
@@ -573,12 +570,12 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void do_interrupt (CPUState *env)
+void do_interrupt (CPUARMState *env)
 {
     env->exception_index = -1;
 }
 
-int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
+int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
                               int mmu_idx, int is_softmmu)
 {
     if (rw == 2) {
@@ -592,41 +589,41 @@
 }
 
 /* These should probably raise undefined insn exceptions.  */
-void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
+void HELPER(set_cp15)(CPUARMState *env, uint32_t insn, uint32_t val)
 {
     cpu_abort(env, "cp15 insn %08x\n", insn);
 }
 
-uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
+uint32_t HELPER(get_cp15)(CPUARMState *env, uint32_t insn)
 {
     cpu_abort(env, "cp15 insn %08x\n", insn);
     return 0;
 }
 
 /* These should probably raise undefined insn exceptions.  */
-void HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
+void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
 {
     cpu_abort(env, "v7m_mrs %d\n", reg);
 }
 
-uint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
+uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
 {
     cpu_abort(env, "v7m_mrs %d\n", reg);
     return 0;
 }
 
-void switch_mode(CPUState *env, int mode)
+void switch_mode(CPUARMState *env, int mode)
 {
     if (mode != ARM_CPU_MODE_USR)
         cpu_abort(env, "Tried to switch out of user mode\n");
 }
 
-void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
+void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
 {
     cpu_abort(env, "banked r13 write\n");
 }
 
-uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
+uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
 {
     cpu_abort(env, "banked r13 read\n");
     return 0;
@@ -660,7 +657,7 @@
     return -1;
 }
 
-void switch_mode(CPUState *env, int mode)
+void switch_mode(CPUARMState *env, int mode)
 {
     int old_mode;
     int i;
@@ -828,12 +825,6 @@
     int new_mode;
     uint32_t offset;
 
-#ifdef CONFIG_TRACE
-    if (tracing) {
-        trace_exception(env->regs[15]);
-    }
-#endif
-
     if (IS_M(env)) {
         do_interrupt_v7m(env);
         return;
@@ -964,7 +955,7 @@
 /* Check section/page access permissions.
    Returns the page protection flags, or zero if the access is not
    permitted.  */
-static inline int check_ap(CPUState *env, int ap, int domain, int access_type,
+static inline int check_ap(CPUARMState *env, int ap, int domain, int access_type,
                            int is_user)
 {
   int prot_ro;
@@ -1013,7 +1004,7 @@
   }
 }
 
-static uint32_t get_level1_table_address(CPUState *env, uint32_t address)
+static uint32_t get_level1_table_address(CPUARMState *env, uint32_t address)
 {
     uint32_t table;
 
@@ -1026,7 +1017,7 @@
     return table;
 }
 
-static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
+static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type,
 			    int is_user, uint32_t *phys_ptr, int *prot,
                             target_ulong *page_size)
 {
@@ -1119,7 +1110,7 @@
     return code | (domain << 4);
 }
 
-static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
+static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
 			    int is_user, uint32_t *phys_ptr, int *prot,
                             target_ulong *page_size)
 {
@@ -1222,7 +1213,7 @@
     return code | (domain << 4);
 }
 
-static int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,
+static int get_phys_addr_mpu(CPUARMState *env, uint32_t address, int access_type,
 			     int is_user, uint32_t *phys_ptr, int *prot)
 {
     int n;
@@ -1283,14 +1274,14 @@
 }
 
 #ifdef CONFIG_GLES2
-int get_phys_addr(CPUState *env, uint32_t address,
+int get_phys_addr(CPUARMState *env, uint32_t address,
                   int access_type, int is_user,
                   uint32_t *phys_ptr, int *prot,
                   target_ulong *page_size);
 #else
 static
 #endif
-int get_phys_addr(CPUState *env, uint32_t address,
+int get_phys_addr(CPUARMState *env, uint32_t address,
                                 int access_type, int is_user,
                                 uint32_t *phys_ptr, int *prot,
                                 target_ulong *page_size)
@@ -1318,7 +1309,7 @@
     }
 }
 
-int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
+int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address,
                               int access_type, int mmu_idx, int is_softmmu)
 {
     uint32_t phys_addr;
@@ -1351,7 +1342,7 @@
     return 1;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+hwaddr cpu_get_phys_page_debug(CPUARMState *env, target_ulong addr)
 {
     uint32_t phys_addr;
     target_ulong page_size;
@@ -1396,7 +1387,7 @@
     return ret;
 }
 
-void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
+void HELPER(set_cp15)(CPUARMState *env, uint32_t insn, uint32_t val)
 {
     int op1;
     int op2;
@@ -1831,7 +1822,7 @@
               (insn >> 16) & 0xf, crm, op1, op2);
 }
 
-uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
+uint32_t HELPER(get_cp15)(CPUARMState *env, uint32_t insn)
 {
     int op1;
     int op2;
@@ -2196,7 +2187,7 @@
     return 0;
 }
 
-void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
+void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
 {
     if ((env->uncached_cpsr & CPSR_M) == mode) {
         env->regs[13] = val;
@@ -2205,7 +2196,7 @@
 }
 }
 
-uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
+uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
 {
     if ((env->uncached_cpsr & CPSR_M) == mode) {
         return env->regs[13];
@@ -2214,7 +2205,7 @@
     }
 }
 
-uint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
+uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
 {
     switch (reg) {
     case 0: /* APSR */
@@ -2251,7 +2242,7 @@
     }
 }
 
-void HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
+void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
 {
     switch (reg) {
     case 0: /* APSR */
@@ -2607,7 +2598,7 @@
     return target_bits;
 }
 
-uint32_t HELPER(vfp_get_fpscr)(CPUState *env)
+uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
 {
     int i;
     uint32_t fpscr;
@@ -2621,7 +2612,7 @@
     return fpscr;
 }
 
-uint32_t vfp_get_fpscr(CPUState *env)
+uint32_t vfp_get_fpscr(CPUARMState *env)
 {
     return HELPER(vfp_get_fpscr)(env);
 }
@@ -2646,7 +2637,7 @@
     return host_bits;
 }
 
-void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val)
+void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
 {
     int i;
     uint32_t changed;
@@ -2687,7 +2678,7 @@
     set_float_exception_flags(0, &env->vfp.standard_fp_status);
 }
 
-void vfp_set_fpscr(CPUState *env, uint32_t val)
+void vfp_set_fpscr(CPUARMState *env, uint32_t val)
 {
     HELPER(vfp_set_fpscr)(env, val);
 }
@@ -2695,11 +2686,11 @@
 #define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
 
 #define VFP_BINOP(name) \
-float32 VFP_HELPER(name, s)(float32 a, float32 b, CPUState *env) \
+float32 VFP_HELPER(name, s)(float32 a, float32 b, CPUARMState *env) \
 { \
     return float32_ ## name (a, b, &env->vfp.fp_status); \
 } \
-float64 VFP_HELPER(name, d)(float64 a, float64 b, CPUState *env) \
+float64 VFP_HELPER(name, d)(float64 a, float64 b, CPUARMState *env) \
 { \
     return float64_ ## name (a, b, &env->vfp.fp_status); \
 }
@@ -2729,19 +2720,19 @@
     return float64_abs(a);
 }
 
-float32 VFP_HELPER(sqrt, s)(float32 a, CPUState *env)
+float32 VFP_HELPER(sqrt, s)(float32 a, CPUARMState *env)
 {
     return float32_sqrt(a, &env->vfp.fp_status);
 }
 
-float64 VFP_HELPER(sqrt, d)(float64 a, CPUState *env)
+float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env)
 {
     return float64_sqrt(a, &env->vfp.fp_status);
 }
 
 /* XXX: check quiet/signaling case */
 #define DO_VFP_cmp(p, type) \
-void VFP_HELPER(cmp, p)(type a, type b, CPUState *env)  \
+void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env)  \
 { \
     uint32_t flags; \
     switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
@@ -2753,7 +2744,7 @@
     env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
         | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
 } \
-void VFP_HELPER(cmpe, p)(type a, type b, CPUState *env) \
+void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
 { \
     uint32_t flags; \
     switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
@@ -2804,7 +2795,7 @@
 #undef FLOAT_CONVS
 
 /* floating point conversion */
-float64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env)
+float64 VFP_HELPER(fcvtd, s)(float32 x, CPUARMState *env)
 {
     float64 r = float32_to_float64(x, &env->vfp.fp_status);
     /* ARM requires that S<->D conversion of any kind of NaN generates
@@ -2813,7 +2804,7 @@
     return float64_maybe_silence_nan(r);
 }
 
-float32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env)
+float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
 {
     float32 r =  float64_to_float32(x, &env->vfp.fp_status);
     /* ARM requires that S<->D conversion of any kind of NaN generates
@@ -2856,7 +2847,7 @@
 #undef VFP_CONV_FIX
 
 /* Half precision conversions.  */
-static float32 do_fcvt_f16_to_f32(uint32_t a, CPUState *env, float_status *s)
+static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s)
 {
     int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
     float32 r = float16_to_float32(make_float16(a), ieee, s);
@@ -2866,7 +2857,7 @@
     return r;
 }
 
-static uint32_t do_fcvt_f32_to_f16(float32 a, CPUState *env, float_status *s)
+static uint32_t do_fcvt_f32_to_f16(float32 a, CPUARMState *env, float_status *s)
 {
     int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
     float16 r = float32_to_float16(a, ieee, s);
@@ -2876,22 +2867,22 @@
     return float16_val(r);
 }
 
-float32 HELPER(neon_fcvt_f16_to_f32)(uint32_t a, CPUState *env)
+float32 HELPER(neon_fcvt_f16_to_f32)(uint32_t a, CPUARMState *env)
 {
     return do_fcvt_f16_to_f32(a, env, &env->vfp.standard_fp_status);
 }
 
-uint32_t HELPER(neon_fcvt_f32_to_f16)(float32 a, CPUState *env)
+uint32_t HELPER(neon_fcvt_f32_to_f16)(float32 a, CPUARMState *env)
 {
     return do_fcvt_f32_to_f16(a, env, &env->vfp.standard_fp_status);
 }
 
-float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, CPUState *env)
+float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, CPUARMState *env)
 {
     return do_fcvt_f16_to_f32(a, env, &env->vfp.fp_status);
 }
 
-uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUState *env)
+uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUARMState *env)
 {
     return do_fcvt_f32_to_f16(a, env, &env->vfp.fp_status);
 }
@@ -2900,7 +2891,7 @@
 #define float32_three make_float32(0x40400000)
 #define float32_one_point_five make_float32(0x3fc00000)
 
-float32 HELPER(recps_f32)(float32 a, float32 b, CPUState *env)
+float32 HELPER(recps_f32)(float32 a, float32 b, CPUARMState *env)
 {
     float_status *s = &env->vfp.standard_fp_status;
     if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) ||
@@ -2913,7 +2904,7 @@
     return float32_sub(float32_two, float32_mul(a, b, s), s);
 }
 
-float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUState *env)
+float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env)
 {
     float_status *s = &env->vfp.standard_fp_status;
     float32 product;
@@ -2938,7 +2929,7 @@
 /* The algorithm that must be used to calculate the estimate
  * is specified by the ARM ARM.
  */
-static float64 recip_estimate(float64 a, CPUState *env)
+static float64 recip_estimate(float64 a, CPUARMState *env)
 {
     /* These calculations mustn't set any fp exception flags,
      * so we use a local copy of the fp_status.
@@ -2964,7 +2955,7 @@
     return float64_div(int64_to_float64(q_int, s), float64_256, s);
 }
 
-float32 HELPER(recpe_f32)(float32 a, CPUState *env)
+float32 HELPER(recpe_f32)(float32 a, CPUARMState *env)
 {
     float_status *s = &env->vfp.standard_fp_status;
     float64 f64;
@@ -3008,7 +2999,7 @@
 /* The algorithm that must be used to calculate the estimate
  * is specified by the ARM ARM.
  */
-static float64 recip_sqrt_estimate(float64 a, CPUState *env)
+static float64 recip_sqrt_estimate(float64 a, CPUARMState *env)
 {
     /* These calculations mustn't set any fp exception flags,
      * so we use a local copy of the fp_status.
@@ -3060,7 +3051,7 @@
     return float64_div(int64_to_float64(q_int, s), float64_256, s);
 }
 
-float32 HELPER(rsqrte_f32)(float32 a, CPUState *env)
+float32 HELPER(rsqrte_f32)(float32 a, CPUARMState *env)
 {
     float_status *s = &env->vfp.standard_fp_status;
     int result_exp;
@@ -3112,7 +3103,7 @@
     return make_float32(val);
 }
 
-uint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env)
+uint32_t HELPER(recpe_u32)(uint32_t a, CPUARMState *env)
 {
     float64 f64;
 
@@ -3128,7 +3119,7 @@
     return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff);
 }
 
-uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
+uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUARMState *env)
 {
     float64 f64;
 
@@ -3149,7 +3140,7 @@
     return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff);
 }
 
-void HELPER(set_teecr)(CPUState *env, uint32_t val)
+void HELPER(set_teecr)(CPUARMState *env, uint32_t val)
 {
     val &= 1;
     if (env->teecr != val) {
diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h
new file mode 100644
index 0000000..2bba0bd
--- /dev/null
+++ b/target-arm/kvm-consts.h
@@ -0,0 +1,64 @@
+/*
+ * KVM ARM ABI constant definitions
+ *
+ * Copyright (c) 2013 Linaro Limited
+ *
+ * Provide versions of KVM constant defines that can be used even
+ * when CONFIG_KVM is not set and we don't have access to the
+ * KVM headers. If CONFIG_KVM is set, we do a compile-time check
+ * that we haven't got out of sync somehow.
+ *
+ * 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 ARM_KVM_CONSTS_H
+#define ARM_KVM_CONSTS_H
+
+#ifdef CONFIG_KVM
+#include "qemu/compiler.h"
+#include <linux/kvm.h>
+
+#define MISMATCH_CHECK(X, Y) QEMU_BUILD_BUG_ON(X != Y)
+
+#else
+#define MISMATCH_CHECK(X, Y)
+#endif
+
+#define CP_REG_SIZE_SHIFT 52
+#define CP_REG_SIZE_MASK       0x00f0000000000000ULL
+#define CP_REG_SIZE_U32        0x0020000000000000ULL
+#define CP_REG_SIZE_U64        0x0030000000000000ULL
+#define CP_REG_ARM             0x4000000000000000ULL
+
+MISMATCH_CHECK(CP_REG_SIZE_SHIFT, KVM_REG_SIZE_SHIFT)
+MISMATCH_CHECK(CP_REG_SIZE_MASK, KVM_REG_SIZE_MASK)
+MISMATCH_CHECK(CP_REG_SIZE_U32, KVM_REG_SIZE_U32)
+MISMATCH_CHECK(CP_REG_SIZE_U64, KVM_REG_SIZE_U64)
+MISMATCH_CHECK(CP_REG_ARM, KVM_REG_ARM)
+
+#define PSCI_FN_BASE 0x95c1ba5e
+#define PSCI_FN(n) (PSCI_FN_BASE + (n))
+#define PSCI_FN_CPU_SUSPEND PSCI_FN(0)
+#define PSCI_FN_CPU_OFF PSCI_FN(1)
+#define PSCI_FN_CPU_ON PSCI_FN(2)
+#define PSCI_FN_MIGRATE PSCI_FN(3)
+
+MISMATCH_CHECK(PSCI_FN_CPU_SUSPEND, KVM_PSCI_FN_CPU_SUSPEND)
+MISMATCH_CHECK(PSCI_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF)
+MISMATCH_CHECK(PSCI_FN_CPU_ON, KVM_PSCI_FN_CPU_ON)
+MISMATCH_CHECK(PSCI_FN_MIGRATE, KVM_PSCI_FN_MIGRATE)
+
+#define QEMU_KVM_ARM_TARGET_CORTEX_A15 0
+
+/* There's no kernel define for this: sentinel value which
+ * matches no KVM target value for either 64 or 32 bit
+ */
+#define QEMU_KVM_ARM_TARGET_NONE UINT_MAX
+
+#ifndef TARGET_AARCH64
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A15, KVM_ARM_TARGET_CORTEX_A15)
+#endif
+
+#undef MISMATCH_CHECK
+
+#endif
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 1726fd5..61239c3 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -1,3 +1,4 @@
+#include "cpu.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
 
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 16608e0..2f17894 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -73,7 +73,7 @@
 void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
-    CPUState *saved_env;
+    CPUARMState *saved_env;
     unsigned long pc;
     int ret;
 
@@ -98,7 +98,7 @@
     env = saved_env;
 }
 
-void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
+void HELPER(set_cp)(CPUARMState *env, uint32_t insn, uint32_t val)
 {
     int cp_num = (insn >> 8) & 0xf;
     int cp_info = (insn >> 5) & 7;
@@ -110,7 +110,7 @@
                                  cp_info, src, operand, val, GETPC());
         }
 
-uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
+uint32_t HELPER(get_cp)(CPUARMState *env, uint32_t insn)
 {
     int cp_num = (insn >> 8) & 0xf;
     int cp_info = (insn >> 5) & 7;
@@ -125,14 +125,14 @@
 
 #else
 
-void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
+void HELPER(set_cp)(CPUARMState *env, uint32_t insn, uint32_t val)
 {
     int op1 = (insn >> 8) & 0xf;
     cpu_abort(env, "cp%i insn %08x\n", op1, insn);
     return;
 }
 
-uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
+uint32_t HELPER(get_cp)(CPUARMState *env, uint32_t insn)
 {
     int op1 = (insn >> 8) & 0xf;
     cpu_abort(env, "cp%i insn %08x\n", op1, insn);
@@ -141,7 +141,7 @@
 
 #endif
 
-/* FIXME: Pass an axplicit pointer to QF to CPUState, and move saturating
+/* FIXME: Pass an axplicit pointer to QF to CPUARMState, and move saturating
    instructions into helper.c  */
 uint32_t HELPER(add_setq)(uint32_t a, uint32_t b)
 {
diff --git a/target-arm/translate-android.h b/target-arm/translate-android.h
index fe13f0f..61e934d 100644
--- a/target-arm/translate-android.h
+++ b/target-arm/translate-android.h
@@ -129,7 +129,7 @@
  *  0  - Insufficient memory.
  */
 static int
-register_ret_address(CPUState* env, target_ulong addr)
+register_ret_address(CPUARMState* env, target_ulong addr)
 {
     int ret;
     if ((0x90000000 <= addr && addr <= 0xBFFFFFFF)) {
@@ -172,7 +172,7 @@
  *  or 0 if it's not.
  */
 static inline int
-is_ret_address(CPUState* env, target_ulong addr)
+is_ret_address(CPUARMState* env, target_ulong addr)
 {
     if ((0x90000000 <= addr && addr <= 0xBFFFFFFF)) {
         return addrarray_check(&ret_addresses, get_phys_addr_code(env, addr));
@@ -265,123 +265,3 @@
 #  define ANDROID_END_CODEGEN()            ((void)0)
 
 #endif  /* !CONFIG_MEMCHECK */
-
-
-/*****
- *****
- *****
- *****  C O N F I G _ T R A C E
- *****
- *****
- *****/
-
-#ifdef CONFIG_TRACE
-
-#include "android/trace.h"
-#define  gen_traceInsn()   gen_helper_traceInsn()
-
-static void
-gen_traceTicks( int  count )
-{
-    TCGv  tmp = tcg_temp_new_i32();
-    tcg_gen_movi_i32(tmp, count);
-    gen_helper_traceTicks(tmp);
-    tcg_temp_free_i32(tmp);
-}
-
-static void
-gen_traceBB( uint64_t  bbNum, void* tb )
-{
-#if HOST_LONG_BITS == 32
-    TCGv_i64  tmpNum = tcg_temp_new_i64();
-    TCGv_i32  tmpTb  = tcg_temp_new_i32();
-
-    tcg_gen_movi_i64(tmpNum, (int64_t)bbNum);
-    tcg_gen_movi_i32(tmpTb,  (int32_t)tb);
-    gen_helper_traceBB32(tmpNum, tmpTb);
-    tcg_temp_free_i32(tmpTb);
-    tcg_temp_free_i64(tmpNum);
-#elif HOST_LONG_BITS == 64
-    TCGv_i64  tmpNum = tcg_temp_new_i64();
-    TCGv_i64  tmpTb  = tcg_temp_new_i64();
-
-    tcg_gen_movi_i64(tmpNum, (int64_t)bbNum);
-    tcg_gen_movi_i64(tmpTb,  (int64_t)tb);
-    gen_helper_traceBB64(tmpNum, tmpTb);
-    tcg_temp_free_i64(tmpTb);
-    tcg_temp_free_i64(tmpNum);
-#endif
-}
-
-#  define ANDROID_TRACE_DECLS   int ticks = 0;
-
-#  define ANDROID_TRACE_START_ARM() \
-    do { \
-        if (tracing) { \
-            trace_add_insn(insn, 0); \
-            ticks = get_insn_ticks_arm(insn); \
-            gen_traceInsn(); \
-        } \
-    } while (0)
-
-#  define ANDROID_TRACE_START_THUMB() \
-    do { \
-        if (tracing) { \
-            int  ticks = get_insn_ticks_thumb(insn); \
-            trace_add_insn( insn_wrap_thumb(insn), 1 ); \
-            gen_traceInsn(); \
-            gen_traceTicks(ticks); \
-        } \
-    } while (0)
-
-#  define ANDROID_TRACE_GEN_TICKS() \
-    do { \
-        if (tracing) { \
-        } \
-    } while (0)
-
-#  define ANDROID_TRACE_GEN_SINGLE_TICK() \
-    do { \
-        if (tracing) { \
-            gen_traceTicks(1); \
-            ticks -= 1; \
-        } \
-    } while (0)
-
-# define ANDROID_TRACE_GEN_OTHER_TICKS() \
-    do { \
-        if (tracing && ticks > 0) { \
-            gen_traceTicks(ticks); \
-        } \
-    } while (0)
-
-#  define ANDROID_TRACE_START_BB() \
-    do { \
-        if (tracing) { \
-            gen_traceBB(trace_static_bb_num(), tb); \
-            trace_bb_start(dc->pc); \
-        } \
-    } while (0)
-
-#  define ANDROID_TRACE_END_BB() \
-    do { \
-        if (tracing) { \
-            trace_bb_end(); \
-        } \
-    } while (0)
-
-#else /* !CONFIG_TRACE */
-
-#  define ANDROID_TRACE_DECLS         /* nothing */
-#  define ANDROID_TRACE_START_ARM()   ((void)0)
-#  define ANDROID_TRACE_START_THUMB() ((void)0)
-
-#  define ANDROID_TRACE_GEN_TICKS()        ((void)0)
-#  define ANDROID_TRACE_GEN_SINGLE_TICK()  ((void)0)
-#  define ANDROID_TRACE_GEN_OTHER_TICKS()  ((void)0)
-
-#  define ANDROID_TRACE_START_BB()         ((void)0)
-#  define ANDROID_TRACE_END_BB()           ((void)0)
-
-#endif /* !CONFIG_TRACE */
-
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 559a674..83d0e8f 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -118,20 +118,20 @@
 
     for (i = 0; i < 16; i++) {
         cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
-                                          offsetof(CPUState, regs[i]),
+                                          offsetof(CPUARMState, regs[i]),
                                           regnames[i]);
     }
     cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
-        offsetof(CPUState, exclusive_addr), "exclusive_addr");
+        offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
     cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
-        offsetof(CPUState, exclusive_val), "exclusive_val");
+        offsetof(CPUARMState, exclusive_val), "exclusive_val");
     cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
-        offsetof(CPUState, exclusive_high), "exclusive_high");
+        offsetof(CPUARMState, exclusive_high), "exclusive_high");
 #ifdef CONFIG_USER_ONLY
     cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
-        offsetof(CPUState, exclusive_test), "exclusive_test");
+        offsetof(CPUARMState, exclusive_test), "exclusive_test");
     cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
-        offsetof(CPUState, exclusive_info), "exclusive_info");
+        offsetof(CPUARMState, exclusive_info), "exclusive_info");
 #endif
 
 #define GEN_HELPER 2
@@ -145,7 +145,7 @@
     return tmp;
 }
 
-#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
+#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
 
 static inline void store_cpu_offset(TCGv var, int offset)
 {
@@ -154,7 +154,7 @@
 }
 
 #define store_cpu_field(var, name) \
-    store_cpu_offset(var, offsetof(CPUState, name))
+    store_cpu_offset(var, offsetof(CPUARMState, name))
 
 /* Set a variable to the value of a CPU register.  */
 static void load_reg_var(DisasContext *s, TCGv var, int reg)
@@ -375,7 +375,7 @@
     tcg_temp_free_i32(t1);
 }
 
-#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
+#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, CF))
 
 /* Set CF to the top bit of var.  */
 static void gen_set_CF_bit31(TCGv var)
@@ -389,8 +389,8 @@
 /* Set N and Z flags from var.  */
 static inline void gen_logic_CC(TCGv var)
 {
-    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
-    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
+    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, NF));
+    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, ZF));
 }
 
 /* T0 += T1 + CF.  */
@@ -530,13 +530,13 @@
 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
     case 1:
         tmp = tcg_temp_new_ptr();
-        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
+        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
         PAS_OP(s)
         tcg_temp_free_ptr(tmp);
         break;
     case 5:
         tmp = tcg_temp_new_ptr();
-        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
+        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
         PAS_OP(u)
         tcg_temp_free_ptr(tmp);
         break;
@@ -577,13 +577,13 @@
 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
     case 0:
         tmp = tcg_temp_new_ptr();
-        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
+        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
         PAS_OP(s)
         tcg_temp_free_ptr(tmp);
         break;
     case 4:
         tmp = tcg_temp_new_ptr();
-        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
+        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
         PAS_OP(u)
         tcg_temp_free_ptr(tmp);
         break;
@@ -732,7 +732,7 @@
     if (s->thumb != (addr & 1)) {
         tmp = tcg_temp_new_i32();
         tcg_gen_movi_i32(tmp, addr & 1);
-        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
+        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
         tcg_temp_free_i32(tmp);
     }
     tcg_gen_movi_i32(cpu_R[15], addr & ~1);
@@ -750,7 +750,7 @@
 /* Variant of store_reg which uses branch&exchange logic when storing
    to r15 in ARM architecture v7 and above. The source must be a temporary
    and will be marked as dead. */
-static inline void store_reg_bx(CPUState *env, DisasContext *s,
+static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
                                 int reg, TCGv var)
 {
     if (reg == 15 && ENABLE_ARCH_7) {
@@ -764,7 +764,7 @@
  * to r15 in ARM architecture v5T and above. This is used for storing
  * the results of a LDR/LDM/POP into r15, and corresponds to the cases
  * in the ARM ARM which use the LoadWritePC() pseudocode function. */
-static inline void store_reg_from_load(CPUState *env, DisasContext *s,
+static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
                                 int reg, TCGv var)
 {
     if (reg == 15 && ENABLE_ARCH_5) {
@@ -774,7 +774,7 @@
     }
 }
 
-static inline void gen_smc(CPUState *env, DisasContext *s)
+static inline void gen_smc(CPUARMState *env, DisasContext *s)
 {
     tcg_gen_movi_i32(cpu_R[15], s->pc);
     s->is_jmp = DISAS_SMC;
@@ -995,9 +995,9 @@
     TCGv_ptr statusptr = tcg_temp_new_ptr(); \
     int offset; \
     if (neon) { \
-        offset = offsetof(CPUState, vfp.standard_fp_status); \
+        offset = offsetof(CPUARMState, vfp.standard_fp_status); \
     } else { \
-        offset = offsetof(CPUState, vfp.fp_status); \
+        offset = offsetof(CPUARMState, vfp.fp_status); \
     } \
     tcg_gen_addi_ptr(statusptr, cpu_env, offset); \
     if (dp) { \
@@ -1018,9 +1018,9 @@
     TCGv_ptr statusptr = tcg_temp_new_ptr(); \
     int offset; \
     if (neon) { \
-        offset = offsetof(CPUState, vfp.standard_fp_status); \
+        offset = offsetof(CPUARMState, vfp.standard_fp_status); \
     } else { \
-        offset = offsetof(CPUState, vfp.fp_status); \
+        offset = offsetof(CPUARMState, vfp.fp_status); \
     } \
     tcg_gen_addi_ptr(statusptr, cpu_env, offset); \
     if (dp) { \
@@ -1044,9 +1044,9 @@
     TCGv_ptr statusptr = tcg_temp_new_ptr(); \
     int offset; \
     if (neon) { \
-        offset = offsetof(CPUState, vfp.standard_fp_status); \
+        offset = offsetof(CPUARMState, vfp.standard_fp_status); \
     } else { \
-        offset = offsetof(CPUState, vfp.fp_status); \
+        offset = offsetof(CPUARMState, vfp.fp_status); \
     } \
     tcg_gen_addi_ptr(statusptr, cpu_env, offset); \
     if (dp) { \
@@ -1163,24 +1163,24 @@
 
 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
 {
-    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
+    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
 }
 
 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
 {
-    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
+    tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
 }
 
 static inline TCGv iwmmxt_load_creg(int reg)
 {
     TCGv var = tcg_temp_new_i32();
-    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
+    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
     return var;
 }
 
 static inline void iwmmxt_store_creg(int reg, TCGv var)
 {
-    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
+    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
     tcg_temp_free_i32(var);
 }
 
@@ -1375,7 +1375,7 @@
 
 /* Disassemble an iwMMXt instruction.  Returns nonzero if an error occurred
    (ie. an undefined instruction).  */
-static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
+static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 {
     int rd, wrd;
     int rdhi, rdlo, rd0, rd1, i;
@@ -2379,7 +2379,7 @@
 
 /* Disassemble an XScale DSP instruction.  Returns nonzero if an error occurred
    (ie. an undefined instruction).  */
-static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
+static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 {
     int acc, rd0, rd1, rdhi, rdlo;
     TCGv tmp, tmp2;
@@ -2449,7 +2449,7 @@
 
 /* Disassemble system coprocessor instruction.  Return nonzero if
    instruction is not defined.  */
-static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
+static int disas_cp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 {
     TCGv tmp, tmp2;
     uint32_t rd = (insn >> 12) & 0xf;
@@ -2497,7 +2497,7 @@
     return 0;
 }
 
-static int cp15_tls_load_store(CPUState *env, DisasContext *s, uint32_t insn, uint32_t rd)
+static int cp15_tls_load_store(CPUARMState *env, DisasContext *s, uint32_t insn, uint32_t rd)
 {
     TCGv tmp;
     int cpn = (insn >> 16) & 0xf;
@@ -2548,7 +2548,7 @@
 
 /* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
    instruction is not defined.  */
-static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
+static int disas_cp15_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 {
     uint32_t rd;
     TCGv tmp, tmp2;
@@ -2722,7 +2722,7 @@
 
 /* Disassemble a VFP instruction.  Returns nonzero if an error occurred
    (ie. an undefined instruction).  */
-static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
+static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 {
     uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
     int dp, veclen;
@@ -3487,7 +3487,7 @@
 }
 
 /* Return the mask of PSR bits set by a MSR instruction.  */
-static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
+static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
     uint32_t mask;
 
     mask = 0;
@@ -3824,7 +3824,7 @@
 
 /* Translate a NEON load/store element instruction.  Return nonzero if the
    instruction is invalid.  */
-static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
+static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 {
     int rd, rn, rm;
     int op;
@@ -4413,7 +4413,7 @@
    We process data in a mixture of 32-bit and 64-bit chunks.
    Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
 
-static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
+static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 {
     int op;
     int q;
@@ -6075,7 +6075,7 @@
     return 0;
 }
 
-static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
+static int disas_cp14_read(CPUARMState * env, DisasContext *s, uint32_t insn)
 {
     int crn = (insn >> 16) & 0xf;
     int crm = insn & 0xf;
@@ -6135,7 +6135,7 @@
     return 1;
 }
 
-static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
+static int disas_cp14_write(CPUARMState * env, DisasContext *s, uint32_t insn)
 {
     int crn = (insn >> 16) & 0xf;
     int crm = insn & 0xf;
@@ -6192,7 +6192,7 @@
     return 1;
 }
 
-static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
+static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 {
     int cpnum;
 
@@ -6412,10 +6412,9 @@
 }
 #endif
 
-static void disas_arm_insn(CPUState * env, DisasContext *s)
+static void disas_arm_insn(CPUARMState * env, DisasContext *s)
 {
     unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
-    ANDROID_TRACE_DECLS
     TCGv tmp;
     TCGv tmp2;
     TCGv tmp3;
@@ -6426,8 +6425,6 @@
 
     ANDROID_WATCH_CALLSTACK_ARM(s);
 
-    ANDROID_TRACE_START_ARM();
-
     s->pc += 4;
 
     /* M variants do not implement ARM mode.  */
@@ -6441,7 +6438,6 @@
          */
         ARCH(5);
 
-        ANDROID_TRACE_GEN_TICKS();
         /* Unconditional instructions.  */
         if (((insn >> 25) & 7) == 1) {
             /* NEON Data processing.  */
@@ -6654,14 +6650,12 @@
         goto illegal_op;
     }
     if (cond != 0xe) {
-        ANDROID_TRACE_GEN_SINGLE_TICK();
         /* if not always execute, we generate a conditional jump to
            next instruction */
         s->condlabel = gen_new_label();
         gen_test_cc(cond ^ 1, s->condlabel);
         s->condjmp = 1;
     }
-    ANDROID_TRACE_GEN_OTHER_TICKS();
     if ((insn & 0x0f900000) == 0x03000000) {
         if ((insn & (1 << 21)) == 0) {
             ARCH(6T2);
@@ -7319,7 +7313,7 @@
                         tmp = load_reg(s, rn);
                         tmp2 = load_reg(s, rm);
                         tmp3 = tcg_temp_new_i32();
-                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
+                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
                         gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
                         tcg_temp_free_i32(tmp3);
                         tcg_temp_free_i32(tmp2);
@@ -7776,7 +7770,7 @@
 
 /* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
    is not legal.  */
-static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
+static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
 {
     uint32_t insn, imm, shift, offset;
     uint32_t rd, rn, rm, rs;
@@ -7833,7 +7827,6 @@
     }
 
     insn = lduw_code(s->pc);
-    ANDROID_TRACE_START_THUMB();
     s->pc += 2;
     insn |= (uint32_t)insn_hw1 << 16;
 
@@ -8190,7 +8183,7 @@
                 case 0x10: /* sel */
                     tmp2 = load_reg(s, rm);
                     tmp3 = tcg_temp_new_i32();
-                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
+                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
                     gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
                     tcg_temp_free_i32(tmp3);
                     tcg_temp_free_i32(tmp2);
@@ -8847,7 +8840,7 @@
     return 1;
 }
 
-static void disas_thumb_insn(CPUState *env, DisasContext *s)
+static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
 {
     uint32_t val, insn, op, rm, rn, rd, shift, cond;
     int32_t offset;
@@ -8869,8 +8862,6 @@
 
     ANDROID_WATCH_CALLSTACK_THUMB(s);
 
-    ANDROID_TRACE_START_THUMB();
-
     s->pc += 2;
 
     switch (insn >> 12) {
@@ -9539,7 +9530,7 @@
 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
    basic block 'tb'. If search_pc is TRUE, also generate PC
    information for each intermediate instruction. */
-static inline void gen_intermediate_code_internal(CPUState *env,
+static inline void gen_intermediate_code_internal(CPUARMState *env,
                                                   TranslationBlock *tb,
                                                   int search_pc)
 {
@@ -9589,29 +9580,28 @@
         max_insns = CF_COUNT_MASK;
 
     gen_icount_start();
-    ANDROID_TRACE_START_BB();
 
     tcg_clear_temp_count();
 
     /* A note on handling of the condexec (IT) bits:
      *
      * We want to avoid the overhead of having to write the updated condexec
-     * bits back to the CPUState for every instruction in an IT block. So:
+     * bits back to the CPUARMState for every instruction in an IT block. So:
      * (1) if the condexec bits are not already zero then we write
-     * zero back into the CPUState now. This avoids complications trying
+     * zero back into the CPUARMState now. This avoids complications trying
      * to do it at the end of the block. (For example if we don't do this
      * it's hard to identify whether we can safely skip writing condexec
      * at the end of the TB, which we definitely want to do for the case
      * where a TB doesn't do anything with the IT state at all.)
      * (2) if we are going to leave the TB then we call gen_set_condexec()
-     * which will write the correct value into CPUState if zero is wrong.
+     * which will write the correct value into CPUARMState if zero is wrong.
      * This is done both for leaving the TB at the end, and for leaving
      * it because of an exception we know will happen, which is done in
      * gen_exception_insn(). The latter is necessary because we need to
      * leave the TB with the PC/IT state just prior to execution of the
      * instruction which caused the exception.
      * (3) if we leave the TB unexpectedly (eg a data abort on a load)
-     * then the CPUState will be wrong and we need to reset it.
+     * then the CPUARMState will be wrong and we need to reset it.
      * This is handled in the same way as restoration of the
      * PC in these situations: we will be called again with search_pc=1
      * and generate a mapping of the condexec bits for each PC in
@@ -9620,7 +9610,7 @@
      *
      * Note that there are no instructions which can read the condexec
      * bits, and none which can write non-static values to them, so
-     * we don't need to care about whether CPUState is correct in the
+     * we don't need to care about whether CPUARMState is correct in the
      * middle of a TB.
      */
 
@@ -9719,8 +9709,6 @@
              dc->pc < next_page_start &&
              num_insns < max_insns);
 
-    ANDROID_TRACE_END_BB();
-
     if (tb->cflags & CF_LAST_IO) {
         if (dc->condjmp) {
             /* FIXME:  This can theoretically happen with self-modifying
@@ -9809,7 +9797,7 @@
     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(env, pc_start, dc->pc - pc_start, dc->thumb);
         qemu_log("\n");
     }
 #endif
@@ -9825,12 +9813,12 @@
     }
 }
 
-void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
+void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
 {
     gen_intermediate_code_internal(env, tb, 0);
 }
 
-void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
+void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
 {
     gen_intermediate_code_internal(env, tb, 1);
 }
@@ -9840,7 +9828,7 @@
   "???", "???", "???", "und", "???", "???", "???", "sys"
 };
 
-void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
+void cpu_dump_state(CPUARMState *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
 {
     int i;
@@ -9892,7 +9880,7 @@
 #endif
 }
 
-void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
+void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
 {
     env->regs[15] = gen_opc_pc[pc_pos];
     env->condexec_bits = gen_opc_condexec_bits[pc_pos];
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 15ffcf3..de23359 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -14,13 +14,13 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 #ifndef CPU_I386_H
 #define CPU_I386_H
 
 #include "config.h"
+#include "qemu-common.h"
 
 #ifdef TARGET_X86_64
 #define TARGET_LONG_BITS 64
@@ -37,12 +37,15 @@
 #define TARGET_HAS_ICE 1
 
 #ifdef TARGET_X86_64
-#define ELF_MACHINE	EM_X86_64
+#define ELF_MACHINE     EM_X86_64
 #else
-#define ELF_MACHINE	EM_386
+#define ELF_MACHINE     EM_386
 #endif
 
-#define CPUState struct CPUX86State
+// TODO(digit): Remove this define.
+#define CPUOldState struct CPUX86State
+
+#define CPUArchState struct CPUX86State
 
 #include "exec/cpu-defs.h"
 
@@ -98,10 +101,10 @@
 #define DESC_TSS_BUSY_MASK (1 << 9)
 
 /* eflags masks */
-#define CC_C   	0x0001
-#define CC_P 	0x0004
-#define CC_A	0x0010
-#define CC_Z	0x0040
+#define CC_C    0x0001
+#define CC_P    0x0004
+#define CC_A    0x0010
+#define CC_Z    0x0040
 #define CC_S    0x0080
 #define CC_O    0x0800
 
@@ -109,22 +112,22 @@
 #define IOPL_SHIFT 12
 #define VM_SHIFT   17
 
-#define TF_MASK 		0x00000100
-#define IF_MASK 		0x00000200
-#define DF_MASK 		0x00000400
-#define IOPL_MASK		0x00003000
-#define NT_MASK	         	0x00004000
-#define RF_MASK			0x00010000
-#define VM_MASK			0x00020000
-#define AC_MASK			0x00040000
+#define TF_MASK                 0x00000100
+#define IF_MASK                 0x00000200
+#define DF_MASK                 0x00000400
+#define IOPL_MASK               0x00003000
+#define NT_MASK                 0x00004000
+#define RF_MASK                 0x00010000
+#define VM_MASK                 0x00020000
+#define AC_MASK                 0x00040000
 #define VIF_MASK                0x00080000
 #define VIP_MASK                0x00100000
 #define ID_MASK                 0x00200000
 
 /* hidden flags - used internally by qemu to represent additional cpu
    states. Only the CPL, INHIBIT_IRQ, SMM and SVMI are not
-   redundant. We avoid using the IOPL_MASK, TF_MASK and VM_MASK bit
-   position to ease oring with eflags. */
+   redundant. We avoid using the IOPL_MASK, TF_MASK, VM_MASK and AC_MASK
+   bit positions to ease oring with eflags. */
 /* current cpl */
 #define HF_CPL_SHIFT         0
 /* true if soft mmu is being used */
@@ -147,10 +150,12 @@
 #define HF_CS64_SHIFT       15 /* only used on x86_64: 64 bit code segment  */
 #define HF_RF_SHIFT         16 /* must be same as eflags */
 #define HF_VM_SHIFT         17 /* must be same as eflags */
+#define HF_AC_SHIFT         18 /* must be same as eflags */
 #define HF_SMM_SHIFT        19 /* CPU in SMM mode */
 #define HF_SVME_SHIFT       20 /* SVME enabled (copy of EFER.SVME) */
 #define HF_SVMI_SHIFT       21 /* SVM intercepts are active */
 #define HF_OSFXSR_SHIFT     22 /* CR4.OSFXSR */
+#define HF_SMAP_SHIFT       23 /* CR4.SMAP */
 
 #define HF_CPL_MASK          (3 << HF_CPL_SHIFT)
 #define HF_SOFTMMU_MASK      (1 << HF_SOFTMMU_SHIFT)
@@ -168,10 +173,12 @@
 #define HF_CS64_MASK         (1 << HF_CS64_SHIFT)
 #define HF_RF_MASK           (1 << HF_RF_SHIFT)
 #define HF_VM_MASK           (1 << HF_VM_SHIFT)
+#define HF_AC_MASK           (1 << HF_AC_SHIFT)
 #define HF_SMM_MASK          (1 << HF_SMM_SHIFT)
 #define HF_SVME_MASK         (1 << HF_SVME_SHIFT)
 #define HF_SVMI_MASK         (1 << HF_SVMI_SHIFT)
 #define HF_OSFXSR_MASK       (1 << HF_OSFXSR_SHIFT)
+#define HF_SMAP_MASK         (1 << HF_SMAP_SHIFT)
 
 /* hflags2 */
 
@@ -210,6 +217,13 @@
 #define CR4_OSFXSR_SHIFT 9
 #define CR4_OSFXSR_MASK (1 << CR4_OSFXSR_SHIFT)
 #define CR4_OSXMMEXCPT_MASK  (1 << 10)
+#define CR4_VMXE_MASK   (1 << 13)
+#define CR4_SMXE_MASK   (1 << 14)
+#define CR4_FSGSBASE_MASK (1 << 16)
+#define CR4_PCIDE_MASK  (1 << 17)
+#define CR4_OSXSAVE_MASK (1 << 18)
+#define CR4_SMEP_MASK   (1 << 20)
+#define CR4_SMAP_MASK   (1 << 21)
 
 #define DR6_BD          (1 << 13)
 #define DR6_BS          (1 << 14)
@@ -220,28 +234,35 @@
 #define DR7_TYPE_SHIFT  16
 #define DR7_LEN_SHIFT   18
 #define DR7_FIXED_1     0x00000400
+#define DR7_LOCAL_BP_MASK    0x55
+#define DR7_MAX_BP           4
+#define DR7_TYPE_BP_INST     0x0
+#define DR7_TYPE_DATA_WR     0x1
+#define DR7_TYPE_IO_RW       0x2
+#define DR7_TYPE_DATA_RW     0x3
 
-#define PG_PRESENT_BIT	0
-#define PG_RW_BIT	1
-#define PG_USER_BIT	2
-#define PG_PWT_BIT	3
-#define PG_PCD_BIT	4
-#define PG_ACCESSED_BIT	5
-#define PG_DIRTY_BIT	6
-#define PG_PSE_BIT	7
-#define PG_GLOBAL_BIT	8
-#define PG_NX_BIT	63
+#define PG_PRESENT_BIT  0
+#define PG_RW_BIT       1
+#define PG_USER_BIT     2
+#define PG_PWT_BIT      3
+#define PG_PCD_BIT      4
+#define PG_ACCESSED_BIT 5
+#define PG_DIRTY_BIT    6
+#define PG_PSE_BIT      7
+#define PG_GLOBAL_BIT   8
+#define PG_NX_BIT       63
 
 #define PG_PRESENT_MASK  (1 << PG_PRESENT_BIT)
-#define PG_RW_MASK	 (1 << PG_RW_BIT)
-#define PG_USER_MASK	 (1 << PG_USER_BIT)
-#define PG_PWT_MASK	 (1 << PG_PWT_BIT)
-#define PG_PCD_MASK	 (1 << PG_PCD_BIT)
+#define PG_RW_MASK       (1 << PG_RW_BIT)
+#define PG_USER_MASK     (1 << PG_USER_BIT)
+#define PG_PWT_MASK      (1 << PG_PWT_BIT)
+#define PG_PCD_MASK      (1 << PG_PCD_BIT)
 #define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
-#define PG_DIRTY_MASK	 (1 << PG_DIRTY_BIT)
-#define PG_PSE_MASK	 (1 << PG_PSE_BIT)
-#define PG_GLOBAL_MASK	 (1 << PG_GLOBAL_BIT)
-#define PG_NX_MASK	 (1LL << PG_NX_BIT)
+#define PG_DIRTY_MASK    (1 << PG_DIRTY_BIT)
+#define PG_PSE_MASK      (1 << PG_PSE_BIT)
+#define PG_GLOBAL_MASK   (1 << PG_GLOBAL_BIT)
+#define PG_HI_USER_MASK  0x7ff0000000000000LL
+#define PG_NX_MASK       (1LL << PG_NX_BIT)
 
 #define PG_ERROR_W_BIT     1
 
@@ -251,27 +272,46 @@
 #define PG_ERROR_RSVD_MASK 0x08
 #define PG_ERROR_I_D_MASK  0x10
 
-#define MCG_CTL_P      (1UL<<8)   /* MCG_CAP register available */
+#define MCG_CTL_P       (1ULL<<8)   /* MCG_CAP register available */
+#define MCG_SER_P       (1ULL<<24) /* MCA recovery/new status bits */
 
 #define MCE_CAP_DEF    MCG_CTL_P
 #define MCE_BANKS_DEF  10
 
 #define MCG_STATUS_MCIP        (1UL<<2)   /* machine check in progress */
 
-#define MCI_STATUS_VAL (1ULL<<63)  /* valid error */
-#define MCI_STATUS_OVER        (1ULL<<62)  /* previous errors lost */
-#define MCI_STATUS_UC  (1ULL<<61)  /* uncorrected error */
+#define MCI_STATUS_VAL   (1ULL<<63)  /* valid error */
+#define MCI_STATUS_OVER  (1ULL<<62)  /* previous errors lost */
+#define MCI_STATUS_UC    (1ULL<<61)  /* uncorrected error */
+#define MCI_STATUS_EN    (1ULL<<60)  /* error enabled */
+#define MCI_STATUS_MISCV (1ULL<<59)  /* misc error reg. valid */
+#define MCI_STATUS_ADDRV (1ULL<<58)  /* addr reg. valid */
+#define MCI_STATUS_PCC   (1ULL<<57)  /* processor context corrupt */
+#define MCI_STATUS_S     (1ULL<<56)  /* Signaled machine check */
+#define MCI_STATUS_AR    (1ULL<<55)  /* Action required */
+
+/* MISC register defines */
+#define MCM_ADDR_SEGOFF  0      /* segment offset */
+#define MCM_ADDR_LINEAR  1      /* linear address */
+#define MCM_ADDR_PHYS    2      /* physical address */
+#define MCM_ADDR_MEM     3      /* memory address */
+#define MCM_ADDR_GENERIC 7      /* generic */
 
 #define MSR_IA32_TSC                    0x10
 #define MSR_IA32_APICBASE               0x1b
 #define MSR_IA32_APICBASE_BSP           (1<<8)
 #define MSR_IA32_APICBASE_ENABLE        (1<<11)
 #define MSR_IA32_APICBASE_BASE          (0xfffff<<12)
+#define MSR_IA32_FEATURE_CONTROL        0x0000003a
+#define MSR_TSC_ADJUST                  0x0000003b
+#define MSR_IA32_TSCDEADLINE            0x6e0
 
-#define MSR_MTRRcap			0xfe
-#define MSR_MTRRcap_VCNT		8
-#define MSR_MTRRcap_FIXRANGE_SUPPORT	(1 << 8)
-#define MSR_MTRRcap_WC_SUPPORTED	(1 << 10)
+#define MSR_P6_PERFCTR0                 0xc1
+
+#define MSR_MTRRcap                     0xfe
+#define MSR_MTRRcap_VCNT                8
+#define MSR_MTRRcap_FIXRANGE_SUPPORT    (1 << 8)
+#define MSR_MTRRcap_WC_SUPPORTED        (1 << 10)
 
 #define MSR_IA32_SYSENTER_CS            0x174
 #define MSR_IA32_SYSENTER_ESP           0x175
@@ -281,31 +321,45 @@
 #define MSR_MCG_STATUS                  0x17a
 #define MSR_MCG_CTL                     0x17b
 
+#define MSR_P6_EVNTSEL0                 0x186
+
 #define MSR_IA32_PERF_STATUS            0x198
 
-#define MSR_MTRRphysBase(reg)		(0x200 + 2 * (reg))
-#define MSR_MTRRphysMask(reg)		(0x200 + 2 * (reg) + 1)
+#define MSR_IA32_MISC_ENABLE            0x1a0
+/* Indicates good rep/movs microcode on some processors: */
+#define MSR_IA32_MISC_ENABLE_DEFAULT    1
 
-#define MSR_MTRRfix64K_00000		0x250
-#define MSR_MTRRfix16K_80000		0x258
-#define MSR_MTRRfix16K_A0000		0x259
-#define MSR_MTRRfix4K_C0000		0x268
-#define MSR_MTRRfix4K_C8000		0x269
-#define MSR_MTRRfix4K_D0000		0x26a
-#define MSR_MTRRfix4K_D8000		0x26b
-#define MSR_MTRRfix4K_E0000		0x26c
-#define MSR_MTRRfix4K_E8000		0x26d
-#define MSR_MTRRfix4K_F0000		0x26e
-#define MSR_MTRRfix4K_F8000		0x26f
+#define MSR_MTRRphysBase(reg)           (0x200 + 2 * (reg))
+#define MSR_MTRRphysMask(reg)           (0x200 + 2 * (reg) + 1)
+
+#define MSR_MTRRfix64K_00000            0x250
+#define MSR_MTRRfix16K_80000            0x258
+#define MSR_MTRRfix16K_A0000            0x259
+#define MSR_MTRRfix4K_C0000             0x268
+#define MSR_MTRRfix4K_C8000             0x269
+#define MSR_MTRRfix4K_D0000             0x26a
+#define MSR_MTRRfix4K_D8000             0x26b
+#define MSR_MTRRfix4K_E0000             0x26c
+#define MSR_MTRRfix4K_E8000             0x26d
+#define MSR_MTRRfix4K_F0000             0x26e
+#define MSR_MTRRfix4K_F8000             0x26f
 
 #define MSR_PAT                         0x277
 
-#define MSR_MTRRdefType			0x2ff
+#define MSR_MTRRdefType                 0x2ff
 
-#define MSR_MC0_CTL                    0x400
-#define MSR_MC0_STATUS                 0x401
-#define MSR_MC0_ADDR                   0x402
-#define MSR_MC0_MISC                   0x403
+#define MSR_CORE_PERF_FIXED_CTR0        0x309
+#define MSR_CORE_PERF_FIXED_CTR1        0x30a
+#define MSR_CORE_PERF_FIXED_CTR2        0x30b
+#define MSR_CORE_PERF_FIXED_CTR_CTRL    0x38d
+#define MSR_CORE_PERF_GLOBAL_STATUS     0x38e
+#define MSR_CORE_PERF_GLOBAL_CTRL       0x38f
+#define MSR_CORE_PERF_GLOBAL_OVF_CTRL   0x390
+
+#define MSR_MC0_CTL                     0x400
+#define MSR_MC0_STATUS                  0x401
+#define MSR_MC0_ADDR                    0x402
+#define MSR_MC0_MISC                    0x403
 
 #define MSR_EFER                        0xc0000080
 
@@ -323,9 +377,29 @@
 #define MSR_FSBASE                      0xc0000100
 #define MSR_GSBASE                      0xc0000101
 #define MSR_KERNELGSBASE                0xc0000102
+#define MSR_TSC_AUX                     0xc0000103
 
 #define MSR_VM_HSAVE_PA                 0xc0010117
 
+#define XSTATE_FP                       1
+#define XSTATE_SSE                      2
+#define XSTATE_YMM                      4
+
+/* CPUID feature words */
+typedef enum FeatureWord {
+    FEAT_1_EDX,         /* CPUID[1].EDX */
+    FEAT_1_ECX,         /* CPUID[1].ECX */
+    FEAT_7_0_EBX,       /* CPUID[EAX=7,ECX=0].EBX */
+    FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */
+    FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
+    FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
+    FEAT_KVM,           /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
+    FEAT_SVM,           /* CPUID[8000_000A].EDX */
+    FEATURE_WORDS,
+} FeatureWord;
+
+typedef uint32_t FeatureWordArray[FEATURE_WORDS];
+
 /* cpuid_features bits */
 #define CPUID_FP87 (1 << 0)
 #define CPUID_VME  (1 << 1)
@@ -359,6 +433,7 @@
 #define CPUID_PBE (1 << 31)
 
 #define CPUID_EXT_SSE3     (1 << 0)
+#define CPUID_EXT_PCLMULQDQ (1 << 1)
 #define CPUID_EXT_DTES64   (1 << 2)
 #define CPUID_EXT_MONITOR  (1 << 3)
 #define CPUID_EXT_DSCPL    (1 << 4)
@@ -368,22 +443,48 @@
 #define CPUID_EXT_TM2      (1 << 8)
 #define CPUID_EXT_SSSE3    (1 << 9)
 #define CPUID_EXT_CID      (1 << 10)
+#define CPUID_EXT_FMA      (1 << 12)
 #define CPUID_EXT_CX16     (1 << 13)
 #define CPUID_EXT_XTPR     (1 << 14)
 #define CPUID_EXT_PDCM     (1 << 15)
+#define CPUID_EXT_PCID     (1 << 17)
 #define CPUID_EXT_DCA      (1 << 18)
 #define CPUID_EXT_SSE41    (1 << 19)
 #define CPUID_EXT_SSE42    (1 << 20)
 #define CPUID_EXT_X2APIC   (1 << 21)
 #define CPUID_EXT_MOVBE    (1 << 22)
 #define CPUID_EXT_POPCNT   (1 << 23)
+#define CPUID_EXT_TSC_DEADLINE_TIMER (1 << 24)
+#define CPUID_EXT_AES      (1 << 25)
 #define CPUID_EXT_XSAVE    (1 << 26)
 #define CPUID_EXT_OSXSAVE  (1 << 27)
+#define CPUID_EXT_AVX      (1 << 28)
+#define CPUID_EXT_F16C     (1 << 29)
+#define CPUID_EXT_RDRAND   (1 << 30)
+#define CPUID_EXT_HYPERVISOR  (1 << 31)
 
+#define CPUID_EXT2_FPU     (1 << 0)
+#define CPUID_EXT2_VME     (1 << 1)
+#define CPUID_EXT2_DE      (1 << 2)
+#define CPUID_EXT2_PSE     (1 << 3)
+#define CPUID_EXT2_TSC     (1 << 4)
+#define CPUID_EXT2_MSR     (1 << 5)
+#define CPUID_EXT2_PAE     (1 << 6)
+#define CPUID_EXT2_MCE     (1 << 7)
+#define CPUID_EXT2_CX8     (1 << 8)
+#define CPUID_EXT2_APIC    (1 << 9)
 #define CPUID_EXT2_SYSCALL (1 << 11)
+#define CPUID_EXT2_MTRR    (1 << 12)
+#define CPUID_EXT2_PGE     (1 << 13)
+#define CPUID_EXT2_MCA     (1 << 14)
+#define CPUID_EXT2_CMOV    (1 << 15)
+#define CPUID_EXT2_PAT     (1 << 16)
+#define CPUID_EXT2_PSE36   (1 << 17)
 #define CPUID_EXT2_MP      (1 << 19)
 #define CPUID_EXT2_NX      (1 << 20)
 #define CPUID_EXT2_MMXEXT  (1 << 22)
+#define CPUID_EXT2_MMX     (1 << 23)
+#define CPUID_EXT2_FXSR    (1 << 24)
 #define CPUID_EXT2_FFXSR   (1 << 25)
 #define CPUID_EXT2_PDPE1GB (1 << 26)
 #define CPUID_EXT2_RDTSCP  (1 << 27)
@@ -391,6 +492,17 @@
 #define CPUID_EXT2_3DNOWEXT (1 << 30)
 #define CPUID_EXT2_3DNOW   (1 << 31)
 
+/* CPUID[8000_0001].EDX bits that are aliase of CPUID[1].EDX bits on AMD CPUs */
+#define CPUID_EXT2_AMD_ALIASES (CPUID_EXT2_FPU | CPUID_EXT2_VME | \
+                                CPUID_EXT2_DE | CPUID_EXT2_PSE | \
+                                CPUID_EXT2_TSC | CPUID_EXT2_MSR | \
+                                CPUID_EXT2_PAE | CPUID_EXT2_MCE | \
+                                CPUID_EXT2_CX8 | CPUID_EXT2_APIC | \
+                                CPUID_EXT2_MTRR | CPUID_EXT2_PGE | \
+                                CPUID_EXT2_MCA | CPUID_EXT2_CMOV | \
+                                CPUID_EXT2_PAT | CPUID_EXT2_PSE36 | \
+                                CPUID_EXT2_MMX | CPUID_EXT2_FXSR)
+
 #define CPUID_EXT3_LAHF_LM (1 << 0)
 #define CPUID_EXT3_CMP_LEG (1 << 1)
 #define CPUID_EXT3_SVM     (1 << 2)
@@ -402,19 +514,63 @@
 #define CPUID_EXT3_3DNOWPREFETCH (1 << 8)
 #define CPUID_EXT3_OSVW    (1 << 9)
 #define CPUID_EXT3_IBS     (1 << 10)
+#define CPUID_EXT3_XOP     (1 << 11)
 #define CPUID_EXT3_SKINIT  (1 << 12)
+#define CPUID_EXT3_WDT     (1 << 13)
+#define CPUID_EXT3_LWP     (1 << 15)
+#define CPUID_EXT3_FMA4    (1 << 16)
+#define CPUID_EXT3_TCE     (1 << 17)
+#define CPUID_EXT3_NODEID  (1 << 19)
+#define CPUID_EXT3_TBM     (1 << 21)
+#define CPUID_EXT3_TOPOEXT (1 << 22)
+#define CPUID_EXT3_PERFCORE (1 << 23)
+#define CPUID_EXT3_PERFNB  (1 << 24)
+
+#define CPUID_SVM_NPT          (1 << 0)
+#define CPUID_SVM_LBRV         (1 << 1)
+#define CPUID_SVM_SVMLOCK      (1 << 2)
+#define CPUID_SVM_NRIPSAVE     (1 << 3)
+#define CPUID_SVM_TSCSCALE     (1 << 4)
+#define CPUID_SVM_VMCBCLEAN    (1 << 5)
+#define CPUID_SVM_FLUSHASID    (1 << 6)
+#define CPUID_SVM_DECODEASSIST (1 << 7)
+#define CPUID_SVM_PAUSEFILTER  (1 << 10)
+#define CPUID_SVM_PFTHRESHOLD  (1 << 12)
+
+#define CPUID_7_0_EBX_FSGSBASE (1 << 0)
+#define CPUID_7_0_EBX_BMI1     (1 << 3)
+#define CPUID_7_0_EBX_HLE      (1 << 4)
+#define CPUID_7_0_EBX_AVX2     (1 << 5)
+#define CPUID_7_0_EBX_SMEP     (1 << 7)
+#define CPUID_7_0_EBX_BMI2     (1 << 8)
+#define CPUID_7_0_EBX_ERMS     (1 << 9)
+#define CPUID_7_0_EBX_INVPCID  (1 << 10)
+#define CPUID_7_0_EBX_RTM      (1 << 11)
+#define CPUID_7_0_EBX_RDSEED   (1 << 18)
+#define CPUID_7_0_EBX_ADX      (1 << 19)
+#define CPUID_7_0_EBX_SMAP     (1 << 20)
+
+#define CPUID_VENDOR_SZ      12
 
 #define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */
 #define CPUID_VENDOR_INTEL_2 0x49656e69 /* "ineI" */
 #define CPUID_VENDOR_INTEL_3 0x6c65746e /* "ntel" */
+#define CPUID_VENDOR_INTEL "GenuineIntel"
 
 #define CPUID_VENDOR_AMD_1   0x68747541 /* "Auth" */
 #define CPUID_VENDOR_AMD_2   0x69746e65 /* "enti" */
 #define CPUID_VENDOR_AMD_3   0x444d4163 /* "cAMD" */
+#define CPUID_VENDOR_AMD   "AuthenticAMD"
+
+#define CPUID_VENDOR_VIA   "CentaurHauls"
 
 #define CPUID_MWAIT_IBE     (1 << 1) /* Interrupts can exit capability */
 #define CPUID_MWAIT_EMX     (1 << 0) /* enumeration supported */
 
+#ifndef HYPERV_SPINLOCK_NEVER_RETRY
+#define HYPERV_SPINLOCK_NEVER_RETRY             0xFFFFFFFF
+#endif
+
 #define EXCP00_DIVZ	0
 #define EXCP01_DB	1
 #define EXCP02_NMI	2
@@ -437,6 +593,17 @@
 #define EXCP_SYSCALL    0x100 /* only happens in user only emulation
                                  for syscall instruction */
 
+/* i386-specific interrupt pending bits.  */
+#define CPU_INTERRUPT_POLL      CPU_INTERRUPT_TGT_EXT_1
+#define CPU_INTERRUPT_SMI       CPU_INTERRUPT_TGT_EXT_2
+#define CPU_INTERRUPT_NMI       CPU_INTERRUPT_TGT_EXT_3
+#define CPU_INTERRUPT_MCE       CPU_INTERRUPT_TGT_EXT_4
+#define CPU_INTERRUPT_VIRQ      CPU_INTERRUPT_TGT_INT_0
+#define CPU_INTERRUPT_INIT      CPU_INTERRUPT_TGT_INT_1
+#define CPU_INTERRUPT_SIPI      CPU_INTERRUPT_TGT_INT_2
+#define CPU_INTERRUPT_TPR       CPU_INTERRUPT_TGT_INT_3
+
+
 enum {
     CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
     CC_OP_EFLAGS,  /* all cc are explicitly computed, CC_SRC = flags */
@@ -555,10 +722,23 @@
 #endif
 #define MMX_Q(n) q
 
+typedef union {
+    floatx80 d __attribute__((aligned(16)));
+    MMXReg mmx;
+} FPReg;
+
+typedef struct {
+    uint64_t base;
+    uint64_t mask;
+} MTRRVar;
+
+#define CPU_NB_REGS64 16
+#define CPU_NB_REGS32 8
+
 #ifdef TARGET_X86_64
-#define CPU_NB_REGS 16
+#define CPU_NB_REGS CPU_NB_REGS64
 #else
-#define CPU_NB_REGS 8
+#define CPU_NB_REGS CPU_NB_REGS32
 #endif
 
 #define NB_MMU_MODES 2
@@ -682,11 +862,6 @@
         uint64_t mask;
     } mtrr_var[8];
 
-#ifdef CONFIG_KQEMU
-    int kqemu_enabled;
-    int last_io_time;
-#endif
-
     /* For KVM */
     uint64_t interrupt_bitmap[256 / 64];
     uint32_t mp_state;
@@ -704,8 +879,7 @@
 CPUX86State *cpu_x86_init(const char *cpu_model);
 int cpu_x86_exec(CPUX86State *s);
 void cpu_x86_close(CPUX86State *s);
-void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
-                                                 ...));
+void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 int cpu_get_pic_interrupt(CPUX86State *s);
 /* MSDOS compatibility mode FPU exception support */
 void cpu_set_ferr(CPUX86State *s);
@@ -846,17 +1020,19 @@
 #define X86_DUMP_FPU  0x0001 /* dump FPU state too */
 #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
 
-#ifdef CONFIG_KQEMU
-static inline int cpu_get_time_fast(void)
-{
-    int low, high;
-    asm volatile("rdtsc" : "=a" (low), "=d" (high));
-    return low;
-}
-#endif
-
 #define TARGET_PAGE_BITS 12
 
+#ifdef TARGET_X86_64
+#define TARGET_PHYS_ADDR_SPACE_BITS 52
+/* ??? This is really 48 bits, sign-extended, but the only thing
+   accessible to userland with bit 48 set is the VSYSCALL, and that
+   is handled via other mechanisms.  */
+#define TARGET_VIRT_ADDR_SPACE_BITS 47
+#else
+#define TARGET_PHYS_ADDR_SPACE_BITS 36
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
+#endif
+
 #define cpu_init cpu_x86_init
 #define cpu_exec cpu_x86_exec
 #define cpu_gen_code cpu_x86_gen_code
@@ -869,7 +1045,7 @@
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _user
 #define MMU_USER_IDX 1
-static inline int cpu_mmu_index (CPUState *env)
+static inline int cpu_mmu_index (CPUX86State *env)
 {
     return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
 }
@@ -883,13 +1059,13 @@
 } CCTable;
 
 /* XXX not defined yet. Should be fixed */
-static inline int is_cpu_user(CPUState *env)
+static inline int is_cpu_user(CPUX86State *env)
 {
 	return 0;
 }
 
 #if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp)
 {
     if (newsp)
         env->regs[R_ESP] = newsp;
@@ -897,17 +1073,19 @@
 }
 #endif
 
-#include "exec/cpu-all.h"
+//#include "exec/cpu-all.h"
 #include "exec/exec-all.h"
 
+struct TranslationBlock;
+
 #include "svm.h"
 
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+static inline void cpu_pc_from_tb(CPUX86State *env, TranslationBlock *tb)
 {
     env->eip = tb->pc - tb->cs_base;
 }
 
-static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
     *cs_base = env->segs[R_CS].base;
@@ -916,8 +1094,8 @@
         (env->eflags & (IOPL_MASK | TF_MASK | RF_MASK | VM_MASK));
 }
 
-void apic_init_reset(CPUState *env);
-void apic_sipi(CPUState *env);
-void do_cpu_init(CPUState *env);
-void do_cpu_sipi(CPUState *env);
+void apic_init_reset(CPUX86State *env);
+void apic_sipi(CPUX86State *env);
+void do_cpu_init(CPUX86State *env);
+void do_cpu_sipi(CPUX86State *env);
 #endif /* CPU_I386_H */
diff --git a/target-i386/exec.h b/target-i386/exec.h
index 3adc0dd..d39f8de 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -338,7 +338,7 @@
 #endif
 }
 
-static inline int cpu_has_work(CPUState *env)
+static inline int cpu_has_work(CPUX86State *env)
 {
     int work;
 
@@ -351,7 +351,7 @@
     return work;
 }
 
-static inline int cpu_halted(CPUState *env) {
+static inline int cpu_halted(CPUX86State *env) {
     /* handle exit of HALTED state */
     if (!env->halted)
         return 0;
@@ -365,7 +365,7 @@
 
 /* load efer and update the corresponding hflags. XXX: do consistency
    checks with cpuid bits ? */
-static inline void cpu_load_efer(CPUState *env, uint64_t val)
+static inline void cpu_load_efer(CPUX86State *env, uint64_t val)
 {
     env->efer = val;
     env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK);
diff --git a/target-i386/hax-all.c b/target-i386/hax-all.c
index 861d194..ef77eb5 100644
--- a/target-i386/hax-all.c
+++ b/target-i386/hax-all.c
@@ -40,12 +40,12 @@
 }
 
 /* Currently non-PG modes are emulated by QEMU */
-int hax_vcpu_emulation_mode(CPUState *env)
+int hax_vcpu_emulation_mode(CPUX86State *env)
 {
     return !(env->cr[0] & CR0_PG_MASK);
 }
 
-static int hax_prepare_emulation(CPUState *env)
+static int hax_prepare_emulation(CPUX86State *env)
 {
     /* Flush all emulation states */
     tlb_flush(env, 1);
@@ -59,7 +59,7 @@
  * Check whether to break the translation block loop
  * Break tbloop after one MMIO emulation, or after finish emulation mode
  */
-static int hax_stop_tbloop(CPUState *env)
+static int hax_stop_tbloop(CPUX86State *env)
 {
     switch (env->hax_vcpu->emulation_state)
     {
@@ -79,7 +79,7 @@
     return 0;
 }
 
-int hax_stop_emulation(CPUState *env)
+int hax_stop_emulation(CPUX86State *env)
 {
     if (hax_stop_tbloop(env))
     {
@@ -95,7 +95,7 @@
     return 0;
 }
 
-int hax_stop_translate(CPUState *env)
+int hax_stop_translate(CPUX86State *env)
 {
     struct hax_vcpu_state *vstate;
 
@@ -112,7 +112,7 @@
     return size >= sizeof(struct hax_tunnel);
 }
 
-hax_fd hax_vcpu_get_fd(CPUState *env)
+hax_fd hax_vcpu_get_fd(CPUX86State *env)
 {
     struct hax_vcpu_state *vcpu = env->hax_vcpu;
     if (!vcpu)
@@ -234,7 +234,7 @@
     return -1;
 }
 
-int hax_vcpu_destroy(CPUState *env)
+int hax_vcpu_destroy(CPUX86State *env)
 {
     struct hax_vcpu_state *vcpu = env->hax_vcpu;
 
@@ -257,7 +257,7 @@
     return 0;
 }
 
-int hax_init_vcpu(CPUState *env)
+int hax_init_vcpu(CPUX86State *env)
 {
     int ret;
 
@@ -396,7 +396,7 @@
     return ret;
 }
 
-int  hax_handle_fastmmio(CPUState *env, struct hax_fastmmio *hft)
+int  hax_handle_fastmmio(CPUX86State *env, struct hax_fastmmio *hft)
 {
     uint64_t buf = 0;
 
@@ -421,7 +421,7 @@
     return 0;
 }
 
-int hax_handle_io(CPUState *env, uint32_t df, uint16_t port, int direction,
+int hax_handle_io(CPUX86State *env, uint32_t df, uint16_t port, int direction,
   int size, int count, void *buffer)
 {
     uint8_t *ptr;
@@ -467,7 +467,7 @@
     return 0;
 }
 
-static int hax_vcpu_interrupt(CPUState *env)
+static int hax_vcpu_interrupt(CPUX86State *env)
 {
     struct hax_vcpu_state *vcpu = env->hax_vcpu;
     struct hax_tunnel *ht = vcpu->tunnel;
@@ -501,7 +501,7 @@
     return 0;
 }
 
-void hax_raise_event(CPUState *env)
+void hax_raise_event(CPUX86State *env)
 {
     struct hax_vcpu_state *vcpu = env->hax_vcpu;
 
@@ -521,7 +521,7 @@
  * 5. An unknown VMX-exit happens
  */
 extern void qemu_system_reset_request(void);
-static int hax_vcpu_hax_exec(CPUState *env)
+static int hax_vcpu_hax_exec(CPUX86State *env)
 {
     int ret = 0;
     struct hax_vcpu_state *vcpu = env->hax_vcpu;
@@ -624,7 +624,7 @@
 /*
  * return 1 when need to emulate, 0 when need to exit loop
  */
-int hax_vcpu_exec(CPUState *env)
+int hax_vcpu_exec(CPUX86State *env)
 {
     int next = 0, ret = 0;
     struct hax_vcpu_state *vcpu;
@@ -721,7 +721,7 @@
 }
 
 /* The sregs has been synced with HAX kernel already before this call */
-static int hax_get_segments(CPUState *env, struct vcpu_state_t *sregs)
+static int hax_get_segments(CPUX86State *env, struct vcpu_state_t *sregs)
 {
     get_seg(&env->segs[R_CS], &sregs->_cs);
     get_seg(&env->segs[R_DS], &sregs->_ds);
@@ -739,7 +739,7 @@
     return 0;
 }
 
-static int hax_set_segments(CPUState *env, struct vcpu_state_t *sregs)
+static int hax_set_segments(CPUX86State *env, struct vcpu_state_t *sregs)
 {
     if ((env->eflags & VM_MASK)) {
         set_v8086_seg(&sregs->_cs, &env->segs[R_CS]);
@@ -777,7 +777,7 @@
  * After get the state from the kernel module, some
  * qemu emulator state need be updated also
  */
-static int hax_setup_qemu_emulator(CPUState *env)
+static int hax_setup_qemu_emulator(CPUX86State *env)
 {
 
 #define HFLAG_COPY_MASK ~( \
@@ -822,7 +822,7 @@
     return 0;
 }
 
-static int hax_sync_vcpu_register(CPUState *env, int set)
+static int hax_sync_vcpu_register(CPUX86State *env, int set)
 {
     struct vcpu_state_t regs;
     int ret;
@@ -884,7 +884,7 @@
     item->value = value;
 }
 
-static int hax_get_msrs(CPUState *env)
+static int hax_get_msrs(CPUX86State *env)
 {
     struct hax_msr_data md;
     struct vmx_msr *msrs = md.entries;
@@ -920,7 +920,7 @@
     return 0;
 }
 
-static int hax_set_msrs(CPUState *env)
+static int hax_set_msrs(CPUX86State *env)
 {
     struct hax_msr_data md;
     struct vmx_msr *msrs;
@@ -939,7 +939,7 @@
 
 }
 
-static int hax_get_fpu(CPUState *env)
+static int hax_get_fpu(CPUX86State *env)
 {
     struct fx_layout fpu;
     int i, ret;
@@ -962,7 +962,7 @@
     return 0;
 }
 
-static int hax_set_fpu(CPUState *env)
+static int hax_set_fpu(CPUX86State *env)
 {
     struct fx_layout fpu;
     int i;
@@ -984,7 +984,7 @@
     return hax_sync_fpu(env, &fpu, 1);
 }
 
-int hax_arch_get_registers(CPUState *env)
+int hax_arch_get_registers(CPUX86State *env)
 {
     int ret;
 
@@ -1003,7 +1003,7 @@
     return 0;
 }
 
-static int hax_arch_set_registers(CPUState *env)
+static int hax_arch_set_registers(CPUX86State *env)
 {
     int ret;
     ret = hax_sync_vcpu_register(env, 1);
@@ -1029,7 +1029,7 @@
     return 0;
 }
 
-void hax_vcpu_sync_state(CPUState *env, int modified)
+void hax_vcpu_sync_state(CPUX86State *env, int modified)
 {
     if (hax_enabled()) {
         if (modified)
@@ -1047,7 +1047,7 @@
 {
     if (hax_enabled())
     {
-        CPUState *env;
+        CPUX86State *env;
 
         env = first_cpu;
         if (!env)
@@ -1070,7 +1070,7 @@
 
 void hax_reset_vcpu_state(void *opaque)
 {
-    CPUState *env;
+    CPUX86State *env;
     for (env = first_cpu; env != NULL; env = env->next_cpu)
     {
         if (env->hax_vcpu)
diff --git a/target-i386/hax-darwin.c b/target-i386/hax-darwin.c
index 8743607..ca4477d 100644
--- a/target-i386/hax-darwin.c
+++ b/target-i386/hax-darwin.c
@@ -265,7 +265,7 @@
     return ret;
 }
 
-int hax_sync_fpu(CPUState *env, struct fx_layout *fl, int set)
+int hax_sync_fpu(CPUX86State *env, struct fx_layout *fl, int set)
 {
     int ret, fd;
 
@@ -280,7 +280,7 @@
     return ret;
 }
 
-int hax_sync_msr(CPUState *env, struct hax_msr_data *msrs, int set)
+int hax_sync_msr(CPUX86State *env, struct hax_msr_data *msrs, int set)
 {
     int ret, fd;
 
@@ -294,7 +294,7 @@
     return ret;
 }
 
-int hax_sync_vcpu_state(CPUState *env, struct vcpu_state_t *state, int set)
+int hax_sync_vcpu_state(CPUX86State *env, struct vcpu_state_t *state, int set)
 {
     int ret, fd;
 
@@ -309,7 +309,7 @@
     return ret;
 }
 
-int hax_inject_interrupt(CPUState *env, int vector)
+int hax_inject_interrupt(CPUX86State *env, int vector)
 {
     int ret, fd;
 
diff --git a/target-i386/hax-i386.h b/target-i386/hax-i386.h
index 8e47a4b..3dd91a0 100644
--- a/target-i386/hax-i386.h
+++ b/target-i386/hax-i386.h
@@ -55,18 +55,18 @@
 };
 
 /* Functions exported to host specific mode */
-hax_fd hax_vcpu_get_fd(CPUState *env);
+hax_fd hax_vcpu_get_fd(CPUX86State *env);
 int valid_hax_tunnel_size(uint16_t size);
 
 /* Host specific functions */
 int hax_mod_version(struct hax_state *hax, struct hax_module_version *version);
-int hax_inject_interrupt(CPUState *env, int vector);
+int hax_inject_interrupt(CPUX86State *env, int vector);
 struct hax_vm *hax_vm_create(struct hax_state *hax);
 int hax_vcpu_run(struct hax_vcpu_state *vcpu);
 int hax_vcpu_create(int id);
-int hax_sync_vcpu_state(CPUState *env, struct vcpu_state_t *state, int set);
-int hax_sync_msr(CPUState *env, struct hax_msr_data *msrs, int set);
-int hax_sync_fpu(CPUState *env, struct fx_layout *fl, int set);
+int hax_sync_vcpu_state(CPUX86State *env, struct vcpu_state_t *state, int set);
+int hax_sync_msr(CPUX86State *env, struct hax_msr_data *msrs, int set);
+int hax_sync_fpu(CPUX86State *env, struct fx_layout *fl, int set);
 int hax_vm_destroy(struct hax_vm *vm);
 int hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap);
 int hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion);
diff --git a/target-i386/hax-windows.c b/target-i386/hax-windows.c
index bccbd0a..46d6bf6 100644
--- a/target-i386/hax-windows.c
+++ b/target-i386/hax-windows.c
@@ -398,7 +398,7 @@
         return 0;
 }
 
-int hax_sync_fpu(CPUState *env, struct fx_layout *fl, int set)
+int hax_sync_fpu(CPUX86State *env, struct fx_layout *fl, int set)
 {
     int ret;
     hax_fd fd;
@@ -431,7 +431,7 @@
         return 0;
 }
 
-int hax_sync_msr(CPUState *env, struct hax_msr_data *msrs, int set)
+int hax_sync_msr(CPUX86State *env, struct hax_msr_data *msrs, int set)
 {
     int ret;
     hax_fd fd;
@@ -463,7 +463,7 @@
         return 0;
 }
 
-int hax_sync_vcpu_state(CPUState *env, struct vcpu_state_t *state, int set)
+int hax_sync_vcpu_state(CPUX86State *env, struct vcpu_state_t *state, int set)
 {
     int ret;
     hax_fd fd;
@@ -496,7 +496,7 @@
         return 0;
 }
 
-int hax_inject_interrupt(CPUState *env, int vector)
+int hax_inject_interrupt(CPUX86State *env, int vector)
 {
     int ret;
     hax_fd fd;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index daee391..c03412a 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -598,7 +598,7 @@
 };
 
 static void
-cpu_x86_dump_seg_cache(CPUState *env, FILE *f,
+cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f,
                        int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                        const char *name, struct SegmentCache *sc)
 {
@@ -652,7 +652,7 @@
     cpu_fprintf(f, "\n");
 }
 
-void cpu_dump_state(CPUState *env, FILE *f,
+void cpu_dump_state(CPUX86State *env, FILE *f,
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                     int flags)
 {
@@ -953,7 +953,7 @@
     return 1;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+hwaddr cpu_get_phys_page_debug(CPUX86State *env, target_ulong addr)
 {
     return addr;
 }
@@ -962,14 +962,10 @@
 
 /* XXX: This value should match the one returned by CPUID
  * and in exec.c */
-#if defined(CONFIG_KQEMU)
-#define PHYS_ADDR_MASK 0xfffff000LL
-#else
-# if defined(TARGET_X86_64)
+#if defined(TARGET_X86_64)
 # define PHYS_ADDR_MASK 0xfffffff000LL
-# else
+#else
 # define PHYS_ADDR_MASK 0xffffff000LL
-# endif
 #endif
 
 /* return value:
@@ -1268,7 +1264,7 @@
     return 1;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+hwaddr cpu_get_phys_page_debug(CPUX86State *env, target_ulong addr)
 {
     target_ulong pde_addr, pte_addr;
     uint64_t pte;
@@ -1362,7 +1358,7 @@
     return paddr;
 }
 
-void hw_breakpoint_insert(CPUState *env, int index)
+void hw_breakpoint_insert(CPUX86State *env, int index)
 {
     int type, err = 0;
 
@@ -1390,7 +1386,7 @@
         env->cpu_breakpoint[index] = NULL;
 }
 
-void hw_breakpoint_remove(CPUState *env, int index)
+void hw_breakpoint_remove(CPUX86State *env, int index)
 {
     if (!env->cpu_breakpoint[index])
         return;
@@ -1409,7 +1405,7 @@
     }
 }
 
-int check_hw_breakpoints(CPUState *env, int force_dr6_update)
+int check_hw_breakpoints(CPUX86State *env, int force_dr6_update)
 {
     target_ulong dr6;
     int reg, type;
@@ -1435,7 +1431,7 @@
 
 void raise_exception(int exception_index);
 
-static void breakpoint_handler(CPUState *env)
+static void breakpoint_handler(CPUX86State *env)
 {
     CPUBreakpoint *bp;
 
@@ -1465,7 +1461,7 @@
 /* This should come from sysemu.h - if we could include it here... */
 void qemu_system_reset_request(void);
 
-void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
+void cpu_inject_x86_mce(CPUX86State *cenv, int bank, uint64_t status,
                         uint64_t mcg_status, uint64_t addr, uint64_t misc)
 {
     uint64_t mcg_cap = cenv->mcg_cap;
@@ -1739,21 +1735,13 @@
 /* XXX: This value must match the one used in the MMU code. */ 
         if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
             /* 64 bit processor */
-#if defined(CONFIG_KQEMU)
-            *eax = 0x00003020;	/* 48 bits virtual, 32 bits physical */
-#else
 /* XXX: The physical address space is limited to 42 bits in exec.c. */
             *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */
-#endif
         } else {
-#if defined(CONFIG_KQEMU)
-            *eax = 0x00000020;	/* 32 bits physical */
-#else
             if (env->cpuid_features & CPUID_PSE36)
                 *eax = 0x00000024; /* 36 bits physical */
             else
                 *eax = 0x00000020; /* 32 bits physical */
-#endif
         }
         *ebx = 0;
         *ecx = 0;
@@ -1799,9 +1787,6 @@
     }
     mce_init(env);
     cpu_reset(env);
-#ifdef CONFIG_KQEMU
-    kqemu_init(env);
-#endif
 
     qemu_init_vcpu(env);
 
@@ -1824,7 +1809,7 @@
 }
 
 #if !defined(CONFIG_USER_ONLY)
-void do_cpu_init(CPUState *env)
+void do_cpu_init(CPUX86State *env)
 {
     int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
     cpu_reset(env);
@@ -1832,15 +1817,15 @@
     apic_init_reset(env);
 }
 
-void do_cpu_sipi(CPUState *env)
+void do_cpu_sipi(CPUX86State *env)
 {
     apic_sipi(env);
 }
 #else
-void do_cpu_init(CPUState *env)
+void do_cpu_init(CPUX86State *env)
 {
 }
-void do_cpu_sipi(CPUState *env)
+void do_cpu_sipi(CPUX86State *env)
 {
 }
 #endif
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 2d55144..609eb6e 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -67,7 +67,7 @@
     return cpuid;
 }
 
-uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg)
+uint32_t kvm_arch_get_supported_cpuid(CPUX86State *env, uint32_t function, int reg)
 {
     struct kvm_cpuid2 *cpuid;
     int i, max;
@@ -116,7 +116,7 @@
 
 #else
 
-uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg)
+uint32_t kvm_arch_get_supported_cpuid(CPUX86State *env, uint32_t function, int reg)
 {
     return -1U;
 }
@@ -127,7 +127,7 @@
 #define KVM_MP_STATE_RUNNABLE 0
 #endif
 
-int kvm_arch_init_vcpu(CPUState *env)
+int kvm_arch_init_vcpu(CPUX86State *env)
 {
     struct {
         struct kvm_cpuid2 cpuid;
@@ -205,7 +205,7 @@
     return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data);
 }
 
-static int kvm_has_msr_star(CPUState *env)
+static int kvm_has_msr_star(CPUX86State *env)
 {
     static int has_msr_star;
     int ret;
@@ -327,7 +327,7 @@
         *qemu_reg = *kvm_reg;
 }
 
-static int kvm_getput_regs(CPUState *env, int set)
+static int kvm_getput_regs(CPUX86State *env, int set)
 {
     struct kvm_regs regs;
     int ret = 0;
@@ -366,7 +366,7 @@
     return ret;
 }
 
-static int kvm_put_fpu(CPUState *env)
+static int kvm_put_fpu(CPUX86State *env)
 {
     struct kvm_fpu fpu;
     int i;
@@ -384,7 +384,7 @@
     return kvm_vcpu_ioctl(env, KVM_SET_FPU, &fpu);
 }
 
-static int kvm_put_sregs(CPUState *env)
+static int kvm_put_sregs(CPUX86State *env)
 {
     struct kvm_sregs sregs;
 
@@ -443,7 +443,7 @@
     entry->data = value;
 }
 
-static int kvm_put_msrs(CPUState *env)
+static int kvm_put_msrs(CPUX86State *env)
 {
     struct {
         struct kvm_msrs info;
@@ -472,7 +472,7 @@
 }
 
 
-static int kvm_get_fpu(CPUState *env)
+static int kvm_get_fpu(CPUX86State *env)
 {
     struct kvm_fpu fpu;
     int i, ret;
@@ -493,7 +493,7 @@
     return 0;
 }
 
-int kvm_get_sregs(CPUState *env)
+int kvm_get_sregs(CPUX86State *env)
 {
     struct kvm_sregs sregs;
     uint32_t hflags;
@@ -575,7 +575,7 @@
     return 0;
 }
 
-static int kvm_get_msrs(CPUState *env)
+static int kvm_get_msrs(CPUX86State *env)
 {
     struct {
         struct kvm_msrs info;
@@ -640,7 +640,7 @@
     return 0;
 }
 
-int kvm_arch_put_registers(CPUState *env)
+int kvm_arch_put_registers(CPUX86State *env)
 {
     int ret;
 
@@ -671,7 +671,7 @@
     return 0;
 }
 
-int kvm_arch_get_registers(CPUState *env)
+int kvm_arch_get_registers(CPUX86State *env)
 {
     int ret;
 
@@ -694,7 +694,7 @@
     return 0;
 }
 
-int kvm_arch_vcpu_run(CPUState *env)
+int kvm_arch_vcpu_run(CPUX86State *env)
 {
 #ifdef CONFIG_KVM_GS_RESTORE
     if (gs_need_restore  != KVM_GS_RESTORE_NO)
@@ -704,7 +704,7 @@
         return kvm_vcpu_ioctl(env, KVM_RUN, 0);
 }
 
-int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
+int kvm_arch_pre_run(CPUX86State *env, struct kvm_run *run)
 {
     /* Try to inject an interrupt if the guest can accept it */
     if (run->ready_for_interrupt_injection &&
@@ -742,7 +742,7 @@
     return 0;
 }
 
-int kvm_arch_post_run(CPUState *env, struct kvm_run *run)
+int kvm_arch_post_run(CPUX86State *env, struct kvm_run *run)
 {
 #ifdef CONFIG_KVM_GS_RESTORE
     gs_base_post_run();
@@ -758,7 +758,7 @@
     return 0;
 }
 
-static int kvm_handle_halt(CPUState *env)
+static int kvm_handle_halt(CPUX86State *env)
 {
     if (!((env->interrupt_request & CPU_INTERRUPT_HARD) &&
           (env->eflags & IF_MASK)) &&
@@ -771,7 +771,7 @@
     return 1;
 }
 
-int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
+int kvm_arch_handle_exit(CPUX86State *env, struct kvm_run *run)
 {
     int ret = 0;
 
@@ -786,7 +786,7 @@
 }
 
 #ifdef KVM_CAP_SET_GUEST_DEBUG
-int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
+int kvm_arch_insert_sw_breakpoint(CPUX86State *env, struct kvm_sw_breakpoint *bp)
 {
     const static uint8_t int3 = 0xcc;
 
@@ -796,7 +796,7 @@
     return 0;
 }
 
-int kvm_arch_remove_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
+int kvm_arch_remove_sw_breakpoint(CPUX86State *env, struct kvm_sw_breakpoint *bp)
 {
     uint8_t int3;
 
@@ -928,7 +928,7 @@
     return handle;
 }
 
-void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
+void kvm_arch_update_guest_debug(CPUX86State *env, struct kvm_guest_debug *dbg)
 {
     const uint8_t type_code[] = {
         [GDB_BREAKPOINT_HW] = 0x0,
diff --git a/target-i386/machine.c b/target-i386/machine.c
index bca12c6..58a87f1 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -24,7 +24,7 @@
 
 void cpu_save(QEMUFile *f, void *opaque)
 {
-    CPUState *env = opaque;
+    CPUX86State *env = opaque;
     uint16_t fptag, fpus, fpuc, fpregs_format;
     uint32_t hflags;
     int32_t a20_mask;
@@ -187,7 +187,7 @@
 
 int cpu_load(QEMUFile *f, void *opaque, int version_id)
 {
-    CPUState *env = opaque;
+    CPUX86State *env = opaque;
     int i, guess_mmx;
     uint32_t hflags;
     uint16_t fpus, fpuc, fptag, fpregs_format;
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index a217dfc..0488d2b 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -1113,14 +1113,6 @@
         env->eflags |= IF_MASK;
         cpu_x86_set_cpl(env, 3);
     }
-#ifdef CONFIG_KQEMU
-    if (kqemu_is_ok(env)) {
-        if (env->hflags & HF_LMA_MASK)
-            CC_OP = CC_OP_EFLAGS;
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
 }
 #endif
 
@@ -2508,12 +2500,6 @@
         SET_ESP(sp, sp_mask);
         EIP = offset;
     }
-#ifdef CONFIG_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
 }
 
 /* real and vm86 mode iret */
@@ -2794,24 +2780,11 @@
         helper_ret_protected(shift, 1, 0);
     }
     env->hflags2 &= ~HF2_NMI_MASK;
-#ifdef CONFIG_KQEMU
-    if (kqemu_is_ok(env)) {
-        CC_OP = CC_OP_EFLAGS;
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
 }
 
 void helper_lret_protected(int shift, int addend)
 {
     helper_ret_protected(shift, 0, addend);
-#ifdef CONFIG_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
 }
 
 void helper_sysenter(void)
@@ -2884,12 +2857,6 @@
     }
     ESP = ECX;
     EIP = EDX;
-#ifdef CONFIG_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
 }
 
 #if defined(CONFIG_USER_ONLY)
@@ -3213,15 +3180,6 @@
         val = env->kernelgsbase;
         break;
 #endif
-#ifdef CONFIG_KQEMU
-    case MSR_QPI_COMMBASE:
-        if (env->kqemu_enabled) {
-            val = kqemu_comm_base;
-        } else {
-            val = 0;
-        }
-        break;
-#endif
     case MSR_MTRRphysBase(0):
     case MSR_MTRRphysBase(1):
     case MSR_MTRRphysBase(2):
@@ -4924,7 +4882,7 @@
 }
 
 static inline void svm_load_seg_cache(hwaddr addr,
-                                      CPUState *env, int seg_reg)
+                                      CPUX86State *env, int seg_reg)
 {
     SegmentCache sc1, *sc = &sc1;
     svm_load_seg(addr, sc);
diff --git a/target-i386/translate.c b/target-i386/translate.c
index c1c3afe..78552ec 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -276,29 +276,29 @@
     switch(ot) {
     case OT_BYTE:
         if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
-            tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_B_OFFSET);
+            tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_B_OFFSET);
         } else {
-            tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUState, regs[reg - 4]) + REG_H_OFFSET);
+            tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg - 4]) + REG_H_OFFSET);
         }
         break;
     case OT_WORD:
-        tcg_gen_st16_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
+        tcg_gen_st16_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET);
         break;
 #ifdef TARGET_X86_64
     case OT_LONG:
-        tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+        tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
         /* high part of register set to zero */
         tcg_gen_movi_tl(cpu_tmp0, 0);
-        tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
+        tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_LH_OFFSET);
         break;
     default:
     case OT_QUAD:
-        tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_st_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]));
         break;
 #else
     default:
     case OT_LONG:
-        tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+        tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
         break;
 #endif
     }
@@ -318,23 +318,23 @@
 {
     switch(size) {
     case 0:
-        tcg_gen_st16_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
+        tcg_gen_st16_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET);
         break;
 #ifdef TARGET_X86_64
     case 1:
-        tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+        tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
         /* high part of register set to zero */
         tcg_gen_movi_tl(cpu_tmp0, 0);
-        tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
+        tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_LH_OFFSET);
         break;
     default:
     case 2:
-        tcg_gen_st_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_st_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]));
         break;
 #else
     default:
     case 1:
-        tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+        tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
         break;
 #endif
     }
@@ -347,12 +347,12 @@
         if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
             goto std_case;
         } else {
-            tcg_gen_ld8u_tl(t0, cpu_env, offsetof(CPUState, regs[reg - 4]) + REG_H_OFFSET);
+            tcg_gen_ld8u_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg - 4]) + REG_H_OFFSET);
         }
         break;
     default:
     std_case:
-        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]));
         break;
     }
 }
@@ -364,7 +364,7 @@
 
 static inline void gen_op_movl_A0_reg(int reg)
 {
-    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
 }
 
 static inline void gen_op_addl_A0_im(int32_t val)
@@ -399,30 +399,30 @@
 
 static inline void gen_op_jmp_T0(void)
 {
-    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip));
+    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, eip));
 }
 
 static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
 {
     switch(size) {
     case 0:
-        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
         tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
-        tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
+        tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET);
         break;
     case 1:
-        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
         tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
 #ifdef TARGET_X86_64
         tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
 #endif
-        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
         break;
 #ifdef TARGET_X86_64
     case 2:
-        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
         tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
-        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
         break;
 #endif
     }
@@ -432,23 +432,23 @@
 {
     switch(size) {
     case 0:
-        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
         tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
-        tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
+        tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET);
         break;
     case 1:
-        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
         tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
 #ifdef TARGET_X86_64
         tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
 #endif
-        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
         break;
 #ifdef TARGET_X86_64
     case 2:
-        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
         tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
-        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
         break;
 #endif
     }
@@ -461,7 +461,7 @@
 
 static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
 {
-    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
     if (shift != 0)
         tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
@@ -472,12 +472,12 @@
 
 static inline void gen_op_movl_A0_seg(int reg)
 {
-    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base) + REG_L_OFFSET);
+    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base) + REG_L_OFFSET);
 }
 
 static inline void gen_op_addl_A0_seg(int reg)
 {
-    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
 #ifdef TARGET_X86_64
     tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
@@ -487,23 +487,23 @@
 #ifdef TARGET_X86_64
 static inline void gen_op_movq_A0_seg(int reg)
 {
-    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base));
+    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base));
 }
 
 static inline void gen_op_addq_A0_seg(int reg)
 {
-    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
 }
 
 static inline void gen_op_movq_A0_reg(int reg)
 {
-    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]));
+    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]));
 }
 
 static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
 {
-    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
     if (shift != 0)
         tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
@@ -602,7 +602,7 @@
 static inline void gen_jmp_im(target_ulong pc)
 {
     tcg_gen_movi_tl(cpu_tmp0, pc);
-    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip));
+    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, eip));
 }
 
 static inline void gen_string_movl_A0_ESI(DisasContext *s)
@@ -663,7 +663,7 @@
 
 static inline void gen_op_movl_T0_Dshift(int ot)
 {
-    tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUState, df));
+    tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, df));
     tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
 };
 
@@ -703,14 +703,14 @@
 
 static inline void gen_op_jnz_ecx(int size, int label1)
 {
-    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ECX]));
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[R_ECX]));
     gen_extu(size + 1, cpu_tmp0);
     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
 }
 
 static inline void gen_op_jz_ecx(int size, int label1)
 {
-    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ECX]));
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[R_ECX]));
     gen_extu(size + 1, cpu_tmp0);
     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
 }
@@ -4838,7 +4838,7 @@
                 rm = 0; /* avoid warning */
             }
             label1 = gen_new_label();
-            tcg_gen_ld_tl(t2, cpu_env, offsetof(CPUState, regs[R_EAX]));
+            tcg_gen_ld_tl(t2, cpu_env, offsetof(CPUX86State, regs[R_EAX]));
             tcg_gen_sub_tl(t2, t2, t0);
             gen_extu(ot, t2);
             tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
@@ -5413,7 +5413,7 @@
             val = ldub_code(s->pc++);
             tcg_gen_movi_tl(cpu_T3, val);
         } else {
-            tcg_gen_ld_tl(cpu_T3, cpu_env, offsetof(CPUState, regs[R_ECX]));
+            tcg_gen_ld_tl(cpu_T3, cpu_env, offsetof(CPUX86State, regs[R_ECX]));
         }
         gen_shiftd_rm_T1_T3(s, ot, opreg, op);
         break;
@@ -6321,10 +6321,10 @@
                 /* XXX: specific Intel behaviour ? */
                 l1 = gen_new_label();
                 gen_jcc1(s, s->cc_op, b ^ 1, l1);
-                tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+                tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
                 gen_set_label(l1);
                 tcg_gen_movi_tl(cpu_tmp0, 0);
-                tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
+                tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_LH_OFFSET);
             } else
 #endif
             {
@@ -6435,11 +6435,11 @@
         break;
     case 0xfc: /* cld */
         tcg_gen_movi_i32(cpu_tmp2_i32, 1);
-        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
+        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
         break;
     case 0xfd: /* std */
         tcg_gen_movi_i32(cpu_tmp2_i32, -1);
-        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
+        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
         break;
 
         /************************/
@@ -7584,12 +7584,12 @@
 #endif
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
     cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
-                                       offsetof(CPUState, cc_op), "cc_op");
-    cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
+                                       offsetof(CPUX86State, cc_op), "cc_op");
+    cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src),
                                     "cc_src");
-    cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
+    cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),
                                     "cc_dst");
-    cpu_cc_tmp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_tmp),
+    cpu_cc_tmp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_tmp),
                                     "cc_tmp");
 
     /* register helpers */
@@ -7600,7 +7600,7 @@
 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
    basic block 'tb'. If search_pc is TRUE, also generate PC
    information for each intermediate instruction. */
-static inline void gen_intermediate_code_internal(CPUState *env,
+static inline void gen_intermediate_code_internal(CPUX86State *env,
                                                   TranslationBlock *tb,
                                                   int search_pc)
 {
@@ -7776,7 +7776,7 @@
         else
 #endif
             disas_flags = !dc->code32;
-        log_target_disas(pc_start, pc_ptr - pc_start, disas_flags);
+        log_target_disas(env, pc_start, pc_ptr - pc_start, disas_flags);
         qemu_log("\n");
     }
 #endif
@@ -7787,17 +7787,17 @@
     }
 }
 
-void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
+void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
 {
     gen_intermediate_code_internal(env, tb, 0);
 }
 
-void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
+void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb)
 {
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
+void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos)
 {
     int cc_op;
 #ifdef DEBUG_DISAS
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index edbc3bf..2107c54 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -1,13 +1,19 @@
 #if !defined (__MIPS_CPU_H__)
 #define __MIPS_CPU_H__
 
+//#define DEBUG_OP
+
 #define TARGET_HAS_ICE 1
 
 #define ELF_MACHINE	EM_MIPS
 
-#define CPUState struct CPUMIPSState
+// TODO(digit): Remove this define.
+#define CPUOldState struct CPUMIPSState
+
+#define CPUArchState struct CPUMIPSState
 
 #include "config.h"
+#include "qemu-common.h"
 #include "mips-defs.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
@@ -36,6 +42,7 @@
     target_ulong PFN[2];
 };
 
+#if !defined(CONFIG_USER_ONLY)
 typedef struct CPUMIPSTLBContext CPUMIPSTLBContext;
 struct CPUMIPSTLBContext {
     uint32_t nb_tlb;
@@ -50,6 +57,7 @@
         } r4k;
     } mmu;
 };
+#endif
 
 typedef union fpr_t fpr_t;
 union fpr_t {
@@ -59,7 +67,7 @@
     uint32_t w[2]; /* binary single fixed-point */
 };
 /* define FP_ENDIAN_IDX to access the same location
- * in the fpr_t union regardless of the host endianess
+ * in the fpr_t union regardless of the host endianness
  */
 #if defined(HOST_WORDS_BIGENDIAN)
 #  define FP_ENDIAN_IDX 1
@@ -360,6 +368,7 @@
 #define CP0C2_SA   0
     int32_t CP0_Config3;
 #define CP0C3_M    31
+#define CP0C3_ISA_ON_EXC 16
 #define CP0C3_DSPP 10
 #define CP0C3_LPA  7
 #define CP0C3_VEIC 6
@@ -411,7 +420,7 @@
     /* 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 */
@@ -458,7 +467,9 @@
     CPU_COMMON
 
     CPUMIPSMVPContext *mvp;
+#if !defined(CONFIG_USER_ONLY)
     CPUMIPSTLBContext *tlb;
+#endif
 
     const mips_def_t *cpu_model;
     void *irq[8];
@@ -488,18 +499,21 @@
 
 #define CPU_SAVE_VERSION 3
 
+// NOTE(digit): Came from cpu-all.h, to be removed later.
+#define CPU_INTERRUPT_TIMER  0x08 /* internal timer exception pending */
+
 /* MMU modes definitions. We carefully match the indices with our
    hflags layout. */
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _super
 #define MMU_MODE2_SUFFIX _user
 #define MMU_USER_IDX 2
-static inline int cpu_mmu_index (CPUState *env)
+static inline int cpu_mmu_index (CPUMIPSState *env)
 {
     return env->hflags & MIPS_HFLAG_KSU;
 }
 
-static inline int is_cpu_user (CPUState *env)
+static inline int is_cpu_user (CPUMIPSState *env)
 {
 #ifdef CONFIG_USER_ONLY
     return 1;
@@ -509,7 +523,7 @@
 #endif  // CONFIG_USER_ONLY
 }
 
-static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUMIPSState *env, target_ulong newsp)
 {
     if (newsp)
         env->active_tc.gpr[29] = newsp;
@@ -517,7 +531,7 @@
     env->active_tc.gpr[2] = 0;
 }
 
-static inline int cpu_mips_hw_interrupts_pending(CPUState *env)
+static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
 {
     int32_t pending;
     int32_t status;
@@ -608,38 +622,46 @@
 /* Dummy exception for conditional stores.  */
 #define EXCP_SC 0x100
 
+/*
+ * This is an interrnally generated WAKE request line.
+ * It is driven by the CPU itself. Raised when the MT
+ * block wants to wake a VPE from an inactive state and
+ * cleared when VPE goes from active to inactive.
+ */
+#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
+
 int cpu_mips_exec(CPUMIPSState *s);
 CPUMIPSState *cpu_mips_init(const char *cpu_model);
 //~ uint32_t cpu_mips_get_clock (void);
 int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
 
 /* mips_timer.c */
-uint32_t cpu_mips_get_random (CPUState *env);
-uint32_t cpu_mips_get_count (CPUState *env);
-void cpu_mips_store_count (CPUState *env, uint32_t value);
-void cpu_mips_store_compare (CPUState *env, uint32_t value);
-void cpu_mips_start_count(CPUState *env);
-void cpu_mips_stop_count(CPUState *env);
+uint32_t cpu_mips_get_random (CPUMIPSState *env);
+uint32_t cpu_mips_get_count (CPUMIPSState *env);
+void cpu_mips_store_count (CPUMIPSState *env, uint32_t value);
+void cpu_mips_store_compare (CPUMIPSState *env, uint32_t value);
+void cpu_mips_start_count(CPUMIPSState *env);
+void cpu_mips_stop_count(CPUMIPSState *env);
 
 /* mips_int.c */
-void cpu_mips_update_irq (CPUState *env);
+void cpu_mips_update_irq (CPUMIPSState *env);
 
 /* helper.c */
-int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
+int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
                                int mmu_idx, int is_softmmu);
 #define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault
-void do_interrupt (CPUState *env);
-hwaddr cpu_mips_translate_address (CPUState *env, target_ulong address,
+void do_interrupt (CPUMIPSState *env);
+hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address,
 		                               int rw);
 
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+static inline void cpu_pc_from_tb(CPUMIPSState *env, TranslationBlock *tb)
 {
     env->active_tc.PC = tb->pc;
     env->hflags &= ~MIPS_HFLAG_BMASK;
     env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
 }
 
-static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
     *pc = env->active_tc.PC;
@@ -647,7 +669,7 @@
     *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
 }
 
-static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
+static inline void cpu_set_tls(CPUMIPSState *env, target_ulong newtls)
 {
     env->tls_value = newtls;
 }
diff --git a/target-mips/exec.h b/target-mips/exec.h
index 3590748..a64fe65 100644
--- a/target-mips/exec.h
+++ b/target-mips/exec.h
@@ -17,13 +17,13 @@
 #include "exec/softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-void dump_fpu(CPUState *env);
-void fpu_dump_state(CPUState *env, FILE *f,
+void dump_fpu(CPUMIPSState *env);
+void fpu_dump_state(CPUMIPSState *env, FILE *f,
                     int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
                     int flags);
 
-void cpu_mips_clock_init (CPUState *env);
-void cpu_mips_tlb_flush (CPUState *env, int flush_global);
+void cpu_mips_clock_init (CPUMIPSState *env);
+void cpu_mips_tlb_flush (CPUMIPSState *env, int flush_global);
 
 static inline void env_to_regs(void)
 {
@@ -33,7 +33,7 @@
 {
 }
 
-static inline int cpu_has_work(CPUState *env)
+static inline int cpu_has_work(CPUMIPSState *env)
 {
     int has_work = 0;
 
@@ -52,7 +52,7 @@
     return has_work;
 }
 
-static inline int cpu_halted(CPUState *env)
+static inline int cpu_halted(CPUMIPSState *env)
 {
     if (!env->halted)
         return 0;
@@ -63,7 +63,7 @@
     return EXCP_HALTED;
 }
 
-static inline void compute_hflags(CPUState *env)
+static inline void compute_hflags(CPUMIPSState *env)
 {
     env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
                      MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 7de79d1..94cd742 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -35,7 +35,7 @@
 };
 
 /* no MMU emulation */
-int no_mmu_map_address (CPUState *env, hwaddr *physical, int *prot,
+int no_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
                         target_ulong address, int rw, int access_type)
 {
     *physical = address;
@@ -44,7 +44,7 @@
 }
 
 /* fixed mapping MMU emulation */
-int fixed_mmu_map_address (CPUState *env, hwaddr *physical, int *prot,
+int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
                            target_ulong address, int rw, int access_type)
 {
     if (address <= (int32_t)0x7FFFFFFFUL) {
@@ -62,7 +62,7 @@
 }
 
 /* MIPS32/MIPS64 R4000-style MMU emulation */
-int r4k_map_address (CPUState *env, hwaddr *physical, int *prot,
+int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
                      target_ulong address, int rw, int access_type)
 {
     uint8_t ASID = env->CP0_EntryHi & 0xFF;
@@ -105,7 +105,7 @@
 }
 
 #if !defined(CONFIG_USER_ONLY)
-static int get_physical_address (CPUState *env, hwaddr *physical,
+static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
                                 int *prot, target_ulong address,
                                 int rw, int access_type)
 {
@@ -207,7 +207,7 @@
 }
 #endif
 
-static void raise_mmu_exception(CPUState *env, target_ulong address,
+static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
                                 int rw, int tlb_error)
 {
     int exception = 0, error_code = 0;
@@ -269,7 +269,7 @@
     int softshift;
 } linux_pte_info = {0};
 
-static inline target_ulong cpu_mips_get_pgd(CPUState *env)
+static inline target_ulong cpu_mips_get_pgd(CPUMIPSState *env)
 {
     if (unlikely(linux_pte_info.pgd_current_p == 0)) {
         int i;
@@ -341,9 +341,9 @@
 }
 
 // in target-mips/op_helper.c
-extern void r4k_helper_ptw_tlbrefill(CPUState*);
+extern void r4k_helper_ptw_tlbrefill(CPUMIPSState*);
 
-static inline int cpu_mips_tlb_refill(CPUState *env, target_ulong address, int rw ,
+static inline int cpu_mips_tlb_refill(CPUMIPSState *env, target_ulong address, int rw ,
                                       int mmu_idx, int is_softmmu)
 {
     int32_t saved_hflags;
@@ -436,7 +436,7 @@
     return ret;
 }
 
-int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
+int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
                                int mmu_idx, int is_softmmu)
 {
 #if !defined(CONFIG_USER_ONLY)
@@ -484,7 +484,7 @@
 }
 
 #if !defined(CONFIG_USER_ONLY)
-hwaddr cpu_mips_translate_address(CPUState *env, target_ulong address, int rw)
+hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address, int rw)
 {
     hwaddr physical;
     int prot;
@@ -506,7 +506,7 @@
 }
 #endif
 
-hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+hwaddr cpu_get_phys_page_debug(CPUMIPSState *env, target_ulong addr)
 {
 #if defined(CONFIG_USER_ONLY)
     return addr;
@@ -584,7 +584,7 @@
     [EXCP_CACHE] = "cache error",
 };
 
-void do_interrupt (CPUState *env)
+void do_interrupt (CPUMIPSState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     target_ulong offset;
@@ -807,7 +807,7 @@
     env->exception_index = EXCP_NONE;
 }
 
-void r4k_invalidate_tlb (CPUState *env, int idx)
+void r4k_invalidate_tlb (CPUMIPSState *env, int idx)
 {
     r4k_tlb_t *tlb;
     target_ulong addr;
diff --git a/target-mips/machine.c b/target-mips/machine.c
index 714be20..55dc74b 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -42,7 +42,7 @@
 
 void cpu_save(QEMUFile *f, void *opaque)
 {
-    CPUState *env = opaque;
+    CPUMIPSState *env = opaque;
     int i;
 
     /* Save active TC */
@@ -189,7 +189,7 @@
 
 int cpu_load(QEMUFile *f, void *opaque, int version_id)
 {
-    CPUState *env = opaque;
+    CPUMIPSState *env = opaque;
     int i;
 
     if (version_id != 3)
diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index 54e80f1..bf094a3 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -10,8 +10,12 @@
 
 #if defined(TARGET_MIPS64)
 #define TARGET_LONG_BITS 64
+#define TARGET_PHYS_ADDR_SPACE_BITS 36
+#define TARGET_VIRT_ADDR_SPACE_BITS 42
 #else
 #define TARGET_LONG_BITS 32
+#define TARGET_PHYS_ADDR_SPACE_BITS 36
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
 #endif
 
 /* Masks used to mark instructions to indicate which ISA level they
@@ -34,8 +38,11 @@
 #define		ASE_DSPR2	0x00010000
 #define		ASE_MT		0x00020000
 #define		ASE_SMARTMIPS	0x00040000
+#define 	ASE_MICROMIPS	0x00080000
 
 /* Chip specific instructions. */
+#define		INSN_LOONGSON2E  0x20000000
+#define		INSN_LOONGSON2F  0x40000000
 #define		INSN_VR54XX	0x80000000
 
 /* MIPS CPU defines. */
@@ -44,6 +51,8 @@
 #define		CPU_MIPS3	(CPU_MIPS2 | ISA_MIPS3)
 #define		CPU_MIPS4	(CPU_MIPS3 | ISA_MIPS4)
 #define		CPU_VR54XX	(CPU_MIPS4 | INSN_VR54XX)
+#define		CPU_LOONGSON2E  (CPU_MIPS3 | INSN_LOONGSON2E)
+#define		CPU_LOONGSON2F  (CPU_MIPS3 | INSN_LOONGSON2F)
 
 #define		CPU_MIPS5	(CPU_MIPS4 | ISA_MIPS5)
 
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 310821c..89ab947 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1498,7 +1498,7 @@
 }
 
 #ifndef CONFIG_USER_ONLY
-static void inline r4k_invalidate_tlb_shadow (CPUState *env, int idx)
+static void inline r4k_invalidate_tlb_shadow (CPUMIPSState *env, int idx)
 {
     r4k_tlb_t *tlb;
     uint8_t ASID = env->CP0_EntryHi & 0xFF;
@@ -1511,7 +1511,7 @@
     }
 }
 
-static void inline r4k_invalidate_tlb (CPUState *env, int idx)
+static void inline r4k_invalidate_tlb (CPUMIPSState *env, int idx)
 {
     r4k_tlb_t *tlb;
     target_ulong addr;
@@ -1557,7 +1557,7 @@
 }
 
 /* TLB management */
-void cpu_mips_tlb_flush (CPUState *env, int flush_global)
+void cpu_mips_tlb_flush (CPUMIPSState *env, int flush_global)
 {
     /* Flush qemu's TLB and discard all shadowed entries.  */
     tlb_flush (env, flush_global);
@@ -1586,9 +1586,9 @@
     tlb->PFN[1] = (env->CP0_EntryLo1 >> 6) << 12;
 }
 
-void r4k_helper_ptw_tlbrefill(CPUState *target_env)
+void r4k_helper_ptw_tlbrefill(CPUMIPSState *target_env)
 {
-   CPUState *saved_env;
+   CPUMIPSState *saved_env;
 
    /* Save current 'env' value */
    saved_env = env;
@@ -1905,7 +1905,7 @@
 void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
-    CPUState *saved_env;
+    CPUMIPSState *saved_env;
     unsigned long pc;
     int ret;
 
@@ -1970,7 +1970,7 @@
  */
 unsigned long v2p(target_ulong ptr, int is_user)
 {
-    CPUState *saved_env;
+    CPUMIPSState *saved_env;
     int index;
     target_ulong addr;
     unsigned long physaddr;
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 75f6ca7..87b2cba 100755
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -554,7 +554,7 @@
         TCGv_i32 t2 = tcg_temp_new_i32();
         TCGv_ptr addr = tcg_temp_new_ptr();
 
-        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
+        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
         tcg_gen_andi_i32(t2, t2, 0xf);
         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
@@ -577,7 +577,7 @@
         TCGv_ptr addr = tcg_temp_new_ptr();
 
         gen_load_gpr(t0, from);
-        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
+        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
         tcg_gen_andi_i32(t2, t2, 0xf);
         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
@@ -594,28 +594,28 @@
 /* Floating point register moves. */
 static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
 {
-    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
+    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
 }
 
 static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
 {
-    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
+    tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
 }
 
 static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
 {
-    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
+    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
 }
 
 static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
 {
-    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
+    tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
 }
 
 static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
 {
     if (ctx->hflags & MIPS_HFLAG_F64) {
-        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
+        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d));
     } else {
         TCGv_i32 t0 = tcg_temp_new_i32();
         TCGv_i32 t1 = tcg_temp_new_i32();
@@ -630,7 +630,7 @@
 static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
 {
     if (ctx->hflags & MIPS_HFLAG_F64) {
-        tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
+        tcg_gen_st_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d));
     } else {
         TCGv_i64 t0 = tcg_temp_new_i64();
         TCGv_i32 t1 = tcg_temp_new_i32();
@@ -770,7 +770,7 @@
     }
 }
 
-static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
+static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
 {
     ctx->saved_hflags = ctx->hflags;
     switch (ctx->hflags & MIPS_HFLAG_BMASK) {
@@ -868,7 +868,7 @@
 
 /* This code generates a "reserved instruction" exception if the
    CPU does not support the instruction set corresponding to flags. */
-static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
+static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
 {
     if (unlikely(!(env->insn_flags & flags)))
         generate_exception(ctx, EXCP_RI);
@@ -919,8 +919,8 @@
     TCGv t0 = tcg_temp_new();                                              \
     tcg_gen_mov_tl(t0, arg1);                                              \
     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
-    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr));                \
-    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
+    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
+    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
     tcg_temp_free(t0);                                                     \
 }
 #else
@@ -946,14 +946,14 @@
                                                                              \
     tcg_gen_andi_tl(t0, arg2, almask);                                       \
     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
-    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
+    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
     generate_exception(ctx, EXCP_AdES);                                      \
     gen_set_label(l1);                                                       \
-    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr));                  \
+    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
-    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
-    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
+    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
+    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
     gen_helper_0i(raise_exception, EXCP_SC);                                 \
     gen_set_label(l2);                                                       \
     tcg_gen_movi_tl(t0, 0);                                                  \
@@ -1247,7 +1247,7 @@
 }
 
 /* Arithmetic with immediate operand */
-static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
+static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
                            int rt, int rs, int16_t imm)
 {
     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
@@ -1334,7 +1334,7 @@
 }
 
 /* Logic with immediate operand */
-static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
+static void gen_logic_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
 {
     target_ulong uimm;
     const char * __attribute__((unused)) opn = "imm logic";
@@ -1376,7 +1376,7 @@
 }
 
 /* Set on less than with immediate operand */
-static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
+static void gen_slt_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
 {
     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
     const char * __attribute__((unused)) opn = "imm arith";
@@ -1404,7 +1404,7 @@
 }
 
 /* Shifts with immediate operand */
-static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
+static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
                           int rt, int rs, int16_t imm)
 {
     target_ulong uimm = ((uint16_t)imm) & 0x1f;
@@ -1543,7 +1543,7 @@
 }
 
 /* Arithmetic */
-static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
+static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
                        int rd, int rs, int rt)
 {
     const char* __attribute__((unused)) opn = "arith";
@@ -1724,7 +1724,7 @@
 }
 
 /* Conditional move */
-static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
+static void gen_cond_move (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
 {
     const char* __attribute__((unused)) opn = "cond move";
     int l1;
@@ -1761,7 +1761,7 @@
 }
 
 /* Logic */
-static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
+static void gen_logic (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
 {
     const char* __attribute__((unused)) opn = "logic";
 
@@ -1821,7 +1821,7 @@
 }
 
 /* Set on lower than */
-static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
+static void gen_slt (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
 {
     const char* __attribute__((unused)) opn = "slt";
     TCGv t0, t1;
@@ -1852,7 +1852,7 @@
 }
 
 /* Shifts */
-static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
+static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
                        int rd, int rs, int rt)
 {
     const char* __attribute__((unused)) opn = "shifts";
@@ -2895,7 +2895,7 @@
     tcg_gen_st_tl(arg, cpu_env, off);
 }
 
-static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
+static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
 {
     const char * __attribute__((unused)) rn = "invalid";
 
@@ -2906,7 +2906,7 @@
     case 0:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
             rn = "Index";
             break;
         case 1:
@@ -2936,37 +2936,37 @@
             break;
         case 1:
             check_insn(env, ctx, ASE_MT);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
             rn = "VPEControl";
             break;
         case 2:
             check_insn(env, ctx, ASE_MT);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
             rn = "VPEConf0";
             break;
         case 3:
             check_insn(env, ctx, ASE_MT);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
             rn = "VPEConf1";
             break;
         case 4:
             check_insn(env, ctx, ASE_MT);
-            gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
+            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
             rn = "YQMask";
             break;
         case 5:
             check_insn(env, ctx, ASE_MT);
-            gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
+            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
             rn = "VPESchedule";
             break;
         case 6:
             check_insn(env, ctx, ASE_MT);
-            gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
+            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
             rn = "VPEScheFBack";
             break;
         case 7:
             check_insn(env, ctx, ASE_MT);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
             rn = "VPEOpt";
             break;
         default:
@@ -2976,7 +2976,7 @@
     case 2:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
             tcg_gen_ext32s_tl(arg, arg);
             rn = "EntryLo0";
             break;
@@ -3022,7 +3022,7 @@
     case 3:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
             tcg_gen_ext32s_tl(arg, arg);
             rn = "EntryLo1";
             break;
@@ -3033,7 +3033,7 @@
     case 4:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
             tcg_gen_ext32s_tl(arg, arg);
             rn = "Context";
             break;
@@ -3048,12 +3048,12 @@
     case 5:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
             rn = "PageMask";
             break;
         case 1:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
             rn = "PageGrain";
             break;
         default:
@@ -3063,32 +3063,32 @@
     case 6:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
             rn = "Wired";
             break;
         case 1:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
             rn = "SRSConf0";
             break;
         case 2:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
             rn = "SRSConf1";
             break;
         case 3:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
             rn = "SRSConf2";
             break;
         case 4:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
             rn = "SRSConf3";
             break;
         case 5:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
             rn = "SRSConf4";
             break;
         default:
@@ -3099,7 +3099,7 @@
         switch (sel) {
         case 0:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
             rn = "HWREna";
             break;
         default:
@@ -3109,7 +3109,7 @@
     case 8:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
             tcg_gen_ext32s_tl(arg, arg);
             rn = "BadVAddr";
             break;
@@ -3138,7 +3138,7 @@
     case 10:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
             tcg_gen_ext32s_tl(arg, arg);
             rn = "EntryHi";
             break;
@@ -3149,7 +3149,7 @@
     case 11:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
             rn = "Compare";
             break;
         /* 6,7 are implementation dependent */
@@ -3160,22 +3160,22 @@
     case 12:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
             rn = "Status";
             break;
         case 1:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
             rn = "IntCtl";
             break;
         case 2:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
             rn = "SRSCtl";
             break;
         case 3:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
             rn = "SRSMap";
             break;
         default:
@@ -3185,7 +3185,7 @@
     case 13:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
             rn = "Cause";
             break;
         default:
@@ -3195,7 +3195,7 @@
     case 14:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
             tcg_gen_ext32s_tl(arg, arg);
             rn = "EPC";
             break;
@@ -3206,12 +3206,12 @@
     case 15:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
             rn = "PRid";
             break;
         case 1:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
             rn = "EBase";
             break;
         default:
@@ -3221,29 +3221,29 @@
     case 16:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
             rn = "Config";
             break;
         case 1:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
             rn = "Config1";
             break;
         case 2:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
             rn = "Config2";
             break;
         case 3:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
             rn = "Config3";
             break;
         /* 4,5 are reserved */
         /* 6,7 are implementation dependent */
         case 6:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
             rn = "Config6";
             break;
         case 7:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
             rn = "Config7";
             break;
         default:
@@ -3285,7 +3285,7 @@
         case 0:
 #if defined(TARGET_MIPS64)
             check_insn(env, ctx, ISA_MIPS3);
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
             tcg_gen_ext32s_tl(arg, arg);
             rn = "XContext";
             break;
@@ -3298,7 +3298,7 @@
        /* Officially reserved, but sel 0 is used for R1x000 framemask */
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
             rn = "Framemask";
             break;
         default:
@@ -3339,7 +3339,7 @@
         switch (sel) {
         case 0:
             /* EJTAG support */
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
             tcg_gen_ext32s_tl(arg, arg);
             rn = "DEPC";
             break;
@@ -3350,7 +3350,7 @@
     case 25:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
             rn = "Performance0";
             break;
         case 1:
@@ -3405,14 +3405,14 @@
         case 2:
         case 4:
         case 6:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
             rn = "TagLo";
             break;
         case 1:
         case 3:
         case 5:
         case 7:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
             rn = "DataLo";
             break;
         default:
@@ -3425,14 +3425,14 @@
         case 2:
         case 4:
         case 6:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
             rn = "TagHi";
             break;
         case 1:
         case 3:
         case 5:
         case 7:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
             rn = "DataHi";
             break;
         default:
@@ -3442,7 +3442,7 @@
     case 30:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
             tcg_gen_ext32s_tl(arg, arg);
             rn = "ErrorEPC";
             break;
@@ -3454,7 +3454,7 @@
         switch (sel) {
         case 0:
             /* EJTAG support */
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
             rn = "DESAVE";
             break;
         default:
@@ -3472,7 +3472,7 @@
     generate_exception(ctx, EXCP_RI);
 }
 
-static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
+static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
 {
     const char * __attribute__((unused)) rn = "invalid";
 
@@ -3536,12 +3536,12 @@
             break;
         case 5:
             check_insn(env, ctx, ASE_MT);
-            gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
+            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
             rn = "VPESchedule";
             break;
         case 6:
             check_insn(env, ctx, ASE_MT);
-            gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
+            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
             rn = "VPEScheFBack";
             break;
         case 7:
@@ -3745,7 +3745,7 @@
             break;
         case 3:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
+            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
             /* Stop translation as we may have switched the execution mode */
             ctx->bstate = BS_STOP;
             rn = "SRSMap";
@@ -3768,7 +3768,7 @@
     case 14:
         switch (sel) {
         case 0:
-            gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
+            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
             rn = "EPC";
             break;
         default:
@@ -3928,7 +3928,7 @@
         switch (sel) {
         case 0:
             /* EJTAG support */
-            gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
+            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
             rn = "DEPC";
             break;
         default:
@@ -4031,7 +4031,7 @@
     case 30:
         switch (sel) {
         case 0:
-            gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
+            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
             rn = "ErrorEPC";
             break;
         default:
@@ -4042,7 +4042,7 @@
         switch (sel) {
         case 0:
             /* EJTAG support */
-            gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
+            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
             rn = "DESAVE";
             break;
         default:
@@ -4068,7 +4068,7 @@
 }
 
 #if defined(TARGET_MIPS64)
-static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
+static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
 {
     const char *rn = "invalid";
 
@@ -4079,7 +4079,7 @@
     case 0:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
             rn = "Index";
             break;
         case 1:
@@ -4109,37 +4109,37 @@
             break;
         case 1:
             check_insn(env, ctx, ASE_MT);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
             rn = "VPEControl";
             break;
         case 2:
             check_insn(env, ctx, ASE_MT);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
             rn = "VPEConf0";
             break;
         case 3:
             check_insn(env, ctx, ASE_MT);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
             rn = "VPEConf1";
             break;
         case 4:
             check_insn(env, ctx, ASE_MT);
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
             rn = "YQMask";
             break;
         case 5:
             check_insn(env, ctx, ASE_MT);
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
             rn = "VPESchedule";
             break;
         case 6:
             check_insn(env, ctx, ASE_MT);
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
             rn = "VPEScheFBack";
             break;
         case 7:
             check_insn(env, ctx, ASE_MT);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
             rn = "VPEOpt";
             break;
         default:
@@ -4149,7 +4149,7 @@
     case 2:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
             rn = "EntryLo0";
             break;
         case 1:
@@ -4194,7 +4194,7 @@
     case 3:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
             rn = "EntryLo1";
             break;
         default:
@@ -4204,7 +4204,7 @@
     case 4:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
             rn = "Context";
             break;
         case 1:
@@ -4218,12 +4218,12 @@
     case 5:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
             rn = "PageMask";
             break;
         case 1:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
             rn = "PageGrain";
             break;
         default:
@@ -4233,32 +4233,32 @@
     case 6:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
             rn = "Wired";
             break;
         case 1:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
             rn = "SRSConf0";
             break;
         case 2:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
             rn = "SRSConf1";
             break;
         case 3:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
             rn = "SRSConf2";
             break;
         case 4:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
             rn = "SRSConf3";
             break;
         case 5:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
             rn = "SRSConf4";
             break;
         default:
@@ -4269,7 +4269,7 @@
         switch (sel) {
         case 0:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
             rn = "HWREna";
             break;
         default:
@@ -4279,7 +4279,7 @@
     case 8:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
             rn = "BadVAddr";
             break;
         default:
@@ -4307,7 +4307,7 @@
     case 10:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
             rn = "EntryHi";
             break;
         default:
@@ -4317,7 +4317,7 @@
     case 11:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
             rn = "Compare";
             break;
         /* 6,7 are implementation dependent */
@@ -4328,22 +4328,22 @@
     case 12:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
             rn = "Status";
             break;
         case 1:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
             rn = "IntCtl";
             break;
         case 2:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
             rn = "SRSCtl";
             break;
         case 3:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
             rn = "SRSMap";
             break;
         default:
@@ -4353,7 +4353,7 @@
     case 13:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
             rn = "Cause";
             break;
         default:
@@ -4363,7 +4363,7 @@
     case 14:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
             rn = "EPC";
             break;
         default:
@@ -4373,12 +4373,12 @@
     case 15:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
             rn = "PRid";
             break;
         case 1:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
             rn = "EBase";
             break;
         default:
@@ -4388,28 +4388,28 @@
     case 16:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
             rn = "Config";
             break;
         case 1:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
             rn = "Config1";
             break;
         case 2:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
             rn = "Config2";
             break;
         case 3:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
             rn = "Config3";
             break;
        /* 6,7 are implementation dependent */
         case 6:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
             rn = "Config6";
             break;
         case 7:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
             rn = "Config7";
             break;
         default:
@@ -4450,7 +4450,7 @@
         switch (sel) {
         case 0:
             check_insn(env, ctx, ISA_MIPS3);
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
             rn = "XContext";
             break;
         default:
@@ -4461,7 +4461,7 @@
        /* Officially reserved, but sel 0 is used for R1x000 framemask */
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
             rn = "Framemask";
             break;
         default:
@@ -4502,7 +4502,7 @@
         switch (sel) {
         case 0:
             /* EJTAG support */
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
             rn = "DEPC";
             break;
         default:
@@ -4512,7 +4512,7 @@
     case 25:
         switch (sel) {
         case 0:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
             rn = "Performance0";
             break;
         case 1:
@@ -4568,14 +4568,14 @@
         case 2:
         case 4:
         case 6:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
             rn = "TagLo";
             break;
         case 1:
         case 3:
         case 5:
         case 7:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
             rn = "DataLo";
             break;
         default:
@@ -4588,14 +4588,14 @@
         case 2:
         case 4:
         case 6:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
             rn = "TagHi";
             break;
         case 1:
         case 3:
         case 5:
         case 7:
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
             rn = "DataHi";
             break;
         default:
@@ -4605,7 +4605,7 @@
     case 30:
         switch (sel) {
         case 0:
-            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
             rn = "ErrorEPC";
             break;
         default:
@@ -4616,7 +4616,7 @@
         switch (sel) {
         case 0:
             /* EJTAG support */
-            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
             rn = "DESAVE";
             break;
         default:
@@ -4634,7 +4634,7 @@
     generate_exception(ctx, EXCP_RI);
 }
 
-static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
+static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
 {
     const char *rn = "invalid";
 
@@ -4698,12 +4698,12 @@
             break;
         case 5:
             check_insn(env, ctx, ASE_MT);
-            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
+            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
             rn = "VPESchedule";
             break;
         case 6:
             check_insn(env, ctx, ASE_MT);
-            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
+            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
             rn = "VPEScheFBack";
             break;
         case 7:
@@ -4911,7 +4911,7 @@
             break;
         case 3:
             check_insn(env, ctx, ISA_MIPS32R2);
-            gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
+            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
             /* Stop translation as we may have switched the execution mode */
             ctx->bstate = BS_STOP;
             rn = "SRSMap";
@@ -4934,7 +4934,7 @@
     case 14:
         switch (sel) {
         case 0:
-            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
+            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
             rn = "EPC";
             break;
         default:
@@ -5081,7 +5081,7 @@
         switch (sel) {
         case 0:
             /* EJTAG support */
-            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
+            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
             rn = "DEPC";
             break;
         default:
@@ -5184,7 +5184,7 @@
     case 30:
         switch (sel) {
         case 0:
-            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
+            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
             rn = "ErrorEPC";
             break;
         default:
@@ -5195,7 +5195,7 @@
         switch (sel) {
         case 0:
             /* EJTAG support */
-            gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
+            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
             rn = "DESAVE";
             break;
         default:
@@ -5221,7 +5221,7 @@
 }
 #endif /* TARGET_MIPS64 */
 
-static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
+static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
                      int u, int sel, int h)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
@@ -5385,7 +5385,7 @@
     generate_exception(ctx, EXCP_RI);
 }
 
-static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
+static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
                      int u, int sel, int h)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
@@ -5549,7 +5549,7 @@
     generate_exception(ctx, EXCP_RI);
 }
 
-static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
+static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
 {
     const char* __attribute__((unused)) opn = "ldst";
 
@@ -5672,7 +5672,7 @@
 #endif /* !CONFIG_USER_ONLY */
 
 /* CP1 Branches (before delay slot) */
-static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
+static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
                                  int32_t cc, int32_t offset)
 {
     target_ulong btarget;
@@ -7625,7 +7625,7 @@
 
 #endif
 
-static void decode_opc (CPUState *env, DisasContext *ctx)
+static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
 {
     int32_t offset;
     int rs, rt, rd, sa;
@@ -7873,7 +7873,7 @@
                     break;
                 case 29:
 #if defined(CONFIG_USER_ONLY)
-                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
+                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
                     gen_store_gpr(t0, rt);
                     break;
 #else
@@ -8276,7 +8276,7 @@
 }
 
 static inline void
-gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
+gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
                                 int search_pc)
 {
     DisasContext ctx;
@@ -8412,24 +8412,24 @@
     LOG_DISAS("\n");
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(pc_start, ctx.pc - pc_start, 0);
+        log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
         qemu_log("\n");
     }
     qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
 #endif
 }
 
-void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
+void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
 {
     gen_intermediate_code_internal(env, tb, 0);
 }
 
-void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
+void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
 {
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-static void fpu_dump_state(CPUState *env, FILE *f,
+static void fpu_dump_state(CPUMIPSState *env, FILE *f,
                            int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
                            int flags)
 {
@@ -8471,7 +8471,7 @@
 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
 
 static void
-cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
+cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
                                 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                                 int flags)
 {
@@ -8498,7 +8498,7 @@
 }
 #endif
 
-void cpu_dump_state (CPUState *env, FILE *f,
+void cpu_dump_state (CPUMIPSState *env, FILE *f,
                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                      int flags)
 {
@@ -8539,36 +8539,36 @@
     TCGV_UNUSED(cpu_gpr[0]);
     for (i = 1; i < 32; i++)
         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
-                                        offsetof(CPUState, active_tc.gpr[i]),
+                                        offsetof(CPUMIPSState, active_tc.gpr[i]),
                                         regnames[i]);
     cpu_PC = tcg_global_mem_new(TCG_AREG0,
-                                offsetof(CPUState, active_tc.PC), "PC");
+                                offsetof(CPUMIPSState, active_tc.PC), "PC");
     for (i = 0; i < MIPS_DSP_ACC; i++) {
         cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
-                                       offsetof(CPUState, active_tc.HI[i]),
+                                       offsetof(CPUMIPSState, active_tc.HI[i]),
                                        regnames_HI[i]);
         cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
-                                       offsetof(CPUState, active_tc.LO[i]),
+                                       offsetof(CPUMIPSState, active_tc.LO[i]),
                                        regnames_LO[i]);
         cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
-                                        offsetof(CPUState, active_tc.ACX[i]),
+                                        offsetof(CPUMIPSState, active_tc.ACX[i]),
                                         regnames_ACX[i]);
     }
     cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
-                                     offsetof(CPUState, active_tc.DSPControl),
+                                     offsetof(CPUMIPSState, active_tc.DSPControl),
                                      "DSPControl");
     bcond = tcg_global_mem_new(TCG_AREG0,
-                               offsetof(CPUState, bcond), "bcond");
+                               offsetof(CPUMIPSState, bcond), "bcond");
     btarget = tcg_global_mem_new(TCG_AREG0,
-                                 offsetof(CPUState, btarget), "btarget");
+                                 offsetof(CPUMIPSState, btarget), "btarget");
     hflags = tcg_global_mem_new_i32(TCG_AREG0,
-                                    offsetof(CPUState, hflags), "hflags");
+                                    offsetof(CPUMIPSState, hflags), "hflags");
 
     fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
-                                      offsetof(CPUState, active_fpu.fcr0),
+                                      offsetof(CPUMIPSState, active_fpu.fcr0),
                                       "fcr0");
     fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
-                                       offsetof(CPUState, active_fpu.fcr31),
+                                       offsetof(CPUMIPSState, active_fpu.fcr31),
                                        "fcr31");
 
     /* register helpers */
@@ -8707,7 +8707,7 @@
     env->exception_index = EXCP_NONE;
 }
 
-void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
+void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
 {
     env->active_tc.PC = gen_opc_pc[pc_pos];
     env->hflags &= ~MIPS_HFLAG_BMASK;
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
deleted file mode 100644
index fb858d8..0000000
--- a/tcg/arm/tcg-target.c
+++ /dev/null
@@ -1,1860 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Andrzej Zaborowski
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#if defined(__ARM_ARCH_7__) ||  \
-    defined(__ARM_ARCH_7A__) || \
-    defined(__ARM_ARCH_7EM__) || \
-    defined(__ARM_ARCH_7M__) || \
-    defined(__ARM_ARCH_7R__)
-#define USE_ARMV7_INSTRUCTIONS
-#endif
-
-#if defined(USE_ARMV7_INSTRUCTIONS) || \
-    defined(__ARM_ARCH_6J__) || \
-    defined(__ARM_ARCH_6K__) || \
-    defined(__ARM_ARCH_6T2__) || \
-    defined(__ARM_ARCH_6Z__) || \
-    defined(__ARM_ARCH_6ZK__)
-#define USE_ARMV6_INSTRUCTIONS
-#endif
-
-#if defined(USE_ARMV6_INSTRUCTIONS) || \
-    defined(__ARM_ARCH_5T__) || \
-    defined(__ARM_ARCH_5TE__) || \
-    defined(__ARM_ARCH_5TEJ__)
-#define USE_ARMV5_INSTRUCTIONS
-#endif
-
-#ifdef USE_ARMV5_INSTRUCTIONS
-static const int use_armv5_instructions = 1;
-#else
-static const int use_armv5_instructions = 0;
-#endif
-#undef USE_ARMV5_INSTRUCTIONS
-
-#ifdef USE_ARMV6_INSTRUCTIONS
-static const int use_armv6_instructions = 1;
-#else
-static const int use_armv6_instructions = 0;
-#endif
-#undef USE_ARMV6_INSTRUCTIONS
-
-#ifdef USE_ARMV7_INSTRUCTIONS
-static const int use_armv7_instructions = 1;
-#else
-static const int use_armv7_instructions = 0;
-#endif
-#undef USE_ARMV7_INSTRUCTIONS
-
-#ifndef NDEBUG
-static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
-    "%r0",
-    "%r1",
-    "%r2",
-    "%r3",
-    "%r4",
-    "%r5",
-    "%r6",
-    "%r7",
-    "%r8",
-    "%r9",
-    "%r10",
-    "%r11",
-    "%r12",
-    "%r13",
-    "%r14",
-    "%pc",
-};
-#endif
-
-static const int tcg_target_reg_alloc_order[] = {
-    TCG_REG_R4,
-    TCG_REG_R5,
-    TCG_REG_R6,
-    TCG_REG_R7,
-    TCG_REG_R8,
-    TCG_REG_R9,
-    TCG_REG_R10,
-    TCG_REG_R11,
-    TCG_REG_R13,
-    TCG_REG_R0,
-    TCG_REG_R1,
-    TCG_REG_R2,
-    TCG_REG_R3,
-    TCG_REG_R12,
-    TCG_REG_R14,
-};
-
-static const int tcg_target_call_iarg_regs[4] = {
-    TCG_REG_R0, TCG_REG_R1, TCG_REG_R2, TCG_REG_R3
-};
-static const int tcg_target_call_oarg_regs[2] = {
-    TCG_REG_R0, TCG_REG_R1
-};
-
-static inline void reloc_abs32(void *code_ptr, tcg_target_long target)
-{
-    *(uint32_t *) code_ptr = target;
-}
-
-static inline void reloc_pc24(void *code_ptr, tcg_target_long target)
-{
-    uint32_t offset = ((target - ((tcg_target_long) code_ptr + 8)) >> 2);
-
-    *(uint32_t *) code_ptr = ((*(uint32_t *) code_ptr) & ~0xffffff)
-                             | (offset & 0xffffff);
-}
-
-static void patch_reloc(uint8_t *code_ptr, int type,
-                tcg_target_long value, tcg_target_long addend)
-{
-    switch (type) {
-    case R_ARM_ABS32:
-        reloc_abs32(code_ptr, value);
-        break;
-
-    case R_ARM_CALL:
-    case R_ARM_JUMP24:
-    default:
-        tcg_abort();
-
-    case R_ARM_PC24:
-        reloc_pc24(code_ptr, value);
-        break;
-    }
-}
-
-/* maximum number of register used for input function arguments */
-static inline int tcg_target_get_call_iarg_regs_count(int flags)
-{
-    return 4;
-}
-
-/* parse target specific constraints */
-static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
-{
-    const char *ct_str;
-
-    ct_str = *pct_str;
-    switch (ct_str[0]) {
-    case 'I':
-         ct->ct |= TCG_CT_CONST_ARM;
-         break;
-
-    case 'r':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
-        break;
-
-    /* qemu_ld address */
-    case 'l':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
-#ifdef CONFIG_SOFTMMU
-        /* r0 and r1 will be overwritten when reading the tlb entry,
-           so don't use these. */
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
-#endif
-        break;
-    case 'L':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
-#ifdef CONFIG_SOFTMMU
-        /* r1 is still needed to load data_reg or data_reg2,
-           so don't use it. */
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
-#endif
-        break;
-
-    /* qemu_st address & data_reg */
-    case 's':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
-        /* r0 and r1 will be overwritten when reading the tlb entry
-           (softmmu only) and doing the byte swapping, so don't
-           use these. */
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
-        break;
-    /* qemu_st64 data_reg2 */
-    case 'S':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
-        /* r0 and r1 will be overwritten when reading the tlb entry
-            (softmmu only) and doing the byte swapping, so don't
-            use these. */
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
-#ifdef CONFIG_SOFTMMU
-        /* r2 is still needed to load data_reg, so don't use it. */
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
-#endif
-        break;
-
-    default:
-        return -1;
-    }
-    ct_str++;
-    *pct_str = ct_str;
-
-    return 0;
-}
-
-static inline uint32_t rotl(uint32_t val, int n)
-{
-  return (val << n) | (val >> (32 - n));
-}
-
-/* ARM immediates for ALU instructions are made of an unsigned 8-bit
-   right-rotated by an even amount between 0 and 30. */
-static inline int encode_imm(uint32_t imm)
-{
-    int shift;
-
-    /* simple case, only lower bits */
-    if ((imm & ~0xff) == 0)
-        return 0;
-    /* then try a simple even shift */
-    shift = ctz32(imm) & ~1;
-    if (((imm >> shift) & ~0xff) == 0)
-        return 32 - shift;
-    /* now try harder with rotations */
-    if ((rotl(imm, 2) & ~0xff) == 0)
-        return 2;
-    if ((rotl(imm, 4) & ~0xff) == 0)
-        return 4;
-    if ((rotl(imm, 6) & ~0xff) == 0)
-        return 6;
-    /* imm can't be encoded */
-    return -1;
-}
-
-static inline int check_fit_imm(uint32_t imm)
-{
-    return encode_imm(imm) >= 0;
-}
-
-/* Test if a constant matches the constraint.
- * TODO: define constraints for:
- *
- * ldr/str offset:   between -0xfff and 0xfff
- * ldrh/strh offset: between -0xff and 0xff
- * mov operand2:     values represented with x << (2 * y), x < 0x100
- * add, sub, eor...: ditto
- */
-static inline int tcg_target_const_match(tcg_target_long val,
-                const TCGArgConstraint *arg_ct)
-{
-    int ct;
-    ct = arg_ct->ct;
-    if (ct & TCG_CT_CONST)
-        return 1;
-    else if ((ct & TCG_CT_CONST_ARM) && check_fit_imm(val))
-        return 1;
-    else
-        return 0;
-}
-
-enum arm_data_opc_e {
-    ARITH_AND = 0x0,
-    ARITH_EOR = 0x1,
-    ARITH_SUB = 0x2,
-    ARITH_RSB = 0x3,
-    ARITH_ADD = 0x4,
-    ARITH_ADC = 0x5,
-    ARITH_SBC = 0x6,
-    ARITH_RSC = 0x7,
-    ARITH_TST = 0x8,
-    ARITH_CMP = 0xa,
-    ARITH_CMN = 0xb,
-    ARITH_ORR = 0xc,
-    ARITH_MOV = 0xd,
-    ARITH_BIC = 0xe,
-    ARITH_MVN = 0xf,
-};
-
-#define TO_CPSR(opc) \
-  ((opc == ARITH_CMP || opc == ARITH_CMN || opc == ARITH_TST) << 20)
-
-#define SHIFT_IMM_LSL(im)	(((im) << 7) | 0x00)
-#define SHIFT_IMM_LSR(im)	(((im) << 7) | 0x20)
-#define SHIFT_IMM_ASR(im)	(((im) << 7) | 0x40)
-#define SHIFT_IMM_ROR(im)	(((im) << 7) | 0x60)
-#define SHIFT_REG_LSL(rs)	(((rs) << 8) | 0x10)
-#define SHIFT_REG_LSR(rs)	(((rs) << 8) | 0x30)
-#define SHIFT_REG_ASR(rs)	(((rs) << 8) | 0x50)
-#define SHIFT_REG_ROR(rs)	(((rs) << 8) | 0x70)
-
-enum arm_cond_code_e {
-    COND_EQ = 0x0,
-    COND_NE = 0x1,
-    COND_CS = 0x2,	/* Unsigned greater or equal */
-    COND_CC = 0x3,	/* Unsigned less than */
-    COND_MI = 0x4,	/* Negative */
-    COND_PL = 0x5,	/* Zero or greater */
-    COND_VS = 0x6,	/* Overflow */
-    COND_VC = 0x7,	/* No overflow */
-    COND_HI = 0x8,	/* Unsigned greater than */
-    COND_LS = 0x9,	/* Unsigned less or equal */
-    COND_GE = 0xa,
-    COND_LT = 0xb,
-    COND_GT = 0xc,
-    COND_LE = 0xd,
-    COND_AL = 0xe,
-};
-
-static const uint8_t tcg_cond_to_arm_cond[10] = {
-    [TCG_COND_EQ] = COND_EQ,
-    [TCG_COND_NE] = COND_NE,
-    [TCG_COND_LT] = COND_LT,
-    [TCG_COND_GE] = COND_GE,
-    [TCG_COND_LE] = COND_LE,
-    [TCG_COND_GT] = COND_GT,
-    /* unsigned */
-    [TCG_COND_LTU] = COND_CC,
-    [TCG_COND_GEU] = COND_CS,
-    [TCG_COND_LEU] = COND_LS,
-    [TCG_COND_GTU] = COND_HI,
-};
-
-static inline void tcg_out_bx(TCGContext *s, int cond, int rn)
-{
-    tcg_out32(s, (cond << 28) | 0x012fff10 | rn);
-}
-
-static inline void tcg_out_b(TCGContext *s, int cond, int32_t offset)
-{
-    tcg_out32(s, (cond << 28) | 0x0a000000 |
-                    (((offset - 8) >> 2) & 0x00ffffff));
-}
-
-static inline void tcg_out_b_noaddr(TCGContext *s, int cond)
-{
-    /* We pay attention here to not modify the branch target by skipping
-       the corresponding bytes. This ensure that caches and memory are
-       kept coherent during retranslation. */
-#ifdef HOST_WORDS_BIGENDIAN
-    tcg_out8(s, (cond << 4) | 0x0a);
-    s->code_ptr += 3;
-#else
-    s->code_ptr += 3;
-    tcg_out8(s, (cond << 4) | 0x0a);
-#endif
-}
-
-static inline void tcg_out_bl(TCGContext *s, int cond, int32_t offset)
-{
-    tcg_out32(s, (cond << 28) | 0x0b000000 |
-                    (((offset - 8) >> 2) & 0x00ffffff));
-}
-
-static inline void tcg_out_blx(TCGContext *s, int cond, int rn)
-{
-    tcg_out32(s, (cond << 28) | 0x012fff30 | rn);
-}
-
-static inline void tcg_out_blx_imm(TCGContext *s, int32_t offset)
-{
-    tcg_out32(s, 0xfa000000 | ((offset & 2) << 23) |
-                (((offset - 8) >> 2) & 0x00ffffff));
-}
-
-static inline void tcg_out_dat_reg(TCGContext *s,
-                int cond, int opc, int rd, int rn, int rm, int shift)
-{
-    tcg_out32(s, (cond << 28) | (0 << 25) | (opc << 21) | TO_CPSR(opc) |
-                    (rn << 16) | (rd << 12) | shift | rm);
-}
-
-static inline void tcg_out_dat_reg2(TCGContext *s,
-                int cond, int opc0, int opc1, int rd0, int rd1,
-                int rn0, int rn1, int rm0, int rm1, int shift)
-{
-    if (rd0 == rn1 || rd0 == rm1) {
-        tcg_out32(s, (cond << 28) | (0 << 25) | (opc0 << 21) | (1 << 20) |
-                        (rn0 << 16) | (8 << 12) | shift | rm0);
-        tcg_out32(s, (cond << 28) | (0 << 25) | (opc1 << 21) |
-                        (rn1 << 16) | (rd1 << 12) | shift | rm1);
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        rd0, 0, TCG_REG_R8, SHIFT_IMM_LSL(0));
-    } else {
-        tcg_out32(s, (cond << 28) | (0 << 25) | (opc0 << 21) | (1 << 20) |
-                        (rn0 << 16) | (rd0 << 12) | shift | rm0);
-        tcg_out32(s, (cond << 28) | (0 << 25) | (opc1 << 21) |
-                        (rn1 << 16) | (rd1 << 12) | shift | rm1);
-    }
-}
-
-static inline void tcg_out_dat_imm(TCGContext *s,
-                int cond, int opc, int rd, int rn, int im)
-{
-    tcg_out32(s, (cond << 28) | (1 << 25) | (opc << 21) | TO_CPSR(opc) |
-                    (rn << 16) | (rd << 12) | im);
-}
-
-static inline void tcg_out_movi32(TCGContext *s,
-                int cond, int rd, uint32_t arg)
-{
-    /* TODO: This is very suboptimal, we can easily have a constant
-     * pool somewhere after all the instructions.  */
-    if ((int)arg < 0 && (int)arg >= -0x100) {
-        tcg_out_dat_imm(s, cond, ARITH_MVN, rd, 0, (~arg) & 0xff);
-    } else if (use_armv7_instructions) {
-        /* use movw/movt */
-        /* movw */
-        tcg_out32(s, (cond << 28) | 0x03000000 | (rd << 12)
-                  | ((arg << 4) & 0x000f0000) | (arg & 0xfff));
-        if (arg & 0xffff0000) {
-            /* movt */
-            tcg_out32(s, (cond << 28) | 0x03400000 | (rd << 12)
-                      | ((arg >> 12) & 0x000f0000) | ((arg >> 16) & 0xfff));
-        }
-    } else {
-        int opc = ARITH_MOV;
-        int rn = 0;
-
-        do {
-            int i, rot;
-
-            i = ctz32(arg) & ~1;
-            rot = ((32 - i) << 7) & 0xf00;
-            tcg_out_dat_imm(s, cond, opc, rd, rn, ((arg >> i) & 0xff) | rot);
-            arg &= ~(0xff << i);
-
-            opc = ARITH_ORR;
-            rn = rd;
-        } while (arg);
-    }
-}
-
-static inline void tcg_out_mul32(TCGContext *s,
-                int cond, int rd, int rs, int rm)
-{
-    if (rd != rm)
-        tcg_out32(s, (cond << 28) | (rd << 16) | (0 << 12) |
-                        (rs << 8) | 0x90 | rm);
-    else if (rd != rs)
-        tcg_out32(s, (cond << 28) | (rd << 16) | (0 << 12) |
-                        (rm << 8) | 0x90 | rs);
-    else {
-        tcg_out32(s, (cond << 28) | ( 8 << 16) | (0 << 12) |
-                        (rs << 8) | 0x90 | rm);
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        rd, 0, TCG_REG_R8, SHIFT_IMM_LSL(0));
-    }
-}
-
-static inline void tcg_out_umull32(TCGContext *s,
-                int cond, int rd0, int rd1, int rs, int rm)
-{
-    if (rd0 != rm && rd1 != rm)
-        tcg_out32(s, (cond << 28) | 0x800090 |
-                        (rd1 << 16) | (rd0 << 12) | (rs << 8) | rm);
-    else if (rd0 != rs && rd1 != rs)
-        tcg_out32(s, (cond << 28) | 0x800090 |
-                        (rd1 << 16) | (rd0 << 12) | (rm << 8) | rs);
-    else {
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        TCG_REG_R8, 0, rm, SHIFT_IMM_LSL(0));
-        tcg_out32(s, (cond << 28) | 0x800098 |
-                        (rd1 << 16) | (rd0 << 12) | (rs << 8));
-    }
-}
-
-static inline void tcg_out_smull32(TCGContext *s,
-                int cond, int rd0, int rd1, int rs, int rm)
-{
-    if (rd0 != rm && rd1 != rm)
-        tcg_out32(s, (cond << 28) | 0xc00090 |
-                        (rd1 << 16) | (rd0 << 12) | (rs << 8) | rm);
-    else if (rd0 != rs && rd1 != rs)
-        tcg_out32(s, (cond << 28) | 0xc00090 |
-                        (rd1 << 16) | (rd0 << 12) | (rm << 8) | rs);
-    else {
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        TCG_REG_R8, 0, rm, SHIFT_IMM_LSL(0));
-        tcg_out32(s, (cond << 28) | 0xc00098 |
-                        (rd1 << 16) | (rd0 << 12) | (rs << 8));
-    }
-}
-
-static inline void tcg_out_ext8s(TCGContext *s, int cond,
-                                 int rd, int rn)
-{
-    if (use_armv6_instructions) {
-        /* sxtb */
-        tcg_out32(s, 0x06af0070 | (cond << 28) | (rd << 12) | rn);
-    } else {
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        rd, 0, rn, SHIFT_IMM_LSL(24));
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        rd, 0, rd, SHIFT_IMM_ASR(24));
-    }
-}
-
-static inline void tcg_out_ext8u(TCGContext *s, int cond,
-                                 int rd, int rn)
-{
-    tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn, 0xff);
-}
-
-static inline void tcg_out_ext16s(TCGContext *s, int cond,
-                                  int rd, int rn)
-{
-    if (use_armv6_instructions) {
-        /* sxth */
-        tcg_out32(s, 0x06bf0070 | (cond << 28) | (rd << 12) | rn);
-    } else {
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        rd, 0, rn, SHIFT_IMM_LSL(16));
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        rd, 0, rd, SHIFT_IMM_ASR(16));
-    }
-}
-
-static inline void tcg_out_ext16u(TCGContext *s, int cond,
-                                  int rd, int rn)
-{
-    if (use_armv6_instructions) {
-        /* uxth */
-        tcg_out32(s, 0x06ff0070 | (cond << 28) | (rd << 12) | rn);
-    } else {
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        rd, 0, rn, SHIFT_IMM_LSL(16));
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        rd, 0, rd, SHIFT_IMM_LSR(16));
-    }
-}
-
-static inline void tcg_out_bswap16s(TCGContext *s, int cond, int rd, int rn)
-{
-    if (use_armv6_instructions) {
-        /* revsh */
-        tcg_out32(s, 0x06ff0fb0 | (cond << 28) | (rd << 12) | rn);
-    } else {
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        TCG_REG_R8, 0, rn, SHIFT_IMM_LSL(24));
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        TCG_REG_R8, 0, TCG_REG_R8, SHIFT_IMM_ASR(16));
-        tcg_out_dat_reg(s, cond, ARITH_ORR,
-                        rd, TCG_REG_R8, rn, SHIFT_IMM_LSR(8));
-    }
-}
-
-static inline void tcg_out_bswap16(TCGContext *s, int cond, int rd, int rn)
-{
-    if (use_armv6_instructions) {
-        /* rev16 */
-        tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn);
-    } else {
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        TCG_REG_R8, 0, rn, SHIFT_IMM_LSL(24));
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        TCG_REG_R8, 0, TCG_REG_R8, SHIFT_IMM_LSR(16));
-        tcg_out_dat_reg(s, cond, ARITH_ORR,
-                        rd, TCG_REG_R8, rn, SHIFT_IMM_LSR(8));
-    }
-}
-
-static inline void tcg_out_bswap32(TCGContext *s, int cond, int rd, int rn)
-{
-    if (use_armv6_instructions) {
-        /* rev */
-        tcg_out32(s, 0x06bf0f30 | (cond << 28) | (rd << 12) | rn);
-    } else {
-        tcg_out_dat_reg(s, cond, ARITH_EOR,
-                        TCG_REG_R8, rn, rn, SHIFT_IMM_ROR(16));
-        tcg_out_dat_imm(s, cond, ARITH_BIC,
-                        TCG_REG_R8, TCG_REG_R8, 0xff | 0x800);
-        tcg_out_dat_reg(s, cond, ARITH_MOV,
-                        rd, 0, rn, SHIFT_IMM_ROR(8));
-        tcg_out_dat_reg(s, cond, ARITH_EOR,
-                        rd, rd, TCG_REG_R8, SHIFT_IMM_LSR(8));
-    }
-}
-
-static inline void tcg_out_ld32_12(TCGContext *s, int cond,
-                int rd, int rn, tcg_target_long im)
-{
-    if (im >= 0)
-        tcg_out32(s, (cond << 28) | 0x05900000 |
-                        (rn << 16) | (rd << 12) | (im & 0xfff));
-    else
-        tcg_out32(s, (cond << 28) | 0x05100000 |
-                        (rn << 16) | (rd << 12) | ((-im) & 0xfff));
-}
-
-static inline void tcg_out_st32_12(TCGContext *s, int cond,
-                int rd, int rn, tcg_target_long im)
-{
-    if (im >= 0)
-        tcg_out32(s, (cond << 28) | 0x05800000 |
-                        (rn << 16) | (rd << 12) | (im & 0xfff));
-    else
-        tcg_out32(s, (cond << 28) | 0x05000000 |
-                        (rn << 16) | (rd << 12) | ((-im) & 0xfff));
-}
-
-static inline void tcg_out_ld32_r(TCGContext *s, int cond,
-                int rd, int rn, int rm)
-{
-    tcg_out32(s, (cond << 28) | 0x07900000 |
-                    (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_st32_r(TCGContext *s, int cond,
-                int rd, int rn, int rm)
-{
-    tcg_out32(s, (cond << 28) | 0x07800000 |
-                    (rn << 16) | (rd << 12) | rm);
-}
-
-/* Register pre-increment with base writeback.  */
-static inline void tcg_out_ld32_rwb(TCGContext *s, int cond,
-                int rd, int rn, int rm)
-{
-    tcg_out32(s, (cond << 28) | 0x07b00000 |
-                    (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_st32_rwb(TCGContext *s, int cond,
-                int rd, int rn, int rm)
-{
-    tcg_out32(s, (cond << 28) | 0x07a00000 |
-                    (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_ld16u_8(TCGContext *s, int cond,
-                int rd, int rn, tcg_target_long im)
-{
-    if (im >= 0)
-        tcg_out32(s, (cond << 28) | 0x01d000b0 |
-                        (rn << 16) | (rd << 12) |
-                        ((im & 0xf0) << 4) | (im & 0xf));
-    else
-        tcg_out32(s, (cond << 28) | 0x015000b0 |
-                        (rn << 16) | (rd << 12) |
-                        (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
-static inline void tcg_out_st16_8(TCGContext *s, int cond,
-                int rd, int rn, tcg_target_long im)
-{
-    if (im >= 0)
-        tcg_out32(s, (cond << 28) | 0x01c000b0 |
-                        (rn << 16) | (rd << 12) |
-                        ((im & 0xf0) << 4) | (im & 0xf));
-    else
-        tcg_out32(s, (cond << 28) | 0x014000b0 |
-                        (rn << 16) | (rd << 12) |
-                        (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
-static inline void tcg_out_ld16u_r(TCGContext *s, int cond,
-                int rd, int rn, int rm)
-{
-    tcg_out32(s, (cond << 28) | 0x019000b0 |
-                    (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_st16_r(TCGContext *s, int cond,
-                int rd, int rn, int rm)
-{
-    tcg_out32(s, (cond << 28) | 0x018000b0 |
-                    (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_ld16s_8(TCGContext *s, int cond,
-                int rd, int rn, tcg_target_long im)
-{
-    if (im >= 0)
-        tcg_out32(s, (cond << 28) | 0x01d000f0 |
-                        (rn << 16) | (rd << 12) |
-                        ((im & 0xf0) << 4) | (im & 0xf));
-    else
-        tcg_out32(s, (cond << 28) | 0x015000f0 |
-                        (rn << 16) | (rd << 12) |
-                        (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
-static inline void tcg_out_ld16s_r(TCGContext *s, int cond,
-                int rd, int rn, int rm)
-{
-    tcg_out32(s, (cond << 28) | 0x019000f0 |
-                    (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_ld8_12(TCGContext *s, int cond,
-                int rd, int rn, tcg_target_long im)
-{
-    if (im >= 0)
-        tcg_out32(s, (cond << 28) | 0x05d00000 |
-                        (rn << 16) | (rd << 12) | (im & 0xfff));
-    else
-        tcg_out32(s, (cond << 28) | 0x05500000 |
-                        (rn << 16) | (rd << 12) | ((-im) & 0xfff));
-}
-
-static inline void tcg_out_st8_12(TCGContext *s, int cond,
-                int rd, int rn, tcg_target_long im)
-{
-    if (im >= 0)
-        tcg_out32(s, (cond << 28) | 0x05c00000 |
-                        (rn << 16) | (rd << 12) | (im & 0xfff));
-    else
-        tcg_out32(s, (cond << 28) | 0x05400000 |
-                        (rn << 16) | (rd << 12) | ((-im) & 0xfff));
-}
-
-static inline void tcg_out_ld8_r(TCGContext *s, int cond,
-                int rd, int rn, int rm)
-{
-    tcg_out32(s, (cond << 28) | 0x07d00000 |
-                    (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_st8_r(TCGContext *s, int cond,
-                int rd, int rn, int rm)
-{
-    tcg_out32(s, (cond << 28) | 0x07c00000 |
-                    (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_ld8s_8(TCGContext *s, int cond,
-                int rd, int rn, tcg_target_long im)
-{
-    if (im >= 0)
-        tcg_out32(s, (cond << 28) | 0x01d000d0 |
-                        (rn << 16) | (rd << 12) |
-                        ((im & 0xf0) << 4) | (im & 0xf));
-    else
-        tcg_out32(s, (cond << 28) | 0x015000d0 |
-                        (rn << 16) | (rd << 12) |
-                        (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
-static inline void tcg_out_ld8s_r(TCGContext *s, int cond,
-                int rd, int rn, int rm)
-{
-    tcg_out32(s, (cond << 28) | 0x019000d0 |
-                    (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_ld32u(TCGContext *s, int cond,
-                int rd, int rn, int32_t offset)
-{
-    if (offset > 0xfff || offset < -0xfff) {
-        tcg_out_movi32(s, cond, TCG_REG_R8, offset);
-        tcg_out_ld32_r(s, cond, rd, rn, TCG_REG_R8);
-    } else
-        tcg_out_ld32_12(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_st32(TCGContext *s, int cond,
-                int rd, int rn, int32_t offset)
-{
-    if (offset > 0xfff || offset < -0xfff) {
-        tcg_out_movi32(s, cond, TCG_REG_R8, offset);
-        tcg_out_st32_r(s, cond, rd, rn, TCG_REG_R8);
-    } else
-        tcg_out_st32_12(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_ld16u(TCGContext *s, int cond,
-                int rd, int rn, int32_t offset)
-{
-    if (offset > 0xff || offset < -0xff) {
-        tcg_out_movi32(s, cond, TCG_REG_R8, offset);
-        tcg_out_ld16u_r(s, cond, rd, rn, TCG_REG_R8);
-    } else
-        tcg_out_ld16u_8(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_ld16s(TCGContext *s, int cond,
-                int rd, int rn, int32_t offset)
-{
-    if (offset > 0xff || offset < -0xff) {
-        tcg_out_movi32(s, cond, TCG_REG_R8, offset);
-        tcg_out_ld16s_r(s, cond, rd, rn, TCG_REG_R8);
-    } else
-        tcg_out_ld16s_8(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_st16(TCGContext *s, int cond,
-                int rd, int rn, int32_t offset)
-{
-    if (offset > 0xff || offset < -0xff) {
-        tcg_out_movi32(s, cond, TCG_REG_R8, offset);
-        tcg_out_st16_r(s, cond, rd, rn, TCG_REG_R8);
-    } else
-        tcg_out_st16_8(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_ld8u(TCGContext *s, int cond,
-                int rd, int rn, int32_t offset)
-{
-    if (offset > 0xfff || offset < -0xfff) {
-        tcg_out_movi32(s, cond, TCG_REG_R8, offset);
-        tcg_out_ld8_r(s, cond, rd, rn, TCG_REG_R8);
-    } else
-        tcg_out_ld8_12(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_ld8s(TCGContext *s, int cond,
-                int rd, int rn, int32_t offset)
-{
-    if (offset > 0xff || offset < -0xff) {
-        tcg_out_movi32(s, cond, TCG_REG_R8, offset);
-        tcg_out_ld8s_r(s, cond, rd, rn, TCG_REG_R8);
-    } else
-        tcg_out_ld8s_8(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_st8(TCGContext *s, int cond,
-                int rd, int rn, int32_t offset)
-{
-    if (offset > 0xfff || offset < -0xfff) {
-        tcg_out_movi32(s, cond, TCG_REG_R8, offset);
-        tcg_out_st8_r(s, cond, rd, rn, TCG_REG_R8);
-    } else
-        tcg_out_st8_12(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_goto(TCGContext *s, int cond, uint32_t addr)
-{
-    int32_t val;
-
-    if (addr & 1) {
-        /* goto to a Thumb destination isn't supported */
-        tcg_abort();
-    }
-
-    val = addr - (tcg_target_long) s->code_ptr;
-    if (val - 8 < 0x01fffffd && val - 8 > -0x01fffffd)
-        tcg_out_b(s, cond, val);
-    else {
-#if 1
-        tcg_abort();
-#else
-        if (cond == COND_AL) {
-            tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
-            tcg_out32(s, addr); /* XXX: This is l->u.value, can we use it? */
-        } else {
-            tcg_out_movi32(s, cond, TCG_REG_R8, val - 8);
-            tcg_out_dat_reg(s, cond, ARITH_ADD,
-                            TCG_REG_PC, TCG_REG_PC,
-                            TCG_REG_R8, SHIFT_IMM_LSL(0));
-        }
-#endif
-    }
-}
-
-static inline void tcg_out_call(TCGContext *s, uint32_t addr)
-{
-    int32_t val;
-
-    val = addr - (tcg_target_long) s->code_ptr;
-    if (val - 8 < 0x02000000 && val - 8 >= -0x02000000) {
-        if (addr & 1) {
-            /* Use BLX if the target is in Thumb mode */
-            if (!use_armv5_instructions) {
-                tcg_abort();
-            }
-            tcg_out_blx_imm(s, val);
-        } else {
-            tcg_out_bl(s, COND_AL, val);
-        }
-    } else {
-#if 1
-        tcg_abort();
-#else
-        if (cond == COND_AL) {
-            tcg_out_dat_imm(s, cond, ARITH_ADD, TCG_REG_R14, TCG_REG_PC, 4);
-            tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
-            tcg_out32(s, addr); /* XXX: This is l->u.value, can we use it? */
-        } else {
-            tcg_out_movi32(s, cond, TCG_REG_R9, addr);
-            tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0,
-                            TCG_REG_PC, SHIFT_IMM_LSL(0));
-            tcg_out_bx(s, cond, TCG_REG_R9);
-        }
-#endif
-    }
-}
-
-static inline void tcg_out_callr(TCGContext *s, int cond, int arg)
-{
-    if (use_armv5_instructions) {
-        tcg_out_blx(s, cond, arg);
-    } else {
-        tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0,
-                        TCG_REG_PC, SHIFT_IMM_LSL(0));
-        tcg_out_bx(s, cond, arg);
-    }
-}
-
-static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
-{
-    TCGLabel *l = &s->labels[label_index];
-
-    if (l->has_value)
-        tcg_out_goto(s, cond, l->u.value);
-    else if (cond == COND_AL) {
-        tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
-        tcg_out_reloc(s, s->code_ptr, R_ARM_ABS32, label_index, 31337);
-        s->code_ptr += 4;
-    } else {
-        /* Probably this should be preferred even for COND_AL... */
-        tcg_out_reloc(s, s->code_ptr, R_ARM_PC24, label_index, 31337);
-        tcg_out_b_noaddr(s, cond);
-    }
-}
-
-#ifdef CONFIG_SOFTMMU
-
-#include "../../softmmu_defs.h"
-
-static void *qemu_ld_helpers[4] = {
-    __ldb_mmu,
-    __ldw_mmu,
-    __ldl_mmu,
-    __ldq_mmu,
-};
-
-static void *qemu_st_helpers[4] = {
-    __stb_mmu,
-    __stw_mmu,
-    __stl_mmu,
-    __stq_mmu,
-};
-#endif
-
-#define TLB_SHIFT	(CPU_TLB_ENTRY_BITS + CPU_TLB_BITS)
-
-static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
-{
-    int addr_reg, data_reg, data_reg2, bswap;
-#ifdef CONFIG_SOFTMMU
-    int mem_index, s_bits;
-# if TARGET_LONG_BITS == 64
-    int addr_reg2;
-# endif
-    uint32_t *label_ptr;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
-    bswap = 1;
-#else
-    bswap = 0;
-#endif
-    data_reg = *args++;
-    if (opc == 3)
-        data_reg2 = *args++;
-    else
-        data_reg2 = 0; /* suppress warning */
-    addr_reg = *args++;
-#ifdef CONFIG_SOFTMMU
-# if TARGET_LONG_BITS == 64
-    addr_reg2 = *args++;
-# endif
-    mem_index = *args;
-    s_bits = opc & 3;
-
-    /* Should generate something like the following:
-     *  shr r8, addr_reg, #TARGET_PAGE_BITS
-     *  and r0, r8, #(CPU_TLB_SIZE - 1)   @ Assumption: CPU_TLB_BITS <= 8
-     *  add r0, env, r0 lsl #CPU_TLB_ENTRY_BITS
-     */
-#  if CPU_TLB_BITS > 8
-#   error
-#  endif
-    tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_R8,
-                    0, addr_reg, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
-    tcg_out_dat_imm(s, COND_AL, ARITH_AND,
-                    TCG_REG_R0, TCG_REG_R8, CPU_TLB_SIZE - 1);
-    tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_AREG0,
-                    TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
-    /* In the
-     *  ldr r1 [r0, #(offsetof(CPUState, tlb_table[mem_index][0].addr_read))]
-     * below, the offset is likely to exceed 12 bits if mem_index != 0 and
-     * not exceed otherwise, so use an
-     *  add r0, r0, #(mem_index * sizeof *CPUState.tlb_table)
-     * before.
-     */
-    if (mem_index)
-        tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
-                        (mem_index << (TLB_SHIFT & 1)) |
-                        ((16 - (TLB_SHIFT >> 1)) << 8));
-    tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R0,
-                    offsetof(CPUState, tlb_table[0][0].addr_read));
-    tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R1,
-                    TCG_REG_R8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
-    /* Check alignment.  */
-    if (s_bits)
-        tcg_out_dat_imm(s, COND_EQ, ARITH_TST,
-                        0, addr_reg, (1 << s_bits) - 1);
-#  if TARGET_LONG_BITS == 64
-    /* XXX: possibly we could use a block data load or writeback in
-     * the first access.  */
-    tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
-                    offsetof(CPUState, tlb_table[0][0].addr_read) + 4);
-    tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
-                    TCG_REG_R1, addr_reg2, SHIFT_IMM_LSL(0));
-#  endif
-    tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
-                    offsetof(CPUState, tlb_table[0][0].addend));
-
-    switch (opc) {
-    case 0:
-        tcg_out_ld8_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
-        break;
-    case 0 | 4:
-        tcg_out_ld8s_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
-        break;
-    case 1:
-        tcg_out_ld16u_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
-        if (bswap) {
-            tcg_out_bswap16(s, COND_EQ, data_reg, data_reg);
-        }
-        break;
-    case 1 | 4:
-        if (bswap) {
-            tcg_out_ld16u_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
-            tcg_out_bswap16s(s, COND_EQ, data_reg, data_reg);
-        } else {
-            tcg_out_ld16s_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
-        }
-        break;
-    case 2:
-    default:
-        tcg_out_ld32_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
-        if (bswap) {
-            tcg_out_bswap32(s, COND_EQ, data_reg, data_reg);
-        }
-        break;
-    case 3:
-        if (bswap) {
-            tcg_out_ld32_rwb(s, COND_EQ, data_reg2, TCG_REG_R1, addr_reg);
-            tcg_out_ld32_12(s, COND_EQ, data_reg, TCG_REG_R1, 4);
-            tcg_out_bswap32(s, COND_EQ, data_reg2, data_reg2);
-            tcg_out_bswap32(s, COND_EQ, data_reg, data_reg);
-        } else {
-            tcg_out_ld32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
-            tcg_out_ld32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
-        }
-        break;
-    }
-
-    label_ptr = (void *) s->code_ptr;
-    tcg_out_b_noaddr(s, COND_EQ);
-
-    /* TODO: move this code to where the constants pool will be */
-    if (addr_reg != TCG_REG_R0) {
-        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                        TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0));
-    }
-# if TARGET_LONG_BITS == 32
-    tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R1, 0, mem_index);
-# else
-    tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                    TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
-    tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
-# endif
-    tcg_out_call(s, (tcg_target_long) qemu_ld_helpers[s_bits]);
-
-    switch (opc) {
-    case 0 | 4:
-        tcg_out_ext8s(s, COND_AL, data_reg, TCG_REG_R0);
-        break;
-    case 1 | 4:
-        tcg_out_ext16s(s, COND_AL, data_reg, TCG_REG_R0);
-        break;
-    case 0:
-    case 1:
-    case 2:
-    default:
-        if (data_reg != TCG_REG_R0) {
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            data_reg, 0, TCG_REG_R0, SHIFT_IMM_LSL(0));
-        }
-        break;
-    case 3:
-        if (data_reg != TCG_REG_R0) {
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            data_reg, 0, TCG_REG_R0, SHIFT_IMM_LSL(0));
-        }
-        if (data_reg2 != TCG_REG_R1) {
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            data_reg2, 0, TCG_REG_R1, SHIFT_IMM_LSL(0));
-        }
-        break;
-    }
-
-    reloc_pc24(label_ptr, (tcg_target_long)s->code_ptr);
-#else /* !CONFIG_SOFTMMU */
-    if (GUEST_BASE) {
-        uint32_t offset = GUEST_BASE;
-        int i;
-        int rot;
-
-        while (offset) {
-            i = ctz32(offset) & ~1;
-            rot = ((32 - i) << 7) & 0xf00;
-
-            tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R8, addr_reg,
-                            ((offset >> i) & 0xff) | rot);
-            addr_reg = TCG_REG_R8;
-            offset &= ~(0xff << i);
-        }
-    }
-    switch (opc) {
-    case 0:
-        tcg_out_ld8_12(s, COND_AL, data_reg, addr_reg, 0);
-        break;
-    case 0 | 4:
-        tcg_out_ld8s_8(s, COND_AL, data_reg, addr_reg, 0);
-        break;
-    case 1:
-        tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
-        if (bswap) {
-            tcg_out_bswap16(s, COND_AL, data_reg, data_reg);
-        }
-        break;
-    case 1 | 4:
-        if (bswap) {
-            tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
-            tcg_out_bswap16s(s, COND_AL, data_reg, data_reg);
-        } else {
-            tcg_out_ld16s_8(s, COND_AL, data_reg, addr_reg, 0);
-        }
-        break;
-    case 2:
-    default:
-        tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0);
-        if (bswap) {
-            tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
-        }
-        break;
-    case 3:
-        /* TODO: use block load -
-         * check that data_reg2 > data_reg or the other way */
-        if (data_reg == addr_reg) {
-            tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
-            tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
-        } else {
-            tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
-            tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
-        }
-        if (bswap) {
-            tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
-            tcg_out_bswap32(s, COND_AL, data_reg2, data_reg2);
-        }
-        break;
-    }
-#endif
-}
-
-static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
-{
-    int addr_reg, data_reg, data_reg2, bswap;
-#ifdef CONFIG_SOFTMMU
-    int mem_index, s_bits;
-# if TARGET_LONG_BITS == 64
-    int addr_reg2;
-# endif
-    uint32_t *label_ptr;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
-    bswap = 1;
-#else
-    bswap = 0;
-#endif
-    data_reg = *args++;
-    if (opc == 3)
-        data_reg2 = *args++;
-    else
-        data_reg2 = 0; /* suppress warning */
-    addr_reg = *args++;
-#ifdef CONFIG_SOFTMMU
-# if TARGET_LONG_BITS == 64
-    addr_reg2 = *args++;
-# endif
-    mem_index = *args;
-    s_bits = opc & 3;
-
-    /* Should generate something like the following:
-     *  shr r8, addr_reg, #TARGET_PAGE_BITS
-     *  and r0, r8, #(CPU_TLB_SIZE - 1)   @ Assumption: CPU_TLB_BITS <= 8
-     *  add r0, env, r0 lsl #CPU_TLB_ENTRY_BITS
-     */
-    tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                    TCG_REG_R8, 0, addr_reg, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
-    tcg_out_dat_imm(s, COND_AL, ARITH_AND,
-                    TCG_REG_R0, TCG_REG_R8, CPU_TLB_SIZE - 1);
-    tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R0,
-                    TCG_AREG0, TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
-    /* In the
-     *  ldr r1 [r0, #(offsetof(CPUState, tlb_table[mem_index][0].addr_write))]
-     * below, the offset is likely to exceed 12 bits if mem_index != 0 and
-     * not exceed otherwise, so use an
-     *  add r0, r0, #(mem_index * sizeof *CPUState.tlb_table)
-     * before.
-     */
-    if (mem_index)
-        tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
-                        (mem_index << (TLB_SHIFT & 1)) |
-                        ((16 - (TLB_SHIFT >> 1)) << 8));
-    tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R0,
-                    offsetof(CPUState, tlb_table[0][0].addr_write));
-    tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R1,
-                    TCG_REG_R8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
-    /* Check alignment.  */
-    if (s_bits)
-        tcg_out_dat_imm(s, COND_EQ, ARITH_TST,
-                        0, addr_reg, (1 << s_bits) - 1);
-#  if TARGET_LONG_BITS == 64
-    /* XXX: possibly we could use a block data load or writeback in
-     * the first access.  */
-    tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
-                    offsetof(CPUState, tlb_table[0][0].addr_write) + 4);
-    tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
-                    TCG_REG_R1, addr_reg2, SHIFT_IMM_LSL(0));
-#  endif
-    tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
-                    offsetof(CPUState, tlb_table[0][0].addend));
-
-    switch (opc) {
-    case 0:
-        tcg_out_st8_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
-        break;
-    case 1:
-        if (bswap) {
-            tcg_out_bswap16(s, COND_EQ, TCG_REG_R0, data_reg);
-            tcg_out_st16_r(s, COND_EQ, TCG_REG_R0, addr_reg, TCG_REG_R1);
-        } else {
-            tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
-        }
-        break;
-    case 2:
-    default:
-        if (bswap) {
-            tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
-            tcg_out_st32_r(s, COND_EQ, TCG_REG_R0, addr_reg, TCG_REG_R1);
-        } else {
-            tcg_out_st32_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
-        }
-        break;
-    case 3:
-        if (bswap) {
-            tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg2);
-            tcg_out_st32_rwb(s, COND_EQ, TCG_REG_R0, TCG_REG_R1, addr_reg);
-            tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
-            tcg_out_st32_12(s, COND_EQ, TCG_REG_R0, TCG_REG_R1, 4);
-        } else {
-            tcg_out_st32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
-            tcg_out_st32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
-        }
-        break;
-    }
-
-    label_ptr = (void *) s->code_ptr;
-    tcg_out_b_noaddr(s, COND_EQ);
-
-    /* TODO: move this code to where the constants pool will be */
-    tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                    TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0));
-# if TARGET_LONG_BITS == 32
-    switch (opc) {
-    case 0:
-        tcg_out_ext8u(s, COND_AL, TCG_REG_R1, data_reg);
-        tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
-        break;
-    case 1:
-        tcg_out_ext16u(s, COND_AL, TCG_REG_R1, data_reg);
-        tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
-        break;
-    case 2:
-        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                        TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0));
-        tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
-        break;
-    case 3:
-        tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R8, 0, mem_index);
-        tcg_out32(s, (COND_AL << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */
-        if (data_reg != TCG_REG_R2) {
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0));
-        }
-        if (data_reg2 != TCG_REG_R3) {
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            TCG_REG_R3, 0, data_reg2, SHIFT_IMM_LSL(0));
-        }
-        break;
-    }
-# else
-    tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                    TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
-    switch (opc) {
-    case 0:
-        tcg_out_ext8u(s, COND_AL, TCG_REG_R2, data_reg);
-        tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
-        break;
-    case 1:
-        tcg_out_ext16u(s, COND_AL, TCG_REG_R2, data_reg);
-        tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
-        break;
-    case 2:
-        if (data_reg != TCG_REG_R2) {
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0));
-        }
-        tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
-        break;
-    case 3:
-        tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R8, 0, mem_index);
-        tcg_out32(s, (COND_AL << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */
-        if (data_reg != TCG_REG_R2) {
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0));
-        }
-        if (data_reg2 != TCG_REG_R3) {
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            TCG_REG_R3, 0, data_reg2, SHIFT_IMM_LSL(0));
-        }
-        break;
-    }
-# endif
-
-    tcg_out_call(s, (tcg_target_long) qemu_st_helpers[s_bits]);
-    if (opc == 3)
-        tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10);
-
-    reloc_pc24(label_ptr, (tcg_target_long)s->code_ptr);
-#else /* !CONFIG_SOFTMMU */
-    if (GUEST_BASE) {
-        uint32_t offset = GUEST_BASE;
-        int i;
-        int rot;
-
-        while (offset) {
-            i = ctz32(offset) & ~1;
-            rot = ((32 - i) << 7) & 0xf00;
-
-            tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R1, addr_reg,
-                            ((offset >> i) & 0xff) | rot);
-            addr_reg = TCG_REG_R1;
-            offset &= ~(0xff << i);
-        }
-    }
-    switch (opc) {
-    case 0:
-        tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);
-        break;
-    case 1:
-        if (bswap) {
-            tcg_out_bswap16(s, COND_AL, TCG_REG_R0, data_reg);
-            tcg_out_st16_8(s, COND_AL, TCG_REG_R0, addr_reg, 0);
-        } else {
-            tcg_out_st16_8(s, COND_AL, data_reg, addr_reg, 0);
-        }
-        break;
-    case 2:
-    default:
-        if (bswap) {
-            tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
-            tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
-        } else {
-            tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
-        }
-        break;
-    case 3:
-        /* TODO: use block store -
-         * check that data_reg2 > data_reg or the other way */
-        if (bswap) {
-            tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg2);
-            tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
-            tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
-            tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 4);
-        } else {
-            tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
-            tcg_out_st32_12(s, COND_AL, data_reg2, addr_reg, 4);
-        }
-        break;
-    }
-#endif
-}
-
-static uint8_t *tb_ret_addr;
-
-static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
-                const TCGArg *args, const int *const_args)
-{
-    int c;
-
-    switch (opc) {
-    case INDEX_op_exit_tb:
-        {
-            uint8_t *ld_ptr = s->code_ptr;
-            if (args[0] >> 8)
-                tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
-            else
-                tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R0, 0, args[0]);
-            tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr);
-            if (args[0] >> 8) {
-                *ld_ptr = (uint8_t) (s->code_ptr - ld_ptr) - 8;
-                tcg_out32(s, args[0]);
-            }
-        }
-        break;
-    case INDEX_op_goto_tb:
-        if (s->tb_jmp_offset) {
-            /* Direct jump method */
-#if defined(USE_DIRECT_JUMP)
-            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
-            tcg_out_b_noaddr(s, COND_AL);
-#else
-            tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
-            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
-            tcg_out32(s, 0);
-#endif
-        } else {
-            /* Indirect jump method */
-#if 1
-            c = (int) (s->tb_next + args[0]) - ((int) s->code_ptr + 8);
-            if (c > 0xfff || c < -0xfff) {
-                tcg_out_movi32(s, COND_AL, TCG_REG_R0,
-                                (tcg_target_long) (s->tb_next + args[0]));
-                tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
-            } else
-                tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, c);
-#else
-            tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
-            tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
-            tcg_out32(s, (tcg_target_long) (s->tb_next + args[0]));
-#endif
-        }
-        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
-        break;
-    case INDEX_op_call:
-        if (const_args[0])
-            tcg_out_call(s, args[0]);
-        else
-            tcg_out_callr(s, COND_AL, args[0]);
-        break;
-    case INDEX_op_jmp:
-        if (const_args[0])
-            tcg_out_goto(s, COND_AL, args[0]);
-        else
-            tcg_out_bx(s, COND_AL, args[0]);
-        break;
-    case INDEX_op_br:
-        tcg_out_goto_label(s, COND_AL, args[0]);
-        break;
-
-    case INDEX_op_ld8u_i32:
-        tcg_out_ld8u(s, COND_AL, args[0], args[1], args[2]);
-        break;
-    case INDEX_op_ld8s_i32:
-        tcg_out_ld8s(s, COND_AL, args[0], args[1], args[2]);
-        break;
-    case INDEX_op_ld16u_i32:
-        tcg_out_ld16u(s, COND_AL, args[0], args[1], args[2]);
-        break;
-    case INDEX_op_ld16s_i32:
-        tcg_out_ld16s(s, COND_AL, args[0], args[1], args[2]);
-        break;
-    case INDEX_op_ld_i32:
-        tcg_out_ld32u(s, COND_AL, args[0], args[1], args[2]);
-        break;
-    case INDEX_op_st8_i32:
-        tcg_out_st8(s, COND_AL, args[0], args[1], args[2]);
-        break;
-    case INDEX_op_st16_i32:
-        tcg_out_st16(s, COND_AL, args[0], args[1], args[2]);
-        break;
-    case INDEX_op_st_i32:
-        tcg_out_st32(s, COND_AL, args[0], args[1], args[2]);
-        break;
-
-    case INDEX_op_mov_i32:
-        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                        args[0], 0, args[1], SHIFT_IMM_LSL(0));
-        break;
-    case INDEX_op_movi_i32:
-        tcg_out_movi32(s, COND_AL, args[0], args[1]);
-        break;
-    case INDEX_op_add_i32:
-        c = ARITH_ADD;
-        goto gen_arith;
-    case INDEX_op_sub_i32:
-        c = ARITH_SUB;
-        goto gen_arith;
-    case INDEX_op_and_i32:
-        c = ARITH_AND;
-        goto gen_arith;
-    case INDEX_op_andc_i32:
-        c = ARITH_BIC;
-        goto gen_arith;
-    case INDEX_op_or_i32:
-        c = ARITH_ORR;
-        goto gen_arith;
-    case INDEX_op_xor_i32:
-        c = ARITH_EOR;
-        /* Fall through.  */
-    gen_arith:
-        if (const_args[2]) {
-            int rot;
-            rot = encode_imm(args[2]);
-            tcg_out_dat_imm(s, COND_AL, c,
-                            args[0], args[1], rotl(args[2], rot) | (rot << 7));
-        } else
-            tcg_out_dat_reg(s, COND_AL, c,
-                            args[0], args[1], args[2], SHIFT_IMM_LSL(0));
-        break;
-    case INDEX_op_add2_i32:
-        tcg_out_dat_reg2(s, COND_AL, ARITH_ADD, ARITH_ADC,
-                        args[0], args[1], args[2], args[3],
-                        args[4], args[5], SHIFT_IMM_LSL(0));
-        break;
-    case INDEX_op_sub2_i32:
-        tcg_out_dat_reg2(s, COND_AL, ARITH_SUB, ARITH_SBC,
-                        args[0], args[1], args[2], args[3],
-                        args[4], args[5], SHIFT_IMM_LSL(0));
-        break;
-    case INDEX_op_neg_i32:
-        tcg_out_dat_imm(s, COND_AL, ARITH_RSB, args[0], args[1], 0);
-        break;
-    case INDEX_op_not_i32:
-        tcg_out_dat_reg(s, COND_AL,
-                        ARITH_MVN, args[0], 0, args[1], SHIFT_IMM_LSL(0));
-        break;
-    case INDEX_op_mul_i32:
-        tcg_out_mul32(s, COND_AL, args[0], args[1], args[2]);
-        break;
-    case INDEX_op_mulu2_i32:
-        tcg_out_umull32(s, COND_AL, args[0], args[1], args[2], args[3]);
-        break;
-    /* XXX: Perhaps args[2] & 0x1f is wrong */
-    case INDEX_op_shl_i32:
-        c = const_args[2] ?
-                SHIFT_IMM_LSL(args[2] & 0x1f) : SHIFT_REG_LSL(args[2]);
-        goto gen_shift32;
-    case INDEX_op_shr_i32:
-        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_LSR(args[2] & 0x1f) :
-                SHIFT_IMM_LSL(0) : SHIFT_REG_LSR(args[2]);
-        goto gen_shift32;
-    case INDEX_op_sar_i32:
-        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ASR(args[2] & 0x1f) :
-                SHIFT_IMM_LSL(0) : SHIFT_REG_ASR(args[2]);
-        goto gen_shift32;
-    case INDEX_op_rotr_i32:
-        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ROR(args[2] & 0x1f) :
-                SHIFT_IMM_LSL(0) : SHIFT_REG_ROR(args[2]);
-        /* Fall through.  */
-    gen_shift32:
-        tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1], c);
-        break;
-
-    case INDEX_op_rotl_i32:
-        if (const_args[2]) {
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
-                            ((0x20 - args[2]) & 0x1f) ?
-                            SHIFT_IMM_ROR((0x20 - args[2]) & 0x1f) :
-                            SHIFT_IMM_LSL(0));
-        } else {
-            tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_R8, args[1], 0x20);
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
-                            SHIFT_REG_ROR(TCG_REG_R8));
-        }
-        break;
-
-    case INDEX_op_brcond_i32:
-        if (const_args[1]) {
-            int rot;
-            rot = encode_imm(args[1]);
-            tcg_out_dat_imm(s, COND_AL, ARITH_CMP, 0,
-                            args[0], rotl(args[1], rot) | (rot << 7));
-        } else {
-            tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,
-                            args[0], args[1], SHIFT_IMM_LSL(0));
-        }
-        tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]], args[3]);
-        break;
-    case INDEX_op_brcond2_i32:
-        /* The resulting conditions are:
-         * TCG_COND_EQ    -->  a0 == a2 && a1 == a3,
-         * TCG_COND_NE    --> (a0 != a2 && a1 == a3) ||  a1 != a3,
-         * TCG_COND_LT(U) --> (a0 <  a2 && a1 == a3) ||  a1 <  a3,
-         * TCG_COND_GE(U) --> (a0 >= a2 && a1 == a3) || (a1 >= a3 && a1 != a3),
-         * TCG_COND_LE(U) --> (a0 <= a2 && a1 == a3) || (a1 <= a3 && a1 != a3),
-         * TCG_COND_GT(U) --> (a0 >  a2 && a1 == a3) ||  a1 >  a3,
-         */
-        tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,
-                        args[1], args[3], SHIFT_IMM_LSL(0));
-        tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
-                        args[0], args[2], SHIFT_IMM_LSL(0));
-        tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[4]], args[5]);
-        break;
-    case INDEX_op_setcond_i32:
-        if (const_args[2]) {
-            int rot;
-            rot = encode_imm(args[2]);
-            tcg_out_dat_imm(s, COND_AL, ARITH_CMP, 0,
-                            args[1], rotl(args[2], rot) | (rot << 7));
-        } else {
-            tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,
-                            args[1], args[2], SHIFT_IMM_LSL(0));
-        }
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
-                        ARITH_MOV, args[0], 0, 1);
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
-                        ARITH_MOV, args[0], 0, 0);
-        break;
-    case INDEX_op_setcond2_i32:
-        /* See brcond2_i32 comment */
-        tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,
-                        args[2], args[4], SHIFT_IMM_LSL(0));
-        tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
-                        args[1], args[3], SHIFT_IMM_LSL(0));
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[5]],
-                        ARITH_MOV, args[0], 0, 1);
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[5])],
-                        ARITH_MOV, args[0], 0, 0);
-        break;
-
-    case INDEX_op_qemu_ld8u:
-        tcg_out_qemu_ld(s, args, 0);
-        break;
-    case INDEX_op_qemu_ld8s:
-        tcg_out_qemu_ld(s, args, 0 | 4);
-        break;
-    case INDEX_op_qemu_ld16u:
-        tcg_out_qemu_ld(s, args, 1);
-        break;
-    case INDEX_op_qemu_ld16s:
-        tcg_out_qemu_ld(s, args, 1 | 4);
-        break;
-    case INDEX_op_qemu_ld32:
-        tcg_out_qemu_ld(s, args, 2);
-        break;
-    case INDEX_op_qemu_ld64:
-        tcg_out_qemu_ld(s, args, 3);
-        break;
-
-    case INDEX_op_qemu_st8:
-        tcg_out_qemu_st(s, args, 0);
-        break;
-    case INDEX_op_qemu_st16:
-        tcg_out_qemu_st(s, args, 1);
-        break;
-    case INDEX_op_qemu_st32:
-        tcg_out_qemu_st(s, args, 2);
-        break;
-    case INDEX_op_qemu_st64:
-        tcg_out_qemu_st(s, args, 3);
-        break;
-
-    case INDEX_op_bswap16_i32:
-        tcg_out_bswap16(s, COND_AL, args[0], args[1]);
-        break;
-    case INDEX_op_bswap32_i32:
-        tcg_out_bswap32(s, COND_AL, args[0], args[1]);
-        break;
-
-    case INDEX_op_ext8s_i32:
-        tcg_out_ext8s(s, COND_AL, args[0], args[1]);
-        break;
-    case INDEX_op_ext16s_i32:
-        tcg_out_ext16s(s, COND_AL, args[0], args[1]);
-        break;
-    case INDEX_op_ext16u_i32:
-        tcg_out_ext16u(s, COND_AL, args[0], args[1]);
-        break;
-
-    default:
-        tcg_abort();
-    }
-}
-
-static const TCGTargetOpDef arm_op_defs[] = {
-    { INDEX_op_exit_tb, { } },
-    { INDEX_op_goto_tb, { } },
-    { INDEX_op_call, { "ri" } },
-    { INDEX_op_jmp, { "ri" } },
-    { INDEX_op_br, { } },
-
-    { INDEX_op_mov_i32, { "r", "r" } },
-    { INDEX_op_movi_i32, { "r" } },
-
-    { INDEX_op_ld8u_i32, { "r", "r" } },
-    { INDEX_op_ld8s_i32, { "r", "r" } },
-    { INDEX_op_ld16u_i32, { "r", "r" } },
-    { INDEX_op_ld16s_i32, { "r", "r" } },
-    { INDEX_op_ld_i32, { "r", "r" } },
-    { INDEX_op_st8_i32, { "r", "r" } },
-    { INDEX_op_st16_i32, { "r", "r" } },
-    { INDEX_op_st_i32, { "r", "r" } },
-
-    /* TODO: "r", "r", "ri" */
-    { INDEX_op_add_i32, { "r", "r", "rI" } },
-    { INDEX_op_sub_i32, { "r", "r", "rI" } },
-    { INDEX_op_mul_i32, { "r", "r", "r" } },
-    { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
-    { INDEX_op_and_i32, { "r", "r", "rI" } },
-    { INDEX_op_andc_i32, { "r", "r", "rI" } },
-    { INDEX_op_or_i32, { "r", "r", "rI" } },
-    { INDEX_op_xor_i32, { "r", "r", "rI" } },
-    { INDEX_op_neg_i32, { "r", "r" } },
-    { INDEX_op_not_i32, { "r", "r" } },
-
-    { INDEX_op_shl_i32, { "r", "r", "ri" } },
-    { INDEX_op_shr_i32, { "r", "r", "ri" } },
-    { INDEX_op_sar_i32, { "r", "r", "ri" } },
-    { INDEX_op_rotl_i32, { "r", "r", "ri" } },
-    { INDEX_op_rotr_i32, { "r", "r", "ri" } },
-
-    { INDEX_op_brcond_i32, { "r", "rI" } },
-    { INDEX_op_setcond_i32, { "r", "r", "rI" } },
-
-    /* TODO: "r", "r", "r", "r", "ri", "ri" */
-    { INDEX_op_add2_i32, { "r", "r", "r", "r", "r", "r" } },
-    { INDEX_op_sub2_i32, { "r", "r", "r", "r", "r", "r" } },
-    { INDEX_op_brcond2_i32, { "r", "r", "r", "r" } },
-    { INDEX_op_setcond2_i32, { "r", "r", "r", "r", "r" } },
-
-#if TARGET_LONG_BITS == 32
-    { INDEX_op_qemu_ld8u, { "r", "l" } },
-    { INDEX_op_qemu_ld8s, { "r", "l" } },
-    { INDEX_op_qemu_ld16u, { "r", "l" } },
-    { INDEX_op_qemu_ld16s, { "r", "l" } },
-    { INDEX_op_qemu_ld32, { "r", "l" } },
-    { INDEX_op_qemu_ld64, { "L", "L", "l" } },
-
-    { INDEX_op_qemu_st8, { "s", "s" } },
-    { INDEX_op_qemu_st16, { "s", "s" } },
-    { INDEX_op_qemu_st32, { "s", "s" } },
-    { INDEX_op_qemu_st64, { "S", "S", "s" } },
-#else
-    { INDEX_op_qemu_ld8u, { "r", "l", "l" } },
-    { INDEX_op_qemu_ld8s, { "r", "l", "l" } },
-    { INDEX_op_qemu_ld16u, { "r", "l", "l" } },
-    { INDEX_op_qemu_ld16s, { "r", "l", "l" } },
-    { INDEX_op_qemu_ld32, { "r", "l", "l" } },
-    { INDEX_op_qemu_ld64, { "L", "L", "l", "l" } },
-
-    { INDEX_op_qemu_st8, { "s", "s", "s" } },
-    { INDEX_op_qemu_st16, { "s", "s", "s" } },
-    { INDEX_op_qemu_st32, { "s", "s", "s" } },
-    { INDEX_op_qemu_st64, { "S", "S", "s", "s" } },
-#endif
-
-    { INDEX_op_bswap16_i32, { "r", "r" } },
-    { INDEX_op_bswap32_i32, { "r", "r" } },
-
-    { INDEX_op_ext8s_i32, { "r", "r" } },
-    { INDEX_op_ext16s_i32, { "r", "r" } },
-    { INDEX_op_ext16u_i32, { "r", "r" } },
-
-    { -1 },
-};
-
-static void tcg_target_init(TCGContext *s)
-{
-#if !defined(CONFIG_USER_ONLY)
-    /* fail safe */
-    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
-        tcg_abort();
-#endif
-
-    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
-    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
-                     (1 << TCG_REG_R0) |
-                     (1 << TCG_REG_R1) |
-                     (1 << TCG_REG_R2) |
-                     (1 << TCG_REG_R3) |
-                     (1 << TCG_REG_R12) |
-                     (1 << TCG_REG_R14));
-
-    tcg_regset_clear(s->reserved_regs);
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R8);
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);
-
-    tcg_add_target_add_op_defs(arm_op_defs);
-}
-
-static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg,
-                int arg1, tcg_target_long arg2)
-{
-    tcg_out_ld32u(s, COND_AL, arg, arg1, arg2);
-}
-
-static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
-                int arg1, tcg_target_long arg2)
-{
-    tcg_out_st32(s, COND_AL, arg, arg1, arg2);
-}
-
-static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
-    if (val > 0)
-        if (val < 0x100)
-            tcg_out_dat_imm(s, COND_AL, ARITH_ADD, reg, reg, val);
-        else
-            tcg_abort();
-    else if (val < 0) {
-        if (val > -0x100)
-            tcg_out_dat_imm(s, COND_AL, ARITH_SUB, reg, reg, -val);
-        else
-            tcg_abort();
-    }
-}
-
-static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg)
-{
-    tcg_out_dat_reg(s, COND_AL, ARITH_MOV, ret, 0, arg, SHIFT_IMM_LSL(0));
-}
-
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
-                int ret, tcg_target_long arg)
-{
-    tcg_out_movi32(s, COND_AL, ret, arg);
-}
-
-static void tcg_target_qemu_prologue(TCGContext *s)
-{
-    /* There is no need to save r7, it is used to store the address
-       of the env structure and is not modified by GCC. */
-
-    /* stmdb sp!, { r4 - r6, r8 - r11, lr } */
-    tcg_out32(s, (COND_AL << 28) | 0x092d4f70);
-
-    tcg_out_bx(s, COND_AL, TCG_REG_R0);
-    tb_ret_addr = s->code_ptr;
-
-    /* ldmia sp!, { r4 - r6, r8 - r11, pc } */
-    tcg_out32(s, (COND_AL << 28) | 0x08bd8f70);
-}
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
deleted file mode 100644
index d8d7d94..0000000
--- a/tcg/arm/tcg-target.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- * Copyright (c) 2008 Andrzej Zaborowski
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define TCG_TARGET_ARM 1
-
-#define TCG_TARGET_REG_BITS 32
-#undef TCG_TARGET_WORDS_BIGENDIAN
-#undef TCG_TARGET_STACK_GROWSUP
-
-enum {
-    TCG_REG_R0 = 0,
-    TCG_REG_R1,
-    TCG_REG_R2,
-    TCG_REG_R3,
-    TCG_REG_R4,
-    TCG_REG_R5,
-    TCG_REG_R6,
-    TCG_REG_R7,
-    TCG_REG_R8,
-    TCG_REG_R9,
-    TCG_REG_R10,
-    TCG_REG_R11,
-    TCG_REG_R12,
-    TCG_REG_R13,
-    TCG_REG_R14,
-    TCG_REG_PC,
-};
-
-#define TCG_TARGET_NB_REGS 16
-
-#define TCG_CT_CONST_ARM 0x100
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK		TCG_REG_R13
-#define TCG_TARGET_STACK_ALIGN		8
-#define TCG_TARGET_CALL_ALIGN_ARGS	1
-#define TCG_TARGET_CALL_STACK_OFFSET	0
-
-/* optional instructions */
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#undef TCG_TARGET_HAS_ext8u_i32       /* and r0, r1, #0xff */
-#define TCG_TARGET_HAS_ext16u_i32
-#define TCG_TARGET_HAS_bswap16_i32
-#define TCG_TARGET_HAS_bswap32_i32
-#define TCG_TARGET_HAS_not_i32
-#define TCG_TARGET_HAS_neg_i32
-#define TCG_TARGET_HAS_rot_i32
-#define TCG_TARGET_HAS_andc_i32
-// #define TCG_TARGET_HAS_orc_i32
-// #define TCG_TARGET_HAS_eqv_i32
-// #define TCG_TARGET_HAS_nand_i32
-// #define TCG_TARGET_HAS_nor_i32
-
-#define TCG_TARGET_HAS_GUEST_BASE
-
-enum {
-    /* Note: must be synced with dyngen-exec.h */
-    TCG_AREG0 = TCG_REG_R7,
-};
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-#if QEMU_GNUC_PREREQ(4, 1)
-    __builtin___clear_cache((char *) start, (char *) stop);
-#else
-    register unsigned long _beg __asm ("a1") = start;
-    register unsigned long _end __asm ("a2") = stop;
-    register unsigned long _flg __asm ("a3") = 0;
-    __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
-#endif
-}
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index 7f4653e..2ecb683 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -1033,13 +1033,13 @@
     lab1 = gen_new_label();
     lab2 = gen_new_label();
 
-    offset = offsetof(CPUState, tlb_table[mem_index][0].addr_read);
+    offset = offsetof(CPUOldState, tlb_table[mem_index][0].addr_read);
     offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg, addrhi_reg,
                               opc & 3, lab1, offset);
 
     /* TLB Hit.  */
     tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : TCG_REG_R25),
-               offsetof(CPUState, tlb_table[mem_index][0].addend) - offset);
+               offsetof(CPUOldState, tlb_table[mem_index][0].addend) - offset);
     tcg_out_qemu_ld_direct(s, datalo_reg, datahi_reg, addrlo_reg, TCG_REG_R20, opc);
     tcg_out_branch(s, lab2, 1);
 
@@ -1148,13 +1148,13 @@
     lab1 = gen_new_label();
     lab2 = gen_new_label();
 
-    offset = offsetof(CPUState, tlb_table[mem_index][0].addr_write);
+    offset = offsetof(CPUOldState, tlb_table[mem_index][0].addr_write);
     offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg, addrhi_reg,
                               opc, lab1, offset);
 
     /* TLB Hit.  */
     tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : TCG_REG_R25),
-               offsetof(CPUState, tlb_table[mem_index][0].addend) - offset);
+               offsetof(CPUOldState, tlb_table[mem_index][0].addend) - offset);
 
     /* There are no indexed stores, so we must do this addition explitly.
        Careful to avoid R20, which is used for the bswaps to follow.  */
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 6f4b537..28ae003 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1026,7 +1026,7 @@
                 (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
 
     tcg_out_modrm_sib_offset(s, OPC_LEA + P_REXW, r1, TCG_AREG0, r1, 0,
-                             offsetof(CPUState, tlb_table[mem_index][0])
+                             offsetof(CPUOldState, tlb_table[mem_index][0])
                              + which);
 
     /* cmp 0(r1), r0 */
diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
deleted file mode 100644
index 7970268..0000000
--- a/tcg/ppc/tcg-target.c
+++ /dev/null
@@ -1,1922 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 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.
- */
-
-static uint8_t *tb_ret_addr;
-
-#ifdef _CALL_DARWIN
-#define LINKAGE_AREA_SIZE 24
-#define LR_OFFSET 8
-#elif defined _CALL_AIX
-#define LINKAGE_AREA_SIZE 52
-#define LR_OFFSET 8
-#else
-#define LINKAGE_AREA_SIZE 8
-#define LR_OFFSET 4
-#endif
-
-#define FAST_PATH
-
-#ifndef GUEST_BASE
-#define GUEST_BASE 0
-#endif
-
-#ifdef CONFIG_USE_GUEST_BASE
-#define TCG_GUEST_BASE_REG 30
-#else
-#define TCG_GUEST_BASE_REG 0
-#endif
-
-#ifndef NDEBUG
-static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
-    "r0",
-    "r1",
-    "r2",
-    "r3",
-    "r4",
-    "r5",
-    "r6",
-    "r7",
-    "r8",
-    "r9",
-    "r10",
-    "r11",
-    "r12",
-    "r13",
-    "r14",
-    "r15",
-    "r16",
-    "r17",
-    "r18",
-    "r19",
-    "r20",
-    "r21",
-    "r22",
-    "r23",
-    "r24",
-    "r25",
-    "r26",
-    "r27",
-    "r28",
-    "r29",
-    "r30",
-    "r31"
-};
-#endif
-
-static const int tcg_target_reg_alloc_order[] = {
-    TCG_REG_R14,
-    TCG_REG_R15,
-    TCG_REG_R16,
-    TCG_REG_R17,
-    TCG_REG_R18,
-    TCG_REG_R19,
-    TCG_REG_R20,
-    TCG_REG_R21,
-    TCG_REG_R22,
-    TCG_REG_R23,
-    TCG_REG_R28,
-    TCG_REG_R29,
-    TCG_REG_R30,
-    TCG_REG_R31,
-#ifdef _CALL_DARWIN
-    TCG_REG_R2,
-#endif
-    TCG_REG_R3,
-    TCG_REG_R4,
-    TCG_REG_R5,
-    TCG_REG_R6,
-    TCG_REG_R7,
-    TCG_REG_R8,
-    TCG_REG_R9,
-    TCG_REG_R10,
-#ifndef _CALL_DARWIN
-    TCG_REG_R11,
-#endif
-    TCG_REG_R12,
-#ifndef _CALL_SYSV
-    TCG_REG_R13,
-#endif
-    TCG_REG_R24,
-    TCG_REG_R25,
-    TCG_REG_R26,
-    TCG_REG_R27
-};
-
-static const int tcg_target_call_iarg_regs[] = {
-    TCG_REG_R3,
-    TCG_REG_R4,
-    TCG_REG_R5,
-    TCG_REG_R6,
-    TCG_REG_R7,
-    TCG_REG_R8,
-    TCG_REG_R9,
-    TCG_REG_R10
-};
-
-static const int tcg_target_call_oarg_regs[2] = {
-    TCG_REG_R3,
-    TCG_REG_R4
-};
-
-static const int tcg_target_callee_save_regs[] = {
-#ifdef _CALL_DARWIN
-    TCG_REG_R11,
-    TCG_REG_R13,
-#endif
-#ifdef _CALL_AIX
-    TCG_REG_R13,
-#endif
-    TCG_REG_R14,
-    TCG_REG_R15,
-    TCG_REG_R16,
-    TCG_REG_R17,
-    TCG_REG_R18,
-    TCG_REG_R19,
-    TCG_REG_R20,
-    TCG_REG_R21,
-    TCG_REG_R22,
-    TCG_REG_R23,
-    TCG_REG_R24,
-    TCG_REG_R25,
-    TCG_REG_R26,
-    /* TCG_REG_R27, */ /* currently used for the global env, so no
-                          need to save */
-    TCG_REG_R28,
-    TCG_REG_R29,
-    TCG_REG_R30,
-    TCG_REG_R31
-};
-
-static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
-{
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long) pc;
-    if ((disp << 6) >> 6 != disp)
-        tcg_abort ();
-
-    return disp & 0x3fffffc;
-}
-
-static void reloc_pc24 (void *pc, tcg_target_long target)
-{
-    *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
-        | reloc_pc24_val (pc, target);
-}
-
-static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
-{
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long) pc;
-    if (disp != (int16_t) disp)
-        tcg_abort ();
-
-    return disp & 0xfffc;
-}
-
-static void reloc_pc14 (void *pc, tcg_target_long target)
-{
-    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
-        | reloc_pc14_val (pc, target);
-}
-
-static void patch_reloc(uint8_t *code_ptr, int type,
-                        tcg_target_long value, tcg_target_long addend)
-{
-    value += addend;
-    switch (type) {
-    case R_PPC_REL14:
-        reloc_pc14 (code_ptr, value);
-        break;
-    case R_PPC_REL24:
-        reloc_pc24 (code_ptr, value);
-        break;
-    default:
-        tcg_abort();
-    }
-}
-
-/* maximum number of register used for input function arguments */
-static int tcg_target_get_call_iarg_regs_count(int flags)
-{
-    return ARRAY_SIZE (tcg_target_call_iarg_regs);
-}
-
-/* parse target specific constraints */
-static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
-{
-    const char *ct_str;
-
-    ct_str = *pct_str;
-    switch (ct_str[0]) {
-    case 'A': case 'B': case 'C': case 'D':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A');
-        break;
-    case 'r':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
-        break;
-#ifdef CONFIG_SOFTMMU
-    case 'L':                   /* qemu_ld constraint */
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
-        break;
-    case 'K':                   /* qemu_st[8..32] constraint */
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
-#if TARGET_LONG_BITS == 64
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
-#endif
-        break;
-    case 'M':                   /* qemu_st64 constraint */
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
-        break;
-#else
-    case 'L':
-    case 'K':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
-        break;
-    case 'M':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
-        break;
-#endif
-    default:
-        return -1;
-    }
-    ct_str++;
-    *pct_str = ct_str;
-    return 0;
-}
-
-/* test if a constant matches the constraint */
-static int tcg_target_const_match(tcg_target_long val,
-                                  const TCGArgConstraint *arg_ct)
-{
-    int ct;
-
-    ct = arg_ct->ct;
-    if (ct & TCG_CT_CONST)
-        return 1;
-    return 0;
-}
-
-#define OPCD(opc) ((opc)<<26)
-#define XO31(opc) (OPCD(31)|((opc)<<1))
-#define XO19(opc) (OPCD(19)|((opc)<<1))
-
-#define B      OPCD(18)
-#define BC     OPCD(16)
-#define LBZ    OPCD(34)
-#define LHZ    OPCD(40)
-#define LHA    OPCD(42)
-#define LWZ    OPCD(32)
-#define STB    OPCD(38)
-#define STH    OPCD(44)
-#define STW    OPCD(36)
-
-#define ADDIC  OPCD(12)
-#define ADDI   OPCD(14)
-#define ADDIS  OPCD(15)
-#define ORI    OPCD(24)
-#define ORIS   OPCD(25)
-#define XORI   OPCD(26)
-#define XORIS  OPCD(27)
-#define ANDI   OPCD(28)
-#define ANDIS  OPCD(29)
-#define MULLI  OPCD( 7)
-#define CMPLI  OPCD(10)
-#define CMPI   OPCD(11)
-#define SUBFIC OPCD( 8)
-
-#define LWZU   OPCD(33)
-#define STWU   OPCD(37)
-
-#define RLWIMI OPCD(20)
-#define RLWINM OPCD(21)
-#define RLWNM  OPCD(23)
-
-#define BCLR   XO19( 16)
-#define BCCTR  XO19(528)
-#define CRAND  XO19(257)
-#define CRANDC XO19(129)
-#define CRNAND XO19(225)
-#define CROR   XO19(449)
-#define CRNOR  XO19( 33)
-
-#define EXTSB  XO31(954)
-#define EXTSH  XO31(922)
-#define ADD    XO31(266)
-#define ADDE   XO31(138)
-#define ADDC   XO31( 10)
-#define AND    XO31( 28)
-#define SUBF   XO31( 40)
-#define SUBFC  XO31(  8)
-#define SUBFE  XO31(136)
-#define OR     XO31(444)
-#define XOR    XO31(316)
-#define MULLW  XO31(235)
-#define MULHWU XO31( 11)
-#define DIVW   XO31(491)
-#define DIVWU  XO31(459)
-#define CMP    XO31(  0)
-#define CMPL   XO31( 32)
-#define LHBRX  XO31(790)
-#define LWBRX  XO31(534)
-#define STHBRX XO31(918)
-#define STWBRX XO31(662)
-#define MFSPR  XO31(339)
-#define MTSPR  XO31(467)
-#define SRAWI  XO31(824)
-#define NEG    XO31(104)
-#define MFCR   XO31( 19)
-#define CNTLZW XO31( 26)
-#define NOR    XO31(124)
-#define ANDC   XO31( 60)
-#define ORC    XO31(412)
-#define EQV    XO31(284)
-#define NAND   XO31(476)
-
-#define LBZX   XO31( 87)
-#define LHZX   XO31(279)
-#define LHAX   XO31(343)
-#define LWZX   XO31( 23)
-#define STBX   XO31(215)
-#define STHX   XO31(407)
-#define STWX   XO31(151)
-
-#define SPR(a,b) ((((a)<<5)|(b))<<11)
-#define LR     SPR(8, 0)
-#define CTR    SPR(9, 0)
-
-#define SLW    XO31( 24)
-#define SRW    XO31(536)
-#define SRAW   XO31(792)
-
-#define TW     XO31(4)
-#define TRAP   (TW | TO (31))
-
-#define RT(r) ((r)<<21)
-#define RS(r) ((r)<<21)
-#define RA(r) ((r)<<16)
-#define RB(r) ((r)<<11)
-#define TO(t) ((t)<<21)
-#define SH(s) ((s)<<11)
-#define MB(b) ((b)<<6)
-#define ME(e) ((e)<<1)
-#define BO(o) ((o)<<21)
-
-#define LK    1
-
-#define TAB(t,a,b) (RT(t) | RA(a) | RB(b))
-#define SAB(s,a,b) (RS(s) | RA(a) | RB(b))
-
-#define BF(n)    ((n)<<23)
-#define BI(n, c) (((c)+((n)*4))<<16)
-#define BT(n, c) (((c)+((n)*4))<<21)
-#define BA(n, c) (((c)+((n)*4))<<16)
-#define BB(n, c) (((c)+((n)*4))<<11)
-
-#define BO_COND_TRUE  BO (12)
-#define BO_COND_FALSE BO (4)
-#define BO_ALWAYS     BO (20)
-
-enum {
-    CR_LT,
-    CR_GT,
-    CR_EQ,
-    CR_SO
-};
-
-static const uint32_t tcg_to_bc[10] = {
-    [TCG_COND_EQ]  = BC | BI (7, CR_EQ) | BO_COND_TRUE,
-    [TCG_COND_NE]  = BC | BI (7, CR_EQ) | BO_COND_FALSE,
-    [TCG_COND_LT]  = BC | BI (7, CR_LT) | BO_COND_TRUE,
-    [TCG_COND_GE]  = BC | BI (7, CR_LT) | BO_COND_FALSE,
-    [TCG_COND_LE]  = BC | BI (7, CR_GT) | BO_COND_FALSE,
-    [TCG_COND_GT]  = BC | BI (7, CR_GT) | BO_COND_TRUE,
-    [TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
-    [TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
-    [TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
-    [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
-};
-
-static void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg)
-{
-    tcg_out32 (s, OR | SAB (arg, ret, arg));
-}
-
-static void tcg_out_movi(TCGContext *s, TCGType type,
-                         int ret, tcg_target_long arg)
-{
-    if (arg == (int16_t) arg)
-        tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff));
-    else {
-        tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
-        if (arg & 0xffff)
-            tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
-    }
-}
-
-static void tcg_out_ldst (TCGContext *s, int ret, int addr,
-                          int offset, int op1, int op2)
-{
-    if (offset == (int16_t) offset)
-        tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
-    else {
-        tcg_out_movi (s, TCG_TYPE_I32, 0, offset);
-        tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
-    }
-}
-
-static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
-{
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long) s->code_ptr;
-    if ((disp << 6) >> 6 == disp)
-        tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
-    else {
-        tcg_out_movi (s, TCG_TYPE_I32, 0, (tcg_target_long) target);
-        tcg_out32 (s, MTSPR | RS (0) | CTR);
-        tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
-    }
-}
-
-static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
-{
-#ifdef _CALL_AIX
-    int reg;
-
-    if (const_arg) {
-        reg = 2;
-        tcg_out_movi (s, TCG_TYPE_I32, reg, arg);
-    }
-    else reg = arg;
-
-    tcg_out32 (s, LWZ | RT (0) | RA (reg));
-    tcg_out32 (s, MTSPR | RA (0) | CTR);
-    tcg_out32 (s, LWZ | RT (2) | RA (reg) | 4);
-    tcg_out32 (s, BCCTR | BO_ALWAYS | LK);
-#else
-    if (const_arg) {
-        tcg_out_b (s, LK, arg);
-    }
-    else {
-        tcg_out32 (s, MTSPR | RS (arg) | LR);
-        tcg_out32 (s, BCLR | BO_ALWAYS | LK);
-    }
-#endif
-}
-
-#if defined(CONFIG_SOFTMMU)
-
-#include "../../softmmu_defs.h"
-
-static void *qemu_ld_helpers[4] = {
-    __ldb_mmu,
-    __ldw_mmu,
-    __ldl_mmu,
-    __ldq_mmu,
-};
-
-static void *qemu_st_helpers[4] = {
-    __stb_mmu,
-    __stw_mmu,
-    __stl_mmu,
-    __stq_mmu,
-};
-#endif
-
-static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
-{
-    int addr_reg, data_reg, data_reg2, r0, r1, rbase, mem_index, s_bits, bswap;
-#ifdef CONFIG_SOFTMMU
-    int r2;
-    void *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
-    int addr_reg2;
-#endif
-
-    data_reg = *args++;
-    if (opc == 3)
-        data_reg2 = *args++;
-    else
-        data_reg2 = 0;
-    addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
-    addr_reg2 = *args++;
-#endif
-    mem_index = *args;
-    s_bits = opc & 3;
-
-#ifdef CONFIG_SOFTMMU
-    r0 = 3;
-    r1 = 4;
-    r2 = 0;
-    rbase = 0;
-
-    tcg_out32 (s, (RLWINM
-                   | RA (r0)
-                   | RS (addr_reg)
-                   | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
-                   | MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS))
-                   | ME (31 - CPU_TLB_ENTRY_BITS)
-                   )
-        );
-    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
-    tcg_out32 (s, (LWZU
-                   | RT (r1)
-                   | RA (r0)
-                   | offsetof (CPUState, tlb_table[mem_index][0].addr_read)
-                   )
-        );
-    tcg_out32 (s, (RLWINM
-                   | RA (r2)
-                   | RS (addr_reg)
-                   | SH (0)
-                   | MB ((32 - s_bits) & 31)
-                   | ME (31 - TARGET_PAGE_BITS)
-                   )
-        );
-
-    tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1));
-#if TARGET_LONG_BITS == 64
-    tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4);
-    tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1));
-    tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
-#endif
-
-    label1_ptr = s->code_ptr;
-#ifdef FAST_PATH
-    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
-#endif
-
-    /* slow path */
-#if TARGET_LONG_BITS == 32
-    tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg);
-    tcg_out_movi (s, TCG_TYPE_I32, 4, mem_index);
-#else
-    tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg2);
-    tcg_out_mov (s, TCG_TYPE_I32, 4, addr_reg);
-    tcg_out_movi (s, TCG_TYPE_I32, 5, mem_index);
-#endif
-
-    tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
-    switch (opc) {
-    case 0|4:
-        tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
-        break;
-    case 1|4:
-        tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
-        break;
-    case 0:
-    case 1:
-    case 2:
-        if (data_reg != 3)
-            tcg_out_mov (s, TCG_TYPE_I32, data_reg, 3);
-        break;
-    case 3:
-        if (data_reg == 3) {
-            if (data_reg2 == 4) {
-                tcg_out_mov (s, TCG_TYPE_I32, 0, 4);
-                tcg_out_mov (s, TCG_TYPE_I32, 4, 3);
-                tcg_out_mov (s, TCG_TYPE_I32, 3, 0);
-            }
-            else {
-                tcg_out_mov (s, TCG_TYPE_I32, data_reg2, 3);
-                tcg_out_mov (s, TCG_TYPE_I32, 3, 4);
-            }
-        }
-        else {
-            if (data_reg != 4) tcg_out_mov (s, TCG_TYPE_I32, data_reg, 4);
-            if (data_reg2 != 3) tcg_out_mov (s, TCG_TYPE_I32, data_reg2, 3);
-        }
-        break;
-    }
-    label2_ptr = s->code_ptr;
-    tcg_out32 (s, B);
-
-    /* label1: fast path */
-#ifdef FAST_PATH
-    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
-#endif
-
-    /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
-    tcg_out32 (s, (LWZ
-                   | RT (r0)
-                   | RA (r0)
-                   | (offsetof (CPUTLBEntry, addend)
-                      - offsetof (CPUTLBEntry, addr_read))
-                   ));
-    /* r0 = env->tlb_table[mem_index][index].addend */
-    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
-    /* r0 = env->tlb_table[mem_index][index].addend + addr */
-
-#else  /* !CONFIG_SOFTMMU */
-    r0 = addr_reg;
-    r1 = 3;
-    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
-    bswap = 0;
-#else
-    bswap = 1;
-#endif
-
-    switch (opc) {
-    default:
-    case 0:
-        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
-        break;
-    case 0|4:
-        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
-        tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
-        break;
-    case 1:
-        if (bswap)
-            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
-        else
-            tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
-        break;
-    case 1|4:
-        if (bswap) {
-            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
-            tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
-        }
-        else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
-        break;
-    case 2:
-        if (bswap)
-            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
-        else
-            tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
-        break;
-    case 3:
-        if (bswap) {
-            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
-            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
-            tcg_out32 (s, LWBRX | TAB (data_reg2, rbase, r1));
-        }
-        else {
-#ifdef CONFIG_USE_GUEST_BASE
-            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
-            tcg_out32 (s, LWZX | TAB (data_reg2, rbase, r0));
-            tcg_out32 (s, LWZX | TAB (data_reg, rbase, r1));
-#else
-            if (r0 == data_reg2) {
-                tcg_out32 (s, LWZ | RT (0) | RA (r0));
-                tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
-                tcg_out_mov (s, TCG_TYPE_I32, data_reg2, 0);
-            }
-            else {
-                tcg_out32 (s, LWZ | RT (data_reg2) | RA (r0));
-                tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
-            }
-#endif
-        }
-        break;
-    }
-
-#ifdef CONFIG_SOFTMMU
-    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
-#endif
-}
-
-static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
-{
-    int addr_reg, r0, r1, data_reg, data_reg2, mem_index, bswap, rbase;
-#ifdef CONFIG_SOFTMMU
-    int r2, ir;
-    void *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
-    int addr_reg2;
-#endif
-
-    data_reg = *args++;
-    if (opc == 3)
-        data_reg2 = *args++;
-    else
-        data_reg2 = 0;
-    addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
-    addr_reg2 = *args++;
-#endif
-    mem_index = *args;
-
-#ifdef CONFIG_SOFTMMU
-    r0 = 3;
-    r1 = 4;
-    r2 = 0;
-    rbase = 0;
-
-    tcg_out32 (s, (RLWINM
-                   | RA (r0)
-                   | RS (addr_reg)
-                   | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
-                   | MB (32 - (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS))
-                   | ME (31 - CPU_TLB_ENTRY_BITS)
-                   )
-        );
-    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
-    tcg_out32 (s, (LWZU
-                   | RT (r1)
-                   | RA (r0)
-                   | offsetof (CPUState, tlb_table[mem_index][0].addr_write)
-                   )
-        );
-    tcg_out32 (s, (RLWINM
-                   | RA (r2)
-                   | RS (addr_reg)
-                   | SH (0)
-                   | MB ((32 - opc) & 31)
-                   | ME (31 - TARGET_PAGE_BITS)
-                   )
-        );
-
-    tcg_out32 (s, CMP | (7 << 23) | RA (r2) | RB (r1));
-#if TARGET_LONG_BITS == 64
-    tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4);
-    tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1));
-    tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
-#endif
-
-    label1_ptr = s->code_ptr;
-#ifdef FAST_PATH
-    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
-#endif
-
-    /* slow path */
-#if TARGET_LONG_BITS == 32
-    tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg);
-    ir = 4;
-#else
-    tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg2);
-    tcg_out_mov (s, TCG_TYPE_I32, 4, addr_reg);
-#ifdef TCG_TARGET_CALL_ALIGN_ARGS
-    ir = 5;
-#else
-    ir = 4;
-#endif
-#endif
-
-    switch (opc) {
-    case 0:
-        tcg_out32 (s, (RLWINM
-                       | RA (ir)
-                       | RS (data_reg)
-                       | SH (0)
-                       | MB (24)
-                       | ME (31)));
-        break;
-    case 1:
-        tcg_out32 (s, (RLWINM
-                       | RA (ir)
-                       | RS (data_reg)
-                       | SH (0)
-                       | MB (16)
-                       | ME (31)));
-        break;
-    case 2:
-        tcg_out_mov (s, TCG_TYPE_I32, ir, data_reg);
-        break;
-    case 3:
-#ifdef TCG_TARGET_CALL_ALIGN_ARGS
-        ir = 5;
-#endif
-        tcg_out_mov (s, TCG_TYPE_I32, ir++, data_reg2);
-        tcg_out_mov (s, TCG_TYPE_I32, ir, data_reg);
-        break;
-    }
-    ir++;
-
-    tcg_out_movi (s, TCG_TYPE_I32, ir, mem_index);
-    tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
-    label2_ptr = s->code_ptr;
-    tcg_out32 (s, B);
-
-    /* label1: fast path */
-#ifdef FAST_PATH
-    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
-#endif
-
-    tcg_out32 (s, (LWZ
-                   | RT (r0)
-                   | RA (r0)
-                   | (offsetof (CPUTLBEntry, addend)
-                      - offsetof (CPUTLBEntry, addr_write))
-                   ));
-    /* r0 = env->tlb_table[mem_index][index].addend */
-    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
-    /* r0 = env->tlb_table[mem_index][index].addend + addr */
-
-#else  /* !CONFIG_SOFTMMU */
-    r0 = addr_reg;
-    r1 = 3;
-    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
-    bswap = 0;
-#else
-    bswap = 1;
-#endif
-    switch (opc) {
-    case 0:
-        tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
-        break;
-    case 1:
-        if (bswap)
-            tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
-        else
-            tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
-        break;
-    case 2:
-        if (bswap)
-            tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
-        else
-            tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
-        break;
-    case 3:
-        if (bswap) {
-            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
-            tcg_out32 (s, STWBRX | SAB (data_reg,  rbase, r0));
-            tcg_out32 (s, STWBRX | SAB (data_reg2, rbase, r1));
-        }
-        else {
-#ifdef CONFIG_USE_GUEST_BASE
-            tcg_out32 (s, STWX | SAB (data_reg2, rbase, r0));
-            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
-            tcg_out32 (s, STWX | SAB (data_reg,  rbase, r1));
-#else
-            tcg_out32 (s, STW | RS (data_reg2) | RA (r0));
-            tcg_out32 (s, STW | RS (data_reg) | RA (r0) | 4);
-#endif
-        }
-        break;
-    }
-
-#ifdef CONFIG_SOFTMMU
-    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
-#endif
-}
-
-static void tcg_target_qemu_prologue (TCGContext *s)
-{
-    int i, frame_size;
-
-    frame_size = 0
-        + LINKAGE_AREA_SIZE
-        + TCG_STATIC_CALL_ARGS_SIZE
-        + ARRAY_SIZE (tcg_target_callee_save_regs) * 4
-        ;
-    frame_size = (frame_size + 15) & ~15;
-
-#ifdef _CALL_AIX
-    {
-        uint32_t addr;
-
-        /* First emit adhoc function descriptor */
-        addr = (uint32_t) s->code_ptr + 12;
-        tcg_out32 (s, addr);        /* entry point */
-        s->code_ptr += 8;           /* skip TOC and environment pointer */
-    }
-#endif
-    tcg_out32 (s, MFSPR | RT (0) | LR);
-    tcg_out32 (s, STWU | RS (1) | RA (1) | (-frame_size & 0xffff));
-    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
-        tcg_out32 (s, (STW
-                       | RS (tcg_target_callee_save_regs[i])
-                       | RA (1)
-                       | (i * 4 + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE)
-                       )
-            );
-    tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size + LR_OFFSET));
-
-#ifdef CONFIG_USE_GUEST_BASE
-    if (GUEST_BASE) {
-        tcg_out_movi (s, TCG_TYPE_I32, TCG_GUEST_BASE_REG, GUEST_BASE);
-        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
-    }
-#endif
-
-    tcg_out32 (s, MTSPR | RS (3) | CTR);
-    tcg_out32 (s, BCCTR | BO_ALWAYS);
-    tb_ret_addr = s->code_ptr;
-
-    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
-        tcg_out32 (s, (LWZ
-                       | RT (tcg_target_callee_save_regs[i])
-                       | RA (1)
-                       | (i * 4 + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE)
-                       )
-            );
-    tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size + LR_OFFSET));
-    tcg_out32 (s, MTSPR | RS (0) | LR);
-    tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
-    tcg_out32 (s, BCLR | BO_ALWAYS);
-}
-
-static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
-                        tcg_target_long arg2)
-{
-    tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
-}
-
-static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
-                        tcg_target_long arg2)
-{
-    tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
-}
-
-static void ppc_addi (TCGContext *s, int rt, int ra, tcg_target_long si)
-{
-    if (!si && rt == ra)
-        return;
-
-    if (si == (int16_t) si)
-        tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
-    else {
-        uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
-        tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
-        tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
-    }
-}
-
-static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
-    ppc_addi (s, reg, reg, val);
-}
-
-static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
-                         int const_arg2, int cr)
-{
-    int imm;
-    uint32_t op;
-
-    switch (cond) {
-    case TCG_COND_EQ:
-    case TCG_COND_NE:
-        if (const_arg2) {
-            if ((int16_t) arg2 == arg2) {
-                op = CMPI;
-                imm = 1;
-                break;
-            }
-            else if ((uint16_t) arg2 == arg2) {
-                op = CMPLI;
-                imm = 1;
-                break;
-            }
-        }
-        op = CMPL;
-        imm = 0;
-        break;
-
-    case TCG_COND_LT:
-    case TCG_COND_GE:
-    case TCG_COND_LE:
-    case TCG_COND_GT:
-        if (const_arg2) {
-            if ((int16_t) arg2 == arg2) {
-                op = CMPI;
-                imm = 1;
-                break;
-            }
-        }
-        op = CMP;
-        imm = 0;
-        break;
-
-    case TCG_COND_LTU:
-    case TCG_COND_GEU:
-    case TCG_COND_LEU:
-    case TCG_COND_GTU:
-        if (const_arg2) {
-            if ((uint16_t) arg2 == arg2) {
-                op = CMPLI;
-                imm = 1;
-                break;
-            }
-        }
-        op = CMPL;
-        imm = 0;
-        break;
-
-    default:
-        tcg_abort ();
-    }
-    op |= BF (cr);
-
-    if (imm)
-        tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
-    else {
-        if (const_arg2) {
-            tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
-            tcg_out32 (s, op | RA (arg1) | RB (0));
-        }
-        else
-            tcg_out32 (s, op | RA (arg1) | RB (arg2));
-    }
-
-}
-
-static void tcg_out_bc (TCGContext *s, int bc, int label_index)
-{
-    TCGLabel *l = &s->labels[label_index];
-
-    if (l->has_value)
-        tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
-    else {
-        uint16_t val = *(uint16_t *) &s->code_ptr[2];
-
-        /* Thanks to Andrzej Zaborowski */
-        tcg_out32 (s, bc | (val & 0xfffc));
-        tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
-    }
-}
-
-static void tcg_out_cr7eq_from_cond (TCGContext *s, const TCGArg *args,
-                                     const int *const_args)
-{
-    TCGCond cond = args[4];
-    int op;
-    struct { int bit1; int bit2; int cond2; } bits[] = {
-        [TCG_COND_LT ] = { CR_LT, CR_LT, TCG_COND_LT  },
-        [TCG_COND_LE ] = { CR_LT, CR_GT, TCG_COND_LT  },
-        [TCG_COND_GT ] = { CR_GT, CR_GT, TCG_COND_GT  },
-        [TCG_COND_GE ] = { CR_GT, CR_LT, TCG_COND_GT  },
-        [TCG_COND_LTU] = { CR_LT, CR_LT, TCG_COND_LTU },
-        [TCG_COND_LEU] = { CR_LT, CR_GT, TCG_COND_LTU },
-        [TCG_COND_GTU] = { CR_GT, CR_GT, TCG_COND_GTU },
-        [TCG_COND_GEU] = { CR_GT, CR_LT, TCG_COND_GTU },
-    }, *b = &bits[cond];
-
-    switch (cond) {
-    case TCG_COND_EQ:
-    case TCG_COND_NE:
-        op = (cond == TCG_COND_EQ) ? CRAND : CRNAND;
-        tcg_out_cmp (s, cond, args[0], args[2], const_args[2], 6);
-        tcg_out_cmp (s, cond, args[1], args[3], const_args[3], 7);
-        tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
-        break;
-    case TCG_COND_LT:
-    case TCG_COND_LE:
-    case TCG_COND_GT:
-    case TCG_COND_GE:
-    case TCG_COND_LTU:
-    case TCG_COND_LEU:
-    case TCG_COND_GTU:
-    case TCG_COND_GEU:
-        op = (b->bit1 != b->bit2) ? CRANDC : CRAND;
-        tcg_out_cmp (s, b->cond2, args[1], args[3], const_args[3], 5);
-        tcg_out_cmp (s, tcg_unsigned_cond (cond), args[0], args[2],
-                     const_args[2], 7);
-        tcg_out32 (s, op | BT (7, CR_EQ) | BA (5, CR_EQ) | BB (7, b->bit2));
-        tcg_out32 (s, CROR | BT (7, CR_EQ) | BA (5, b->bit1) | BB (7, CR_EQ));
-        break;
-    default:
-        tcg_abort();
-    }
-}
-
-static void tcg_out_setcond (TCGContext *s, TCGCond cond, TCGArg arg0,
-                             TCGArg arg1, TCGArg arg2, int const_arg2)
-{
-    int crop, sh, arg;
-
-    switch (cond) {
-    case TCG_COND_EQ:
-        if (const_arg2) {
-            if (!arg2) {
-                arg = arg1;
-            }
-            else {
-                arg = 0;
-                if ((uint16_t) arg2 == arg2) {
-                    tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
-                }
-                else {
-                    tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
-                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
-                }
-            }
-        }
-        else {
-            arg = 0;
-            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
-        }
-        tcg_out32 (s, CNTLZW | RS (arg) | RA (0));
-        tcg_out32 (s, (RLWINM
-                       | RA (arg0)
-                       | RS (0)
-                       | SH (27)
-                       | MB (5)
-                       | ME (31)
-                       )
-            );
-        break;
-
-    case TCG_COND_NE:
-        if (const_arg2) {
-            if (!arg2) {
-                arg = arg1;
-            }
-            else {
-                arg = 0;
-                if ((uint16_t) arg2 == arg2) {
-                    tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
-                }
-                else {
-                    tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
-                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
-                }
-            }
-        }
-        else {
-            arg = 0;
-            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
-        }
-
-        if (arg == arg1 && arg1 == arg0) {
-            tcg_out32 (s, ADDIC | RT (0) | RA (arg) | 0xffff);
-            tcg_out32 (s, SUBFE | TAB (arg0, 0, arg));
-        }
-        else {
-            tcg_out32 (s, ADDIC | RT (arg0) | RA (arg) | 0xffff);
-            tcg_out32 (s, SUBFE | TAB (arg0, arg0, arg));
-        }
-        break;
-
-    case TCG_COND_GT:
-    case TCG_COND_GTU:
-        sh = 30;
-        crop = 0;
-        goto crtest;
-
-    case TCG_COND_LT:
-    case TCG_COND_LTU:
-        sh = 29;
-        crop = 0;
-        goto crtest;
-
-    case TCG_COND_GE:
-    case TCG_COND_GEU:
-        sh = 31;
-        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_LT) | BB (7, CR_LT);
-        goto crtest;
-
-    case TCG_COND_LE:
-    case TCG_COND_LEU:
-        sh = 31;
-        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_GT) | BB (7, CR_GT);
-    crtest:
-        tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
-        if (crop) tcg_out32 (s, crop);
-        tcg_out32 (s, MFCR | RT (0));
-        tcg_out32 (s, (RLWINM
-                       | RA (arg0)
-                       | RS (0)
-                       | SH (sh)
-                       | MB (31)
-                       | ME (31)
-                       )
-            );
-        break;
-
-    default:
-        tcg_abort ();
-    }
-}
-
-static void tcg_out_setcond2 (TCGContext *s, const TCGArg *args,
-                              const int *const_args)
-{
-    tcg_out_cr7eq_from_cond (s, args + 1, const_args + 1);
-    tcg_out32 (s, MFCR | RT (0));
-    tcg_out32 (s, (RLWINM
-                   | RA (args[0])
-                   | RS (0)
-                   | SH (31)
-                   | MB (31)
-                   | ME (31)
-                   )
-        );
-}
-
-static void tcg_out_brcond (TCGContext *s, TCGCond cond,
-                            TCGArg arg1, TCGArg arg2, int const_arg2,
-                            int label_index)
-{
-    tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
-    tcg_out_bc (s, tcg_to_bc[cond], label_index);
-}
-
-/* XXX: we implement it at the target level to avoid having to
-   handle cross basic blocks temporaries */
-static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
-                             const int *const_args)
-{
-    tcg_out_cr7eq_from_cond (s, args, const_args);
-    tcg_out_bc (s, (BC | BI (7, CR_EQ) | BO_COND_TRUE), args[5]);
-}
-
-void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
-{
-    uint32_t *ptr;
-    long disp = addr - jmp_addr;
-    unsigned long patch_size;
-
-    ptr = (uint32_t *)jmp_addr;
-
-    if ((disp << 6) >> 6 != disp) {
-        ptr[0] = 0x3c000000 | (addr >> 16);    /* lis 0,addr@ha */
-        ptr[1] = 0x60000000 | (addr & 0xffff); /* la  0,addr@l(0) */
-        ptr[2] = 0x7c0903a6;                   /* mtctr 0 */
-        ptr[3] = 0x4e800420;                   /* brctr */
-        patch_size = 16;
-    } else {
-        /* patch the branch destination */
-        if (disp != 16) {
-            *ptr = 0x48000000 | (disp & 0x03fffffc); /* b disp */
-            patch_size = 4;
-        } else {
-            ptr[0] = 0x60000000; /* nop */
-            ptr[1] = 0x60000000;
-            ptr[2] = 0x60000000;
-            ptr[3] = 0x60000000;
-            patch_size = 16;
-        }
-    }
-    /* flush icache */
-    flush_icache_range(jmp_addr, jmp_addr + patch_size);
-}
-
-static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
-                       const int *const_args)
-{
-    switch (opc) {
-    case INDEX_op_exit_tb:
-        tcg_out_movi (s, TCG_TYPE_I32, TCG_REG_R3, args[0]);
-        tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
-        break;
-    case INDEX_op_goto_tb:
-        if (s->tb_jmp_offset) {
-            /* direct jump method */
-
-            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
-            s->code_ptr += 16;
-        }
-        else {
-            tcg_abort ();
-        }
-        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
-        break;
-    case INDEX_op_br:
-        {
-            TCGLabel *l = &s->labels[args[0]];
-
-            if (l->has_value) {
-                tcg_out_b (s, 0, l->u.value);
-            }
-            else {
-                uint32_t val = *(uint32_t *) s->code_ptr;
-
-                /* Thanks to Andrzej Zaborowski */
-                tcg_out32 (s, B | (val & 0x3fffffc));
-                tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
-            }
-        }
-        break;
-    case INDEX_op_call:
-        tcg_out_call (s, args[0], const_args[0]);
-        break;
-    case INDEX_op_jmp:
-        if (const_args[0]) {
-            tcg_out_b (s, 0, args[0]);
-        }
-        else {
-            tcg_out32 (s, MTSPR | RS (args[0]) | CTR);
-            tcg_out32 (s, BCCTR | BO_ALWAYS);
-        }
-        break;
-    case INDEX_op_movi_i32:
-        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
-        break;
-    case INDEX_op_ld8u_i32:
-        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
-        break;
-    case INDEX_op_ld8s_i32:
-        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
-        tcg_out32 (s, EXTSB | RS (args[0]) | RA (args[0]));
-        break;
-    case INDEX_op_ld16u_i32:
-        tcg_out_ldst (s, args[0], args[1], args[2], LHZ, LHZX);
-        break;
-    case INDEX_op_ld16s_i32:
-        tcg_out_ldst (s, args[0], args[1], args[2], LHA, LHAX);
-        break;
-    case INDEX_op_ld_i32:
-        tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
-        break;
-    case INDEX_op_st8_i32:
-        tcg_out_ldst (s, args[0], args[1], args[2], STB, STBX);
-        break;
-    case INDEX_op_st16_i32:
-        tcg_out_ldst (s, args[0], args[1], args[2], STH, STHX);
-        break;
-    case INDEX_op_st_i32:
-        tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
-        break;
-
-    case INDEX_op_add_i32:
-        if (const_args[2])
-            ppc_addi (s, args[0], args[1], args[2]);
-        else
-            tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
-        break;
-    case INDEX_op_sub_i32:
-        if (const_args[2])
-            ppc_addi (s, args[0], args[1], -args[2]);
-        else
-            tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
-        break;
-
-    case INDEX_op_and_i32:
-        if (const_args[2]) {
-            uint32_t c;
-
-            c = args[2];
-
-            if (!c) {
-                tcg_out_movi (s, TCG_TYPE_I32, args[0], 0);
-                break;
-            }
-#ifdef __PPU__
-            uint32_t t, n;
-            int mb, me;
-
-            n = c ^ -(c & 1);
-            t = n + (n & -n);
-
-            if ((t & (t - 1)) == 0) {
-                int lzc, tzc;
-
-                if ((c & 0x80000001) == 0x80000001) {
-                    lzc = clz32 (n);
-                    tzc = ctz32 (n);
-
-                    mb = 32 - tzc;
-                    me = lzc - 1;
-                }
-                else {
-                    lzc = clz32 (c);
-                    tzc = ctz32 (c);
-
-                    mb = lzc;
-                    me = 31 - tzc;
-                }
-
-                tcg_out32 (s, (RLWINM
-                               | RA (args[0])
-                               | RS (args[1])
-                               | SH (0)
-                               | MB (mb)
-                               | ME (me)
-                               )
-                    );
-            }
-            else
-#endif /* !__PPU__ */
-            {
-                if ((c & 0xffff) == c)
-                    tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | c);
-                else if ((c & 0xffff0000) == c)
-                    tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
-                               | ((c >> 16) & 0xffff));
-                else {
-                    tcg_out_movi (s, TCG_TYPE_I32, 0, c);
-                    tcg_out32 (s, AND | SAB (args[1], args[0], 0));
-                }
-            }
-        }
-        else
-            tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_or_i32:
-        if (const_args[2]) {
-            if (args[2] & 0xffff) {
-                tcg_out32 (s, ORI | RS (args[1])  | RA (args[0])
-                           | (args[2] & 0xffff));
-                if (args[2] >> 16)
-                    tcg_out32 (s, ORIS | RS (args[0])  | RA (args[0])
-                               | ((args[2] >> 16) & 0xffff));
-            }
-            else {
-                tcg_out32 (s, ORIS | RS (args[1])  | RA (args[0])
-                           | ((args[2] >> 16) & 0xffff));
-            }
-        }
-        else
-            tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_xor_i32:
-        if (const_args[2]) {
-            if ((args[2] & 0xffff) == args[2])
-                tcg_out32 (s, XORI | RS (args[1])  | RA (args[0])
-                           | (args[2] & 0xffff));
-            else if ((args[2] & 0xffff0000) == args[2])
-                tcg_out32 (s, XORIS | RS (args[1])  | RA (args[0])
-                           | ((args[2] >> 16) & 0xffff));
-            else {
-                tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
-                tcg_out32 (s, XOR | SAB (args[1], args[0], 0));
-            }
-        }
-        else
-            tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_andc_i32:
-        tcg_out32 (s, ANDC | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_orc_i32:
-        tcg_out32 (s, ORC | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_eqv_i32:
-        tcg_out32 (s, EQV | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_nand_i32:
-        tcg_out32 (s, NAND | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_nor_i32:
-        tcg_out32 (s, NOR | SAB (args[1], args[0], args[2]));
-        break;
-
-    case INDEX_op_mul_i32:
-        if (const_args[2]) {
-            if (args[2] == (int16_t) args[2])
-                tcg_out32 (s, MULLI | RT (args[0]) | RA (args[1])
-                           | (args[2] & 0xffff));
-            else {
-                tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
-                tcg_out32 (s, MULLW | TAB (args[0], args[1], 0));
-            }
-        }
-        else
-            tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2]));
-        break;
-
-    case INDEX_op_div_i32:
-        tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2]));
-        break;
-
-    case INDEX_op_divu_i32:
-        tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
-        break;
-
-    case INDEX_op_rem_i32:
-        tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
-        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
-        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
-        break;
-
-    case INDEX_op_remu_i32:
-        tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
-        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
-        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
-        break;
-
-    case INDEX_op_mulu2_i32:
-        if (args[0] == args[2] || args[0] == args[3]) {
-            tcg_out32 (s, MULLW | TAB (0, args[2], args[3]));
-            tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3]));
-            tcg_out_mov (s, TCG_TYPE_I32, args[0], 0);
-        }
-        else {
-            tcg_out32 (s, MULLW | TAB (args[0], args[2], args[3]));
-            tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3]));
-        }
-        break;
-
-    case INDEX_op_shl_i32:
-        if (const_args[2]) {
-            tcg_out32 (s, (RLWINM
-                           | RA (args[0])
-                           | RS (args[1])
-                           | SH (args[2])
-                           | MB (0)
-                           | ME (31 - args[2])
-                           )
-                );
-        }
-        else
-            tcg_out32 (s, SLW | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_shr_i32:
-        if (const_args[2]) {
-            tcg_out32 (s, (RLWINM
-                           | RA (args[0])
-                           | RS (args[1])
-                           | SH (32 - args[2])
-                           | MB (args[2])
-                           | ME (31)
-                           )
-                );
-        }
-        else
-            tcg_out32 (s, SRW | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_sar_i32:
-        if (const_args[2])
-            tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2]));
-        else
-            tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_rotl_i32:
-        {
-            int op = 0
-                | RA (args[0])
-                | RS (args[1])
-                | MB (0)
-                | ME (31)
-                | (const_args[2] ? RLWINM | SH (args[2])
-                                 : RLWNM | RB (args[2]))
-                ;
-            tcg_out32 (s, op);
-        }
-        break;
-    case INDEX_op_rotr_i32:
-        if (const_args[2]) {
-            if (!args[2]) {
-                tcg_out_mov (s, TCG_TYPE_I32, args[0], args[1]);
-            }
-            else {
-                tcg_out32 (s, RLWINM
-                           | RA (args[0])
-                           | RS (args[1])
-                           | SH (32 - args[2])
-                           | MB (0)
-                           | ME (31)
-                    );
-            }
-        }
-        else {
-            tcg_out32 (s, SUBFIC | RT (0) | RA (args[2]) | 32);
-            tcg_out32 (s, RLWNM
-                       | RA (args[0])
-                       | RS (args[1])
-                       | RB (0)
-                       | MB (0)
-                       | ME (31)
-                );
-        }
-        break;
-
-    case INDEX_op_add2_i32:
-        if (args[0] == args[3] || args[0] == args[5]) {
-            tcg_out32 (s, ADDC | TAB (0, args[2], args[4]));
-            tcg_out32 (s, ADDE | TAB (args[1], args[3], args[5]));
-            tcg_out_mov (s, TCG_TYPE_I32, args[0], 0);
-        }
-        else {
-            tcg_out32 (s, ADDC | TAB (args[0], args[2], args[4]));
-            tcg_out32 (s, ADDE | TAB (args[1], args[3], args[5]));
-        }
-        break;
-    case INDEX_op_sub2_i32:
-        if (args[0] == args[3] || args[0] == args[5]) {
-            tcg_out32 (s, SUBFC | TAB (0, args[4], args[2]));
-            tcg_out32 (s, SUBFE | TAB (args[1], args[5], args[3]));
-            tcg_out_mov (s, TCG_TYPE_I32, args[0], 0);
-        }
-        else {
-            tcg_out32 (s, SUBFC | TAB (args[0], args[4], args[2]));
-            tcg_out32 (s, SUBFE | TAB (args[1], args[5], args[3]));
-        }
-        break;
-
-    case INDEX_op_brcond_i32:
-        /*
-          args[0] = r0
-          args[1] = r1
-          args[2] = cond
-          args[3] = r1 is const
-          args[4] = label_index
-        */
-        tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3]);
-        break;
-    case INDEX_op_brcond2_i32:
-        tcg_out_brcond2(s, args, const_args);
-        break;
-
-    case INDEX_op_neg_i32:
-        tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
-        break;
-
-    case INDEX_op_not_i32:
-        tcg_out32 (s, NOR | SAB (args[1], args[0], args[1]));
-        break;
-
-    case INDEX_op_qemu_ld8u:
-        tcg_out_qemu_ld(s, args, 0);
-        break;
-    case INDEX_op_qemu_ld8s:
-        tcg_out_qemu_ld(s, args, 0 | 4);
-        break;
-    case INDEX_op_qemu_ld16u:
-        tcg_out_qemu_ld(s, args, 1);
-        break;
-    case INDEX_op_qemu_ld16s:
-        tcg_out_qemu_ld(s, args, 1 | 4);
-        break;
-    case INDEX_op_qemu_ld32:
-        tcg_out_qemu_ld(s, args, 2);
-        break;
-    case INDEX_op_qemu_ld64:
-        tcg_out_qemu_ld(s, args, 3);
-        break;
-    case INDEX_op_qemu_st8:
-        tcg_out_qemu_st(s, args, 0);
-        break;
-    case INDEX_op_qemu_st16:
-        tcg_out_qemu_st(s, args, 1);
-        break;
-    case INDEX_op_qemu_st32:
-        tcg_out_qemu_st(s, args, 2);
-        break;
-    case INDEX_op_qemu_st64:
-        tcg_out_qemu_st(s, args, 3);
-        break;
-
-    case INDEX_op_ext8s_i32:
-        tcg_out32 (s, EXTSB | RS (args[1]) | RA (args[0]));
-        break;
-    case INDEX_op_ext8u_i32:
-        tcg_out32 (s, RLWINM
-                   | RA (args[0])
-                   | RS (args[1])
-                   | SH (0)
-                   | MB (24)
-                   | ME (31)
-            );
-        break;
-    case INDEX_op_ext16s_i32:
-        tcg_out32 (s, EXTSH | RS (args[1]) | RA (args[0]));
-        break;
-    case INDEX_op_ext16u_i32:
-        tcg_out32 (s, RLWINM
-                   | RA (args[0])
-                   | RS (args[1])
-                   | SH (0)
-                   | MB (16)
-                   | ME (31)
-            );
-        break;
-
-    case INDEX_op_setcond_i32:
-        tcg_out_setcond (s, args[3], args[0], args[1], args[2], const_args[2]);
-        break;
-    case INDEX_op_setcond2_i32:
-        tcg_out_setcond2 (s, args, const_args);
-        break;
-
-    case INDEX_op_bswap16_i32:
-        /* Stolen from gcc's builtin_bswap16 */
-
-        /* a1 = abcd */
-
-        /* r0 = (a1 << 8) & 0xff00 # 00d0 */
-        tcg_out32 (s, RLWINM
-                   | RA (0)
-                   | RS (args[1])
-                   | SH (8)
-                   | MB (16)
-                   | ME (23)
-            );
-
-        /* a0 = rotate_left (a1, 24) & 0xff # 000c */
-        tcg_out32 (s, RLWINM
-                   | RA (args[0])
-                   | RS (args[1])
-                   | SH (24)
-                   | MB (24)
-                   | ME (31)
-            );
-
-        /* a0 = a0 | r0 # 00dc */
-        tcg_out32 (s, OR | SAB (0, args[0], args[0]));
-        break;
-
-    case INDEX_op_bswap32_i32:
-        /* Stolen from gcc's builtin_bswap32 */
-        {
-            int a0 = args[0];
-
-            /* a1 = args[1] # abcd */
-
-            if (a0 == args[1]) {
-                a0 = 0;
-            }
-
-            /* a0 = rotate_left (a1, 8) # bcda */
-            tcg_out32 (s, RLWINM
-                       | RA (a0)
-                       | RS (args[1])
-                       | SH (8)
-                       | MB (0)
-                       | ME (31)
-                );
-
-            /* a0 = (a0 & ~0xff000000) | ((a1 << 24) & 0xff000000) # dcda */
-            tcg_out32 (s, RLWIMI
-                       | RA (a0)
-                       | RS (args[1])
-                       | SH (24)
-                       | MB (0)
-                       | ME (7)
-                );
-
-            /* a0 = (a0 & ~0x0000ff00) | ((a1 << 24) & 0x0000ff00) # dcba */
-            tcg_out32 (s, RLWIMI
-                       | RA (a0)
-                       | RS (args[1])
-                       | SH (24)
-                       | MB (16)
-                       | ME (23)
-                );
-
-            if (!a0) {
-                tcg_out_mov (s, TCG_TYPE_I32, args[0], a0);
-            }
-        }
-        break;
-
-    default:
-        tcg_dump_ops (s, stderr);
-        tcg_abort ();
-    }
-}
-
-static const TCGTargetOpDef ppc_op_defs[] = {
-    { INDEX_op_exit_tb, { } },
-    { INDEX_op_goto_tb, { } },
-    { INDEX_op_call, { "ri" } },
-    { INDEX_op_jmp, { "ri" } },
-    { INDEX_op_br, { } },
-
-    { INDEX_op_mov_i32, { "r", "r" } },
-    { INDEX_op_movi_i32, { "r" } },
-    { INDEX_op_ld8u_i32, { "r", "r" } },
-    { INDEX_op_ld8s_i32, { "r", "r" } },
-    { INDEX_op_ld16u_i32, { "r", "r" } },
-    { INDEX_op_ld16s_i32, { "r", "r" } },
-    { INDEX_op_ld_i32, { "r", "r" } },
-    { INDEX_op_st8_i32, { "r", "r" } },
-    { INDEX_op_st16_i32, { "r", "r" } },
-    { INDEX_op_st_i32, { "r", "r" } },
-
-    { INDEX_op_add_i32, { "r", "r", "ri" } },
-    { INDEX_op_mul_i32, { "r", "r", "ri" } },
-    { INDEX_op_div_i32, { "r", "r", "r" } },
-    { INDEX_op_divu_i32, { "r", "r", "r" } },
-    { INDEX_op_rem_i32, { "r", "r", "r" } },
-    { INDEX_op_remu_i32, { "r", "r", "r" } },
-    { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
-    { INDEX_op_sub_i32, { "r", "r", "ri" } },
-    { INDEX_op_and_i32, { "r", "r", "ri" } },
-    { INDEX_op_or_i32, { "r", "r", "ri" } },
-    { INDEX_op_xor_i32, { "r", "r", "ri" } },
-
-    { INDEX_op_shl_i32, { "r", "r", "ri" } },
-    { INDEX_op_shr_i32, { "r", "r", "ri" } },
-    { INDEX_op_sar_i32, { "r", "r", "ri" } },
-
-    { INDEX_op_rotl_i32, { "r", "r", "ri" } },
-    { INDEX_op_rotr_i32, { "r", "r", "ri" } },
-
-    { INDEX_op_brcond_i32, { "r", "ri" } },
-
-    { INDEX_op_add2_i32, { "r", "r", "r", "r", "r", "r" } },
-    { INDEX_op_sub2_i32, { "r", "r", "r", "r", "r", "r" } },
-    { INDEX_op_brcond2_i32, { "r", "r", "r", "r" } },
-
-    { INDEX_op_neg_i32, { "r", "r" } },
-    { INDEX_op_not_i32, { "r", "r" } },
-
-    { INDEX_op_andc_i32, { "r", "r", "r" } },
-    { INDEX_op_orc_i32, { "r", "r", "r" } },
-    { INDEX_op_eqv_i32, { "r", "r", "r" } },
-    { INDEX_op_nand_i32, { "r", "r", "r" } },
-    { INDEX_op_nor_i32, { "r", "r", "r" } },
-
-    { INDEX_op_setcond_i32, { "r", "r", "ri" } },
-    { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
-
-    { INDEX_op_bswap16_i32, { "r", "r" } },
-    { INDEX_op_bswap32_i32, { "r", "r" } },
-
-#if TARGET_LONG_BITS == 32
-    { INDEX_op_qemu_ld8u, { "r", "L" } },
-    { INDEX_op_qemu_ld8s, { "r", "L" } },
-    { INDEX_op_qemu_ld16u, { "r", "L" } },
-    { INDEX_op_qemu_ld16s, { "r", "L" } },
-    { INDEX_op_qemu_ld32, { "r", "L" } },
-    { INDEX_op_qemu_ld64, { "r", "r", "L" } },
-
-    { INDEX_op_qemu_st8, { "K", "K" } },
-    { INDEX_op_qemu_st16, { "K", "K" } },
-    { INDEX_op_qemu_st32, { "K", "K" } },
-    { INDEX_op_qemu_st64, { "M", "M", "M" } },
-#else
-    { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
-    { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
-    { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
-    { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
-    { INDEX_op_qemu_ld32, { "r", "L", "L" } },
-    { INDEX_op_qemu_ld64, { "r", "L", "L", "L" } },
-
-    { INDEX_op_qemu_st8, { "K", "K", "K" } },
-    { INDEX_op_qemu_st16, { "K", "K", "K" } },
-    { INDEX_op_qemu_st32, { "K", "K", "K" } },
-    { INDEX_op_qemu_st64, { "M", "M", "M", "M" } },
-#endif
-
-    { INDEX_op_ext8s_i32, { "r", "r" } },
-    { INDEX_op_ext8u_i32, { "r", "r" } },
-    { INDEX_op_ext16s_i32, { "r", "r" } },
-    { INDEX_op_ext16u_i32, { "r", "r" } },
-
-    { -1 },
-};
-
-static void tcg_target_init(TCGContext *s)
-{
-    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
-    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
-                     (1 << TCG_REG_R0) |
-#ifdef _CALL_DARWIN
-                     (1 << TCG_REG_R2) |
-#endif
-                     (1 << TCG_REG_R3) |
-                     (1 << TCG_REG_R4) |
-                     (1 << TCG_REG_R5) |
-                     (1 << TCG_REG_R6) |
-                     (1 << TCG_REG_R7) |
-                     (1 << TCG_REG_R8) |
-                     (1 << TCG_REG_R9) |
-                     (1 << TCG_REG_R10) |
-                     (1 << TCG_REG_R11) |
-                     (1 << TCG_REG_R12)
-        );
-
-    tcg_regset_clear(s->reserved_regs);
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1);
-#ifndef _CALL_DARWIN
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2);
-#endif
-#ifdef _CALL_SYSV
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13);
-#endif
-
-    tcg_add_target_add_op_defs(ppc_op_defs);
-}
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
deleted file mode 100644
index a1f8599..0000000
--- a/tcg/ppc/tcg-target.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define TCG_TARGET_PPC 1
-
-#define TCG_TARGET_REG_BITS 32
-#define TCG_TARGET_WORDS_BIGENDIAN
-#define TCG_TARGET_NB_REGS 32
-
-enum {
-    TCG_REG_R0 = 0,
-    TCG_REG_R1,
-    TCG_REG_R2,
-    TCG_REG_R3,
-    TCG_REG_R4,
-    TCG_REG_R5,
-    TCG_REG_R6,
-    TCG_REG_R7,
-    TCG_REG_R8,
-    TCG_REG_R9,
-    TCG_REG_R10,
-    TCG_REG_R11,
-    TCG_REG_R12,
-    TCG_REG_R13,
-    TCG_REG_R14,
-    TCG_REG_R15,
-    TCG_REG_R16,
-    TCG_REG_R17,
-    TCG_REG_R18,
-    TCG_REG_R19,
-    TCG_REG_R20,
-    TCG_REG_R21,
-    TCG_REG_R22,
-    TCG_REG_R23,
-    TCG_REG_R24,
-    TCG_REG_R25,
-    TCG_REG_R26,
-    TCG_REG_R27,
-    TCG_REG_R28,
-    TCG_REG_R29,
-    TCG_REG_R30,
-    TCG_REG_R31
-};
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK TCG_REG_R1
-#define TCG_TARGET_STACK_ALIGN 16
-#if defined _CALL_DARWIN || defined __APPLE__
-#define TCG_TARGET_CALL_STACK_OFFSET 24
-#elif defined _CALL_AIX
-#define TCG_TARGET_CALL_STACK_OFFSET 52
-#elif defined _CALL_SYSV
-#define TCG_TARGET_CALL_ALIGN_ARGS 1
-#define TCG_TARGET_CALL_STACK_OFFSET 8
-#else
-#error Unsupported system
-#endif
-
-/* optional instructions */
-#define TCG_TARGET_HAS_div_i32
-#define TCG_TARGET_HAS_rot_i32
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#define TCG_TARGET_HAS_ext8u_i32
-#define TCG_TARGET_HAS_ext16u_i32
-#define TCG_TARGET_HAS_bswap16_i32
-#define TCG_TARGET_HAS_bswap32_i32
-#define TCG_TARGET_HAS_not_i32
-#define TCG_TARGET_HAS_neg_i32
-#define TCG_TARGET_HAS_andc_i32
-#define TCG_TARGET_HAS_orc_i32
-#define TCG_TARGET_HAS_eqv_i32
-#define TCG_TARGET_HAS_nand_i32
-#define TCG_TARGET_HAS_nor_i32
-
-#define TCG_AREG0 TCG_REG_R27
-
-#define TCG_TARGET_HAS_GUEST_BASE
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
deleted file mode 100644
index ebbee343..0000000
--- a/tcg/ppc64/tcg-target.c
+++ /dev/null
@@ -1,1699 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#define TCG_CT_CONST_U32 0x100
-
-static uint8_t *tb_ret_addr;
-
-#define FAST_PATH
-
-#if TARGET_LONG_BITS == 32
-#define LD_ADDR LWZU
-#define CMP_L 0
-#else
-#define LD_ADDR LDU
-#define CMP_L (1<<21)
-#endif
-
-#ifndef GUEST_BASE
-#define GUEST_BASE 0
-#endif
-
-#ifdef CONFIG_USE_GUEST_BASE
-#define TCG_GUEST_BASE_REG 30
-#else
-#define TCG_GUEST_BASE_REG 0
-#endif
-
-#ifndef NDEBUG
-static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
-    "r0",
-    "r1",
-    "r2",
-    "r3",
-    "r4",
-    "r5",
-    "r6",
-    "r7",
-    "r8",
-    "r9",
-    "r10",
-    "r11",
-    "r12",
-    "r13",
-    "r14",
-    "r15",
-    "r16",
-    "r17",
-    "r18",
-    "r19",
-    "r20",
-    "r21",
-    "r22",
-    "r23",
-    "r24",
-    "r25",
-    "r26",
-    "r27",
-    "r28",
-    "r29",
-    "r30",
-    "r31"
-};
-#endif
-
-static const int tcg_target_reg_alloc_order[] = {
-    TCG_REG_R14,
-    TCG_REG_R15,
-    TCG_REG_R16,
-    TCG_REG_R17,
-    TCG_REG_R18,
-    TCG_REG_R19,
-    TCG_REG_R20,
-    TCG_REG_R21,
-    TCG_REG_R22,
-    TCG_REG_R23,
-    TCG_REG_R28,
-    TCG_REG_R29,
-    TCG_REG_R30,
-    TCG_REG_R31,
-#ifdef __APPLE__
-    TCG_REG_R2,
-#endif
-    TCG_REG_R3,
-    TCG_REG_R4,
-    TCG_REG_R5,
-    TCG_REG_R6,
-    TCG_REG_R7,
-    TCG_REG_R8,
-    TCG_REG_R9,
-    TCG_REG_R10,
-#ifndef __APPLE__
-    TCG_REG_R11,
-#endif
-    TCG_REG_R12,
-    TCG_REG_R24,
-    TCG_REG_R25,
-    TCG_REG_R26,
-    TCG_REG_R27
-};
-
-static const int tcg_target_call_iarg_regs[] = {
-    TCG_REG_R3,
-    TCG_REG_R4,
-    TCG_REG_R5,
-    TCG_REG_R6,
-    TCG_REG_R7,
-    TCG_REG_R8,
-    TCG_REG_R9,
-    TCG_REG_R10
-};
-
-static const int tcg_target_call_oarg_regs[2] = {
-    TCG_REG_R3
-};
-
-static const int tcg_target_callee_save_regs[] = {
-#ifdef __APPLE__
-    TCG_REG_R11,
-#endif
-    TCG_REG_R14,
-    TCG_REG_R15,
-    TCG_REG_R16,
-    TCG_REG_R17,
-    TCG_REG_R18,
-    TCG_REG_R19,
-    TCG_REG_R20,
-    TCG_REG_R21,
-    TCG_REG_R22,
-    TCG_REG_R23,
-    TCG_REG_R24,
-    TCG_REG_R25,
-    TCG_REG_R26,
-    /* TCG_REG_R27, */ /* currently used for the global env, so no
-                          need to save */
-    TCG_REG_R28,
-    TCG_REG_R29,
-    TCG_REG_R30,
-    TCG_REG_R31
-};
-
-static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
-{
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long) pc;
-    if ((disp << 38) >> 38 != disp)
-        tcg_abort ();
-
-    return disp & 0x3fffffc;
-}
-
-static void reloc_pc24 (void *pc, tcg_target_long target)
-{
-    *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
-        | reloc_pc24_val (pc, target);
-}
-
-static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
-{
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long) pc;
-    if (disp != (int16_t) disp)
-        tcg_abort ();
-
-    return disp & 0xfffc;
-}
-
-static void reloc_pc14 (void *pc, tcg_target_long target)
-{
-    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
-        | reloc_pc14_val (pc, target);
-}
-
-static void patch_reloc (uint8_t *code_ptr, int type,
-                         tcg_target_long value, tcg_target_long addend)
-{
-    value += addend;
-    switch (type) {
-    case R_PPC_REL14:
-        reloc_pc14 (code_ptr, value);
-        break;
-    case R_PPC_REL24:
-        reloc_pc24 (code_ptr, value);
-        break;
-    default:
-        tcg_abort ();
-    }
-}
-
-/* maximum number of register used for input function arguments */
-static int tcg_target_get_call_iarg_regs_count (int flags)
-{
-    return ARRAY_SIZE (tcg_target_call_iarg_regs);
-}
-
-/* parse target specific constraints */
-static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str)
-{
-    const char *ct_str;
-
-    ct_str = *pct_str;
-    switch (ct_str[0]) {
-    case 'A': case 'B': case 'C': case 'D':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set_reg (ct->u.regs, 3 + ct_str[0] - 'A');
-        break;
-    case 'r':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
-        break;
-    case 'L':                   /* qemu_ld constraint */
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
-        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
-#ifdef CONFIG_SOFTMMU
-        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
-#endif
-        break;
-    case 'S':                   /* qemu_st constraint */
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
-        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
-#ifdef CONFIG_SOFTMMU
-        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
-        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
-#endif
-        break;
-    case 'Z':
-        ct->ct |= TCG_CT_CONST_U32;
-        break;
-    default:
-        return -1;
-    }
-    ct_str++;
-    *pct_str = ct_str;
-    return 0;
-}
-
-/* test if a constant matches the constraint */
-static int tcg_target_const_match (tcg_target_long val,
-                                   const TCGArgConstraint *arg_ct)
-{
-    int ct;
-
-    ct = arg_ct->ct;
-    if (ct & TCG_CT_CONST)
-        return 1;
-    else if ((ct & TCG_CT_CONST_U32) && (val == (uint32_t) val))
-        return 1;
-    return 0;
-}
-
-#define OPCD(opc) ((opc)<<26)
-#define XO19(opc) (OPCD(19)|((opc)<<1))
-#define XO30(opc) (OPCD(30)|((opc)<<2))
-#define XO31(opc) (OPCD(31)|((opc)<<1))
-#define XO58(opc) (OPCD(58)|(opc))
-#define XO62(opc) (OPCD(62)|(opc))
-
-#define B      OPCD( 18)
-#define BC     OPCD( 16)
-#define LBZ    OPCD( 34)
-#define LHZ    OPCD( 40)
-#define LHA    OPCD( 42)
-#define LWZ    OPCD( 32)
-#define STB    OPCD( 38)
-#define STH    OPCD( 44)
-#define STW    OPCD( 36)
-
-#define STD    XO62(  0)
-#define STDU   XO62(  1)
-#define STDX   XO31(149)
-
-#define LD     XO58(  0)
-#define LDX    XO31( 21)
-#define LDU    XO58(  1)
-#define LWA    XO58(  2)
-#define LWAX   XO31(341)
-
-#define ADDIC  OPCD( 12)
-#define ADDI   OPCD( 14)
-#define ADDIS  OPCD( 15)
-#define ORI    OPCD( 24)
-#define ORIS   OPCD( 25)
-#define XORI   OPCD( 26)
-#define XORIS  OPCD( 27)
-#define ANDI   OPCD( 28)
-#define ANDIS  OPCD( 29)
-#define MULLI  OPCD(  7)
-#define CMPLI  OPCD( 10)
-#define CMPI   OPCD( 11)
-
-#define LWZU   OPCD( 33)
-#define STWU   OPCD( 37)
-
-#define RLWINM OPCD( 21)
-
-#define RLDICL XO30(  0)
-#define RLDICR XO30(  1)
-#define RLDIMI XO30(  3)
-
-#define BCLR   XO19( 16)
-#define BCCTR  XO19(528)
-#define CRAND  XO19(257)
-#define CRANDC XO19(129)
-#define CRNAND XO19(225)
-#define CROR   XO19(449)
-#define CRNOR  XO19( 33)
-
-#define EXTSB  XO31(954)
-#define EXTSH  XO31(922)
-#define EXTSW  XO31(986)
-#define ADD    XO31(266)
-#define ADDE   XO31(138)
-#define ADDC   XO31( 10)
-#define AND    XO31( 28)
-#define SUBF   XO31( 40)
-#define SUBFC  XO31(  8)
-#define SUBFE  XO31(136)
-#define OR     XO31(444)
-#define XOR    XO31(316)
-#define MULLW  XO31(235)
-#define MULHWU XO31( 11)
-#define DIVW   XO31(491)
-#define DIVWU  XO31(459)
-#define CMP    XO31(  0)
-#define CMPL   XO31( 32)
-#define LHBRX  XO31(790)
-#define LWBRX  XO31(534)
-#define STHBRX XO31(918)
-#define STWBRX XO31(662)
-#define MFSPR  XO31(339)
-#define MTSPR  XO31(467)
-#define SRAWI  XO31(824)
-#define NEG    XO31(104)
-#define MFCR   XO31( 19)
-#define CNTLZW XO31( 26)
-#define CNTLZD XO31( 58)
-
-#define MULLD  XO31(233)
-#define MULHD  XO31( 73)
-#define MULHDU XO31(  9)
-#define DIVD   XO31(489)
-#define DIVDU  XO31(457)
-
-#define LBZX   XO31( 87)
-#define LHZX   XO31(279)
-#define LHAX   XO31(343)
-#define LWZX   XO31( 23)
-#define STBX   XO31(215)
-#define STHX   XO31(407)
-#define STWX   XO31(151)
-
-#define SPR(a,b) ((((a)<<5)|(b))<<11)
-#define LR     SPR(8, 0)
-#define CTR    SPR(9, 0)
-
-#define SLW    XO31( 24)
-#define SRW    XO31(536)
-#define SRAW   XO31(792)
-
-#define SLD    XO31( 27)
-#define SRD    XO31(539)
-#define SRAD   XO31(794)
-#define SRADI  XO31(413<<1)
-
-#define TW     XO31( 4)
-#define TRAP   (TW | TO (31))
-
-#define RT(r) ((r)<<21)
-#define RS(r) ((r)<<21)
-#define RA(r) ((r)<<16)
-#define RB(r) ((r)<<11)
-#define TO(t) ((t)<<21)
-#define SH(s) ((s)<<11)
-#define MB(b) ((b)<<6)
-#define ME(e) ((e)<<1)
-#define BO(o) ((o)<<21)
-#define MB64(b) ((b)<<5)
-
-#define LK    1
-
-#define TAB(t,a,b) (RT(t) | RA(a) | RB(b))
-#define SAB(s,a,b) (RS(s) | RA(a) | RB(b))
-
-#define BF(n)    ((n)<<23)
-#define BI(n, c) (((c)+((n)*4))<<16)
-#define BT(n, c) (((c)+((n)*4))<<21)
-#define BA(n, c) (((c)+((n)*4))<<16)
-#define BB(n, c) (((c)+((n)*4))<<11)
-
-#define BO_COND_TRUE  BO (12)
-#define BO_COND_FALSE BO ( 4)
-#define BO_ALWAYS     BO (20)
-
-enum {
-    CR_LT,
-    CR_GT,
-    CR_EQ,
-    CR_SO
-};
-
-static const uint32_t tcg_to_bc[10] = {
-    [TCG_COND_EQ]  = BC | BI (7, CR_EQ) | BO_COND_TRUE,
-    [TCG_COND_NE]  = BC | BI (7, CR_EQ) | BO_COND_FALSE,
-    [TCG_COND_LT]  = BC | BI (7, CR_LT) | BO_COND_TRUE,
-    [TCG_COND_GE]  = BC | BI (7, CR_LT) | BO_COND_FALSE,
-    [TCG_COND_LE]  = BC | BI (7, CR_GT) | BO_COND_FALSE,
-    [TCG_COND_GT]  = BC | BI (7, CR_GT) | BO_COND_TRUE,
-    [TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
-    [TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
-    [TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
-    [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
-};
-
-static void tcg_out_mov (TCGContext *s, TCGType type, int ret, int arg)
-{
-    tcg_out32 (s, OR | SAB (arg, ret, arg));
-}
-
-static void tcg_out_rld (TCGContext *s, int op, int ra, int rs, int sh, int mb)
-{
-    sh = SH (sh & 0x1f) | (((sh >> 5) & 1) << 1);
-    mb = MB64 ((mb >> 5) | ((mb << 1) & 0x3f));
-    tcg_out32 (s, op | RA (ra) | RS (rs) | sh | mb);
-}
-
-static void tcg_out_movi32 (TCGContext *s, int ret, int32_t arg)
-{
-    if (arg == (int16_t) arg)
-        tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff));
-    else {
-        tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
-        if (arg & 0xffff)
-            tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
-    }
-}
-
-static void tcg_out_movi (TCGContext *s, TCGType type,
-                          int ret, tcg_target_long arg)
-{
-    int32_t arg32 = arg;
-    arg = type == TCG_TYPE_I32 ? arg & 0xffffffff : arg;
-
-    if (arg == arg32) {
-        tcg_out_movi32 (s, ret, arg32);
-    }
-    else {
-        if ((uint64_t) arg >> 32) {
-            uint16_t h16 = arg >> 16;
-            uint16_t l16 = arg;
-
-            tcg_out_movi32 (s, ret, arg >> 32);
-            tcg_out_rld (s, RLDICR, ret, ret, 32, 31);
-            if (h16) tcg_out32 (s, ORIS | RS (ret) | RA (ret) | h16);
-            if (l16) tcg_out32 (s, ORI | RS (ret) | RA (ret) | l16);
-        }
-        else {
-            tcg_out_movi32 (s, ret, arg32);
-            if (arg32 < 0)
-                tcg_out_rld (s, RLDICL, ret, ret, 0, 32);
-        }
-    }
-}
-
-static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
-{
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long) s->code_ptr;
-    if ((disp << 38) >> 38 == disp)
-        tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
-    else {
-        tcg_out_movi (s, TCG_TYPE_I64, 0, (tcg_target_long) target);
-        tcg_out32 (s, MTSPR | RS (0) | CTR);
-        tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
-    }
-}
-
-static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
-{
-#ifdef __APPLE__
-    if (const_arg) {
-        tcg_out_b (s, LK, arg);
-    }
-    else {
-        tcg_out32 (s, MTSPR | RS (arg) | LR);
-        tcg_out32 (s, BCLR | BO_ALWAYS | LK);
-    }
-#else
-    int reg;
-
-    if (const_arg) {
-        reg = 2;
-        tcg_out_movi (s, TCG_TYPE_I64, reg, arg);
-    }
-    else reg = arg;
-
-    tcg_out32 (s, LD | RT (0) | RA (reg));
-    tcg_out32 (s, MTSPR | RA (0) | CTR);
-    tcg_out32 (s, LD | RT (11) | RA (reg) | 16);
-    tcg_out32 (s, LD | RT (2) | RA (reg) | 8);
-    tcg_out32 (s, BCCTR | BO_ALWAYS | LK);
-#endif
-}
-
-static void tcg_out_ldst (TCGContext *s, int ret, int addr,
-                          int offset, int op1, int op2)
-{
-    if (offset == (int16_t) offset)
-        tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
-    else {
-        tcg_out_movi (s, TCG_TYPE_I64, 0, offset);
-        tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
-    }
-}
-
-static void tcg_out_ldsta (TCGContext *s, int ret, int addr,
-                           int offset, int op1, int op2)
-{
-    if (offset == (int16_t) (offset & ~3))
-        tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
-    else {
-        tcg_out_movi (s, TCG_TYPE_I64, 0, offset);
-        tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
-    }
-}
-
-#if defined (CONFIG_SOFTMMU)
-
-#include "../../softmmu_defs.h"
-
-static void *qemu_ld_helpers[4] = {
-    __ldb_mmu,
-    __ldw_mmu,
-    __ldl_mmu,
-    __ldq_mmu,
-};
-
-static void *qemu_st_helpers[4] = {
-    __stb_mmu,
-    __stw_mmu,
-    __stl_mmu,
-    __stq_mmu,
-};
-
-static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
-                              int addr_reg, int s_bits, int offset)
-{
-#if TARGET_LONG_BITS == 32
-    tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
-
-    tcg_out32 (s, (RLWINM
-                   | RA (r0)
-                   | RS (addr_reg)
-                   | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
-                   | MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS))
-                   | ME (31 - CPU_TLB_ENTRY_BITS)
-                   )
-        );
-    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
-    tcg_out32 (s, (LWZU | RT (r1) | RA (r0) | offset));
-    tcg_out32 (s, (RLWINM
-                   | RA (r2)
-                   | RS (addr_reg)
-                   | SH (0)
-                   | MB ((32 - s_bits) & 31)
-                   | ME (31 - TARGET_PAGE_BITS)
-                   )
-        );
-#else
-    tcg_out_rld (s, RLDICL, r0, addr_reg,
-                 64 - TARGET_PAGE_BITS,
-                 64 - CPU_TLB_BITS);
-    tcg_out_rld (s, RLDICR, r0, r0,
-                 CPU_TLB_ENTRY_BITS,
-                 63 - CPU_TLB_ENTRY_BITS);
-
-    tcg_out32 (s, ADD | TAB (r0, r0, TCG_AREG0));
-    tcg_out32 (s, LD_ADDR | RT (r1) | RA (r0) | offset);
-
-    if (!s_bits) {
-        tcg_out_rld (s, RLDICR, r2, addr_reg, 0, 63 - TARGET_PAGE_BITS);
-    }
-    else {
-        tcg_out_rld (s, RLDICL, r2, addr_reg,
-                     64 - TARGET_PAGE_BITS,
-                     TARGET_PAGE_BITS - s_bits);
-        tcg_out_rld (s, RLDICL, r2, r2, TARGET_PAGE_BITS, 0);
-    }
-#endif
-}
-#endif
-
-static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
-{
-    int addr_reg, data_reg, r0, r1, rbase, mem_index, s_bits, bswap;
-#ifdef CONFIG_SOFTMMU
-    int r2;
-    void *label1_ptr, *label2_ptr;
-#endif
-
-    data_reg = *args++;
-    addr_reg = *args++;
-    mem_index = *args;
-    s_bits = opc & 3;
-
-#ifdef CONFIG_SOFTMMU
-    r0 = 3;
-    r1 = 4;
-    r2 = 0;
-    rbase = 0;
-
-    tcg_out_tlb_read (s, r0, r1, r2, addr_reg, s_bits,
-                      offsetof (CPUState, tlb_table[mem_index][0].addr_read));
-
-    tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
-
-    label1_ptr = s->code_ptr;
-#ifdef FAST_PATH
-    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
-#endif
-
-    /* slow path */
-    tcg_out_mov (s, TCG_TYPE_I64, 3, addr_reg);
-    tcg_out_movi (s, TCG_TYPE_I64, 4, mem_index);
-
-    tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
-
-    switch (opc) {
-    case 0|4:
-        tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
-        break;
-    case 1|4:
-        tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
-        break;
-    case 2|4:
-        tcg_out32 (s, EXTSW | RA (data_reg) | RS (3));
-        break;
-    case 0:
-    case 1:
-    case 2:
-    case 3:
-        if (data_reg != 3)
-            tcg_out_mov (s, TCG_TYPE_I64, data_reg, 3);
-        break;
-    }
-    label2_ptr = s->code_ptr;
-    tcg_out32 (s, B);
-
-    /* label1: fast path */
-#ifdef FAST_PATH
-    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
-#endif
-
-    /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
-    tcg_out32 (s, (LD
-                   | RT (r0)
-                   | RA (r0)
-                   | (offsetof (CPUTLBEntry, addend)
-                      - offsetof (CPUTLBEntry, addr_read))
-                   ));
-    /* r0 = env->tlb_table[mem_index][index].addend */
-    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
-    /* r0 = env->tlb_table[mem_index][index].addend + addr */
-
-#else  /* !CONFIG_SOFTMMU */
-#if TARGET_LONG_BITS == 32
-    tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
-#endif
-    r0 = addr_reg;
-    r1 = 3;
-    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
-    bswap = 0;
-#else
-    bswap = 1;
-#endif
-    switch (opc) {
-    default:
-    case 0:
-        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
-        break;
-    case 0|4:
-        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
-        tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
-        break;
-    case 1:
-        if (bswap)
-            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
-        else
-            tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
-        break;
-    case 1|4:
-        if (bswap) {
-            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
-            tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
-        }
-        else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
-        break;
-    case 2:
-        if (bswap)
-            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
-        else
-            tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
-        break;
-    case 2|4:
-        if (bswap) {
-            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
-            tcg_out32 (s, EXTSW | RA (data_reg) | RS (data_reg));
-        }
-        else tcg_out32 (s, LWAX | TAB (data_reg, rbase, r0));
-        break;
-    case 3:
-#ifdef CONFIG_USE_GUEST_BASE
-        if (bswap) {
-            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
-            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
-            tcg_out32 (s, LWBRX | TAB (      r1, rbase, r1));
-            tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
-        }
-        else tcg_out32 (s, LDX | TAB (data_reg, rbase, r0));
-#else
-        if (bswap) {
-            tcg_out_movi32 (s, 0, 4);
-            tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
-            tcg_out32 (s, LWBRX | RT (      r1) | RA (r0));
-            tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
-        }
-        else tcg_out32 (s, LD | RT (data_reg) | RA (r0));
-#endif
-        break;
-    }
-
-#ifdef CONFIG_SOFTMMU
-    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
-#endif
-}
-
-static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
-{
-    int addr_reg, r0, r1, rbase, data_reg, mem_index, bswap;
-#ifdef CONFIG_SOFTMMU
-    int r2;
-    void *label1_ptr, *label2_ptr;
-#endif
-
-    data_reg = *args++;
-    addr_reg = *args++;
-    mem_index = *args;
-
-#ifdef CONFIG_SOFTMMU
-    r0 = 3;
-    r1 = 4;
-    r2 = 0;
-    rbase = 0;
-
-    tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc,
-                      offsetof (CPUState, tlb_table[mem_index][0].addr_write));
-
-    tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
-
-    label1_ptr = s->code_ptr;
-#ifdef FAST_PATH
-    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
-#endif
-
-    /* slow path */
-    tcg_out_mov (s, TCG_TYPE_I64, 3, addr_reg);
-    tcg_out_rld (s, RLDICL, 4, data_reg, 0, 64 - (1 << (3 + opc)));
-    tcg_out_movi (s, TCG_TYPE_I64, 5, mem_index);
-
-    tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
-
-    label2_ptr = s->code_ptr;
-    tcg_out32 (s, B);
-
-    /* label1: fast path */
-#ifdef FAST_PATH
-    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
-#endif
-
-    tcg_out32 (s, (LD
-                   | RT (r0)
-                   | RA (r0)
-                   | (offsetof (CPUTLBEntry, addend)
-                      - offsetof (CPUTLBEntry, addr_write))
-                   ));
-    /* r0 = env->tlb_table[mem_index][index].addend */
-    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
-    /* r0 = env->tlb_table[mem_index][index].addend + addr */
-
-#else  /* !CONFIG_SOFTMMU */
-#if TARGET_LONG_BITS == 32
-    tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
-#endif
-    r1 = 3;
-    r0 = addr_reg;
-    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
-    bswap = 0;
-#else
-    bswap = 1;
-#endif
-    switch (opc) {
-    case 0:
-        tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
-        break;
-    case 1:
-        if (bswap)
-            tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
-        else
-            tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
-        break;
-    case 2:
-        if (bswap)
-            tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
-        else
-            tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
-        break;
-    case 3:
-        if (bswap) {
-            tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
-            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
-            tcg_out_rld (s, RLDICL, 0, data_reg, 32, 0);
-            tcg_out32 (s, STWBRX | SAB (0, rbase, r1));
-        }
-        else tcg_out32 (s, STDX | SAB (data_reg, rbase, r0));
-        break;
-    }
-
-#ifdef CONFIG_SOFTMMU
-    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
-#endif
-}
-
-static void tcg_target_qemu_prologue (TCGContext *s)
-{
-    int i, frame_size;
-#ifndef __APPLE__
-    uint64_t addr;
-#endif
-
-    frame_size = 0
-        + 8                     /* back chain */
-        + 8                     /* CR */
-        + 8                     /* LR */
-        + 8                     /* compiler doubleword */
-        + 8                     /* link editor doubleword */
-        + 8                     /* TOC save area */
-        + TCG_STATIC_CALL_ARGS_SIZE
-        + ARRAY_SIZE (tcg_target_callee_save_regs) * 8
-        ;
-    frame_size = (frame_size + 15) & ~15;
-
-#ifndef __APPLE__
-    /* First emit adhoc function descriptor */
-    addr = (uint64_t) s->code_ptr + 24;
-    tcg_out32 (s, addr >> 32); tcg_out32 (s, addr); /* entry point */
-    s->code_ptr += 16;          /* skip TOC and environment pointer */
-#endif
-
-    /* Prologue */
-    tcg_out32 (s, MFSPR | RT (0) | LR);
-    tcg_out32 (s, STDU | RS (1) | RA (1) | (-frame_size & 0xffff));
-    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
-        tcg_out32 (s, (STD
-                       | RS (tcg_target_callee_save_regs[i])
-                       | RA (1)
-                       | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
-                       )
-            );
-    tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 16));
-
-#ifdef CONFIG_USE_GUEST_BASE
-    if (GUEST_BASE) {
-        tcg_out_movi (s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);
-        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
-    }
-#endif
-
-    tcg_out32 (s, MTSPR | RS (3) | CTR);
-    tcg_out32 (s, BCCTR | BO_ALWAYS);
-
-    /* Epilogue */
-    tb_ret_addr = s->code_ptr;
-
-    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
-        tcg_out32 (s, (LD
-                       | RT (tcg_target_callee_save_regs[i])
-                       | RA (1)
-                       | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
-                       )
-            );
-    tcg_out32 (s, LD | RT (0) | RA (1) | (frame_size + 16));
-    tcg_out32 (s, MTSPR | RS (0) | LR);
-    tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
-    tcg_out32 (s, BCLR | BO_ALWAYS);
-}
-
-static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
-                        tcg_target_long arg2)
-{
-    if (type == TCG_TYPE_I32)
-        tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
-    else
-        tcg_out_ldsta (s, ret, arg1, arg2, LD, LDX);
-}
-
-static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
-                        tcg_target_long arg2)
-{
-    if (type == TCG_TYPE_I32)
-        tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
-    else
-        tcg_out_ldsta (s, arg, arg1, arg2, STD, STDX);
-}
-
-static void ppc_addi32 (TCGContext *s, int rt, int ra, tcg_target_long si)
-{
-    if (!si && rt == ra)
-        return;
-
-    if (si == (int16_t) si)
-        tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
-    else {
-        uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
-        tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
-        tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
-    }
-}
-
-static void ppc_addi64 (TCGContext *s, int rt, int ra, tcg_target_long si)
-{
-    /* XXX: suboptimal */
-    if (si == (int16_t) si
-        || ((((uint64_t) si >> 31) == 0) && (si & 0x8000) == 0))
-        ppc_addi32 (s, rt, ra, si);
-    else {
-        tcg_out_movi (s, TCG_TYPE_I64, 0, si);
-        tcg_out32 (s, ADD | RT (rt) | RA (ra));
-    }
-}
-
-static void tcg_out_addi (TCGContext *s, int reg, tcg_target_long val)
-{
-    ppc_addi64 (s, reg, reg, val);
-}
-
-static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
-                         int const_arg2, int cr, int arch64)
-{
-    int imm;
-    uint32_t op;
-
-    switch (cond) {
-    case TCG_COND_EQ:
-    case TCG_COND_NE:
-        if (const_arg2) {
-            if ((int16_t) arg2 == arg2) {
-                op = CMPI;
-                imm = 1;
-                break;
-            }
-            else if ((uint16_t) arg2 == arg2) {
-                op = CMPLI;
-                imm = 1;
-                break;
-            }
-        }
-        op = CMPL;
-        imm = 0;
-        break;
-
-    case TCG_COND_LT:
-    case TCG_COND_GE:
-    case TCG_COND_LE:
-    case TCG_COND_GT:
-        if (const_arg2) {
-            if ((int16_t) arg2 == arg2) {
-                op = CMPI;
-                imm = 1;
-                break;
-            }
-        }
-        op = CMP;
-        imm = 0;
-        break;
-
-    case TCG_COND_LTU:
-    case TCG_COND_GEU:
-    case TCG_COND_LEU:
-    case TCG_COND_GTU:
-        if (const_arg2) {
-            if ((uint16_t) arg2 == arg2) {
-                op = CMPLI;
-                imm = 1;
-                break;
-            }
-        }
-        op = CMPL;
-        imm = 0;
-        break;
-
-    default:
-        tcg_abort ();
-    }
-    op |= BF (cr) | (arch64 << 21);
-
-    if (imm)
-        tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
-    else {
-        if (const_arg2) {
-            tcg_out_movi (s, TCG_TYPE_I64, 0, arg2);
-            tcg_out32 (s, op | RA (arg1) | RB (0));
-        }
-        else
-            tcg_out32 (s, op | RA (arg1) | RB (arg2));
-    }
-
-}
-
-static void tcg_out_setcond (TCGContext *s, TCGType type, TCGCond cond,
-                             TCGArg arg0, TCGArg arg1, TCGArg arg2,
-                             int const_arg2)
-{
-    int crop, sh, arg;
-
-    switch (cond) {
-    case TCG_COND_EQ:
-        if (const_arg2) {
-            if (!arg2) {
-                arg = arg1;
-            }
-            else {
-                arg = 0;
-                if ((uint16_t) arg2 == arg2) {
-                    tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
-                }
-                else {
-                    tcg_out_movi (s, type, 0, arg2);
-                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
-                }
-            }
-        }
-        else {
-            arg = 0;
-            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
-        }
-
-        if (type == TCG_TYPE_I64) {
-            tcg_out32 (s, CNTLZD | RS (arg) | RA (0));
-            tcg_out_rld (s, RLDICL, arg0, 0, 58, 6);
-        }
-        else {
-            tcg_out32 (s, CNTLZW | RS (arg) | RA (0));
-            tcg_out32 (s, (RLWINM
-                           | RA (arg0)
-                           | RS (0)
-                           | SH (27)
-                           | MB (5)
-                           | ME (31)
-                           )
-                );
-        }
-        break;
-
-    case TCG_COND_NE:
-        if (const_arg2) {
-            if (!arg2) {
-                arg = arg1;
-            }
-            else {
-                arg = 0;
-                if ((uint16_t) arg2 == arg2) {
-                    tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
-                }
-                else {
-                    tcg_out_movi (s, type, 0, arg2);
-                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
-                }
-            }
-        }
-        else {
-            arg = 0;
-            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
-        }
-
-        if (arg == arg1 && arg1 == arg0) {
-            tcg_out32 (s, ADDIC | RT (0) | RA (arg) | 0xffff);
-            tcg_out32 (s, SUBFE | TAB (arg0, 0, arg));
-        }
-        else {
-            tcg_out32 (s, ADDIC | RT (arg0) | RA (arg) | 0xffff);
-            tcg_out32 (s, SUBFE | TAB (arg0, arg0, arg));
-        }
-        break;
-
-    case TCG_COND_GT:
-    case TCG_COND_GTU:
-        sh = 30;
-        crop = 0;
-        goto crtest;
-
-    case TCG_COND_LT:
-    case TCG_COND_LTU:
-        sh = 29;
-        crop = 0;
-        goto crtest;
-
-    case TCG_COND_GE:
-    case TCG_COND_GEU:
-        sh = 31;
-        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_LT) | BB (7, CR_LT);
-        goto crtest;
-
-    case TCG_COND_LE:
-    case TCG_COND_LEU:
-        sh = 31;
-        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_GT) | BB (7, CR_GT);
-    crtest:
-        tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7, type == TCG_TYPE_I64);
-        if (crop) tcg_out32 (s, crop);
-        tcg_out32 (s, MFCR | RT (0));
-        tcg_out32 (s, (RLWINM
-                       | RA (arg0)
-                       | RS (0)
-                       | SH (sh)
-                       | MB (31)
-                       | ME (31)
-                       )
-            );
-        break;
-
-    default:
-        tcg_abort ();
-    }
-}
-
-static void tcg_out_bc (TCGContext *s, int bc, int label_index)
-{
-    TCGLabel *l = &s->labels[label_index];
-
-    if (l->has_value)
-        tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
-    else {
-        uint16_t val = *(uint16_t *) &s->code_ptr[2];
-
-        /* Thanks to Andrzej Zaborowski */
-        tcg_out32 (s, bc | (val & 0xfffc));
-        tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
-    }
-}
-
-static void tcg_out_brcond (TCGContext *s, TCGCond cond,
-                            TCGArg arg1, TCGArg arg2, int const_arg2,
-                            int label_index, int arch64)
-{
-    tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7, arch64);
-    tcg_out_bc (s, tcg_to_bc[cond], label_index);
-}
-
-void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
-{
-    TCGContext s;
-    unsigned long patch_size;
-
-    s.code_ptr = (uint8_t *) jmp_addr;
-    tcg_out_b (&s, 0, addr);
-    patch_size = s.code_ptr - (uint8_t *) jmp_addr;
-    flush_icache_range (jmp_addr, jmp_addr + patch_size);
-}
-
-static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
-                        const int *const_args)
-{
-    int c;
-
-    switch (opc) {
-    case INDEX_op_exit_tb:
-        tcg_out_movi (s, TCG_TYPE_I64, TCG_REG_R3, args[0]);
-        tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
-        break;
-    case INDEX_op_goto_tb:
-        if (s->tb_jmp_offset) {
-            /* direct jump method */
-
-            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
-            s->code_ptr += 28;
-        }
-        else {
-            tcg_abort ();
-        }
-        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
-        break;
-    case INDEX_op_br:
-        {
-            TCGLabel *l = &s->labels[args[0]];
-
-            if (l->has_value) {
-                tcg_out_b (s, 0, l->u.value);
-            }
-            else {
-                uint32_t val = *(uint32_t *) s->code_ptr;
-
-                /* Thanks to Andrzej Zaborowski */
-                tcg_out32 (s, B | (val & 0x3fffffc));
-                tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
-            }
-        }
-        break;
-    case INDEX_op_call:
-        tcg_out_call (s, args[0], const_args[0]);
-        break;
-    case INDEX_op_jmp:
-        if (const_args[0]) {
-            tcg_out_b (s, 0, args[0]);
-        }
-        else {
-            tcg_out32 (s, MTSPR | RS (args[0]) | CTR);
-            tcg_out32 (s, BCCTR | BO_ALWAYS);
-        }
-        break;
-    case INDEX_op_movi_i32:
-        tcg_out_movi (s, TCG_TYPE_I32, args[0], args[1]);
-        break;
-    case INDEX_op_movi_i64:
-        tcg_out_movi (s, TCG_TYPE_I64, args[0], args[1]);
-        break;
-    case INDEX_op_ld8u_i32:
-    case INDEX_op_ld8u_i64:
-        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
-        break;
-    case INDEX_op_ld8s_i32:
-    case INDEX_op_ld8s_i64:
-        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
-        tcg_out32 (s, EXTSB | RS (args[0]) | RA (args[0]));
-        break;
-    case INDEX_op_ld16u_i32:
-    case INDEX_op_ld16u_i64:
-        tcg_out_ldst (s, args[0], args[1], args[2], LHZ, LHZX);
-        break;
-    case INDEX_op_ld16s_i32:
-    case INDEX_op_ld16s_i64:
-        tcg_out_ldst (s, args[0], args[1], args[2], LHA, LHAX);
-        break;
-    case INDEX_op_ld_i32:
-    case INDEX_op_ld32u_i64:
-        tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
-        break;
-    case INDEX_op_ld32s_i64:
-        tcg_out_ldsta (s, args[0], args[1], args[2], LWA, LWAX);
-        break;
-    case INDEX_op_ld_i64:
-        tcg_out_ldsta (s, args[0], args[1], args[2], LD, LDX);
-        break;
-    case INDEX_op_st8_i32:
-    case INDEX_op_st8_i64:
-        tcg_out_ldst (s, args[0], args[1], args[2], STB, STBX);
-        break;
-    case INDEX_op_st16_i32:
-    case INDEX_op_st16_i64:
-        tcg_out_ldst (s, args[0], args[1], args[2], STH, STHX);
-        break;
-    case INDEX_op_st_i32:
-    case INDEX_op_st32_i64:
-        tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
-        break;
-    case INDEX_op_st_i64:
-        tcg_out_ldsta (s, args[0], args[1], args[2], STD, STDX);
-        break;
-
-    case INDEX_op_add_i32:
-        if (const_args[2])
-            ppc_addi32 (s, args[0], args[1], args[2]);
-        else
-            tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
-        break;
-    case INDEX_op_sub_i32:
-        if (const_args[2])
-            ppc_addi32 (s, args[0], args[1], -args[2]);
-        else
-            tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
-        break;
-
-    case INDEX_op_and_i64:
-    case INDEX_op_and_i32:
-        if (const_args[2]) {
-            if ((args[2] & 0xffff) == args[2])
-                tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | args[2]);
-            else if ((args[2] & 0xffff0000) == args[2])
-                tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
-                           | ((args[2] >> 16) & 0xffff));
-            else {
-                tcg_out_movi (s, (opc == INDEX_op_and_i32
-                                  ? TCG_TYPE_I32
-                                  : TCG_TYPE_I64),
-                              0, args[2]);
-                tcg_out32 (s, AND | SAB (args[1], args[0], 0));
-            }
-        }
-        else
-            tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_or_i64:
-    case INDEX_op_or_i32:
-        if (const_args[2]) {
-            if (args[2] & 0xffff) {
-                tcg_out32 (s, ORI | RS (args[1]) | RA (args[0])
-                           | (args[2] & 0xffff));
-                if (args[2] >> 16)
-                    tcg_out32 (s, ORIS | RS (args[0])  | RA (args[0])
-                               | ((args[2] >> 16) & 0xffff));
-            }
-            else {
-                tcg_out32 (s, ORIS | RS (args[1])  | RA (args[0])
-                           | ((args[2] >> 16) & 0xffff));
-            }
-        }
-        else
-            tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_xor_i64:
-    case INDEX_op_xor_i32:
-        if (const_args[2]) {
-            if ((args[2] & 0xffff) == args[2])
-                tcg_out32 (s, XORI | RS (args[1])  | RA (args[0])
-                           | (args[2] & 0xffff));
-            else if ((args[2] & 0xffff0000) == args[2])
-                tcg_out32 (s, XORIS | RS (args[1])  | RA (args[0])
-                           | ((args[2] >> 16) & 0xffff));
-            else {
-                tcg_out_movi (s, (opc == INDEX_op_and_i32
-                                  ? TCG_TYPE_I32
-                                  : TCG_TYPE_I64),
-                              0, args[2]);
-                tcg_out32 (s, XOR | SAB (args[1], args[0], 0));
-            }
-        }
-        else
-            tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
-        break;
-
-    case INDEX_op_mul_i32:
-        if (const_args[2]) {
-            if (args[2] == (int16_t) args[2])
-                tcg_out32 (s, MULLI | RT (args[0]) | RA (args[1])
-                           | (args[2] & 0xffff));
-            else {
-                tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
-                tcg_out32 (s, MULLW | TAB (args[0], args[1], 0));
-            }
-        }
-        else
-            tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2]));
-        break;
-
-    case INDEX_op_div_i32:
-        tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2]));
-        break;
-
-    case INDEX_op_divu_i32:
-        tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
-        break;
-
-    case INDEX_op_rem_i32:
-        tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
-        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
-        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
-        break;
-
-    case INDEX_op_remu_i32:
-        tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
-        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
-        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
-        break;
-
-    case INDEX_op_shl_i32:
-        if (const_args[2]) {
-            tcg_out32 (s, (RLWINM
-                           | RA (args[0])
-                           | RS (args[1])
-                           | SH (args[2])
-                           | MB (0)
-                           | ME (31 - args[2])
-                           )
-                );
-        }
-        else
-            tcg_out32 (s, SLW | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_shr_i32:
-        if (const_args[2]) {
-            tcg_out32 (s, (RLWINM
-                           | RA (args[0])
-                           | RS (args[1])
-                           | SH (32 - args[2])
-                           | MB (args[2])
-                           | ME (31)
-                           )
-                );
-        }
-        else
-            tcg_out32 (s, SRW | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_sar_i32:
-        if (const_args[2])
-            tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2]));
-        else
-            tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
-        break;
-
-    case INDEX_op_brcond_i32:
-        tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3], 0);
-        break;
-
-    case INDEX_op_brcond_i64:
-        tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3], 1);
-        break;
-
-    case INDEX_op_neg_i32:
-    case INDEX_op_neg_i64:
-        tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
-        break;
-
-    case INDEX_op_add_i64:
-        if (const_args[2])
-            ppc_addi64 (s, args[0], args[1], args[2]);
-        else
-            tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
-        break;
-    case INDEX_op_sub_i64:
-        if (const_args[2])
-            ppc_addi64 (s, args[0], args[1], -args[2]);
-        else
-            tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
-        break;
-
-    case INDEX_op_shl_i64:
-        if (const_args[2])
-            tcg_out_rld (s, RLDICR, args[0], args[1], args[2], 63 - args[2]);
-        else
-            tcg_out32 (s, SLD | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_shr_i64:
-        if (const_args[2])
-            tcg_out_rld (s, RLDICL, args[0], args[1], 64 - args[2], args[2]);
-        else
-            tcg_out32 (s, SRD | SAB (args[1], args[0], args[2]));
-        break;
-    case INDEX_op_sar_i64:
-        if (const_args[2]) {
-            int sh = SH (args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
-            tcg_out32 (s, SRADI | RA (args[0]) | RS (args[1]) | sh);
-        }
-        else
-            tcg_out32 (s, SRAD | SAB (args[1], args[0], args[2]));
-        break;
-
-    case INDEX_op_mul_i64:
-        tcg_out32 (s, MULLD | TAB (args[0], args[1], args[2]));
-        break;
-    case INDEX_op_div_i64:
-        tcg_out32 (s, DIVD | TAB (args[0], args[1], args[2]));
-        break;
-    case INDEX_op_divu_i64:
-        tcg_out32 (s, DIVDU | TAB (args[0], args[1], args[2]));
-        break;
-    case INDEX_op_rem_i64:
-        tcg_out32 (s, DIVD | TAB (0, args[1], args[2]));
-        tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
-        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
-        break;
-    case INDEX_op_remu_i64:
-        tcg_out32 (s, DIVDU | TAB (0, args[1], args[2]));
-        tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
-        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
-        break;
-
-    case INDEX_op_qemu_ld8u:
-        tcg_out_qemu_ld (s, args, 0);
-        break;
-    case INDEX_op_qemu_ld8s:
-        tcg_out_qemu_ld (s, args, 0 | 4);
-        break;
-    case INDEX_op_qemu_ld16u:
-        tcg_out_qemu_ld (s, args, 1);
-        break;
-    case INDEX_op_qemu_ld16s:
-        tcg_out_qemu_ld (s, args, 1 | 4);
-        break;
-    case INDEX_op_qemu_ld32:
-    case INDEX_op_qemu_ld32u:
-        tcg_out_qemu_ld (s, args, 2);
-        break;
-    case INDEX_op_qemu_ld32s:
-        tcg_out_qemu_ld (s, args, 2 | 4);
-        break;
-    case INDEX_op_qemu_ld64:
-        tcg_out_qemu_ld (s, args, 3);
-        break;
-    case INDEX_op_qemu_st8:
-        tcg_out_qemu_st (s, args, 0);
-        break;
-    case INDEX_op_qemu_st16:
-        tcg_out_qemu_st (s, args, 1);
-        break;
-    case INDEX_op_qemu_st32:
-        tcg_out_qemu_st (s, args, 2);
-        break;
-    case INDEX_op_qemu_st64:
-        tcg_out_qemu_st (s, args, 3);
-        break;
-
-    case INDEX_op_ext8s_i32:
-    case INDEX_op_ext8s_i64:
-        c = EXTSB;
-        goto gen_ext;
-    case INDEX_op_ext16s_i32:
-    case INDEX_op_ext16s_i64:
-        c = EXTSH;
-        goto gen_ext;
-    case INDEX_op_ext32s_i64:
-        c = EXTSW;
-        goto gen_ext;
-    gen_ext:
-        tcg_out32 (s, c | RS (args[1]) | RA (args[0]));
-        break;
-
-    case INDEX_op_setcond_i32:
-        tcg_out_setcond (s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
-                         const_args[2]);
-        break;
-    case INDEX_op_setcond_i64:
-        tcg_out_setcond (s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
-                         const_args[2]);
-        break;
-
-    default:
-        tcg_dump_ops (s, stderr);
-        tcg_abort ();
-    }
-}
-
-static const TCGTargetOpDef ppc_op_defs[] = {
-    { INDEX_op_exit_tb, { } },
-    { INDEX_op_goto_tb, { } },
-    { INDEX_op_call, { "ri" } },
-    { INDEX_op_jmp, { "ri" } },
-    { INDEX_op_br, { } },
-
-    { INDEX_op_mov_i32, { "r", "r" } },
-    { INDEX_op_mov_i64, { "r", "r" } },
-    { INDEX_op_movi_i32, { "r" } },
-    { INDEX_op_movi_i64, { "r" } },
-
-    { INDEX_op_ld8u_i32, { "r", "r" } },
-    { INDEX_op_ld8s_i32, { "r", "r" } },
-    { INDEX_op_ld16u_i32, { "r", "r" } },
-    { INDEX_op_ld16s_i32, { "r", "r" } },
-    { INDEX_op_ld_i32, { "r", "r" } },
-    { INDEX_op_ld_i64, { "r", "r" } },
-    { INDEX_op_st8_i32, { "r", "r" } },
-    { INDEX_op_st8_i64, { "r", "r" } },
-    { INDEX_op_st16_i32, { "r", "r" } },
-    { INDEX_op_st16_i64, { "r", "r" } },
-    { INDEX_op_st_i32, { "r", "r" } },
-    { INDEX_op_st_i64, { "r", "r" } },
-    { INDEX_op_st32_i64, { "r", "r" } },
-
-    { INDEX_op_ld8u_i64, { "r", "r" } },
-    { INDEX_op_ld8s_i64, { "r", "r" } },
-    { INDEX_op_ld16u_i64, { "r", "r" } },
-    { 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" } },
-    { INDEX_op_div_i32, { "r", "r", "r" } },
-    { INDEX_op_divu_i32, { "r", "r", "r" } },
-    { INDEX_op_rem_i32, { "r", "r", "r" } },
-    { INDEX_op_remu_i32, { "r", "r", "r" } },
-    { INDEX_op_sub_i32, { "r", "r", "ri" } },
-    { INDEX_op_and_i32, { "r", "r", "ri" } },
-    { INDEX_op_or_i32, { "r", "r", "ri" } },
-    { INDEX_op_xor_i32, { "r", "r", "ri" } },
-
-    { INDEX_op_shl_i32, { "r", "r", "ri" } },
-    { INDEX_op_shr_i32, { "r", "r", "ri" } },
-    { INDEX_op_sar_i32, { "r", "r", "ri" } },
-
-    { INDEX_op_brcond_i32, { "r", "ri" } },
-    { INDEX_op_brcond_i64, { "r", "ri" } },
-
-    { INDEX_op_neg_i32, { "r", "r" } },
-
-    { INDEX_op_add_i64, { "r", "r", "ri" } },
-    { INDEX_op_sub_i64, { "r", "r", "ri" } },
-    { INDEX_op_and_i64, { "r", "r", "rZ" } },
-    { INDEX_op_or_i64, { "r", "r", "rZ" } },
-    { INDEX_op_xor_i64, { "r", "r", "rZ" } },
-
-    { INDEX_op_shl_i64, { "r", "r", "ri" } },
-    { INDEX_op_shr_i64, { "r", "r", "ri" } },
-    { INDEX_op_sar_i64, { "r", "r", "ri" } },
-
-    { INDEX_op_mul_i64, { "r", "r", "r" } },
-    { INDEX_op_div_i64, { "r", "r", "r" } },
-    { INDEX_op_divu_i64, { "r", "r", "r" } },
-    { INDEX_op_rem_i64, { "r", "r", "r" } },
-    { INDEX_op_remu_i64, { "r", "r", "r" } },
-
-    { INDEX_op_neg_i64, { "r", "r" } },
-
-    { INDEX_op_qemu_ld8u, { "r", "L" } },
-    { INDEX_op_qemu_ld8s, { "r", "L" } },
-    { INDEX_op_qemu_ld16u, { "r", "L" } },
-    { INDEX_op_qemu_ld16s, { "r", "L" } },
-    { INDEX_op_qemu_ld32, { "r", "L" } },
-    { INDEX_op_qemu_ld32u, { "r", "L" } },
-    { INDEX_op_qemu_ld32s, { "r", "L" } },
-    { INDEX_op_qemu_ld64, { "r", "L" } },
-
-    { INDEX_op_qemu_st8, { "S", "S" } },
-    { INDEX_op_qemu_st16, { "S", "S" } },
-    { INDEX_op_qemu_st32, { "S", "S" } },
-    { INDEX_op_qemu_st64, { "S", "S" } },
-
-    { INDEX_op_ext8s_i32, { "r", "r" } },
-    { INDEX_op_ext16s_i32, { "r", "r" } },
-    { INDEX_op_ext8s_i64, { "r", "r" } },
-    { INDEX_op_ext16s_i64, { "r", "r" } },
-    { INDEX_op_ext32s_i64, { "r", "r" } },
-
-    { INDEX_op_setcond_i32, { "r", "r", "ri" } },
-    { INDEX_op_setcond_i64, { "r", "r", "ri" } },
-
-    { -1 },
-};
-
-static void tcg_target_init (TCGContext *s)
-{
-    tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
-    tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
-    tcg_regset_set32 (tcg_target_call_clobber_regs, 0,
-                     (1 << TCG_REG_R0) |
-#ifdef __APPLE__
-                     (1 << TCG_REG_R2) |
-#endif
-                     (1 << TCG_REG_R3) |
-                     (1 << TCG_REG_R4) |
-                     (1 << TCG_REG_R5) |
-                     (1 << TCG_REG_R6) |
-                     (1 << TCG_REG_R7) |
-                     (1 << TCG_REG_R8) |
-                     (1 << TCG_REG_R9) |
-                     (1 << TCG_REG_R10) |
-                     (1 << TCG_REG_R11) |
-                     (1 << TCG_REG_R12)
-        );
-
-    tcg_regset_clear (s->reserved_regs);
-    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R0);
-    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R1);
-#ifndef __APPLE__
-    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R2);
-#endif
-    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
-
-    tcg_add_target_add_op_defs (ppc_op_defs);
-}
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
deleted file mode 100644
index 8a6db11..0000000
--- a/tcg/ppc64/tcg-target.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define TCG_TARGET_PPC64 1
-
-#define TCG_TARGET_REG_BITS 64
-#define TCG_TARGET_WORDS_BIGENDIAN
-#define TCG_TARGET_NB_REGS 32
-
-enum {
-    TCG_REG_R0 = 0,
-    TCG_REG_R1,
-    TCG_REG_R2,
-    TCG_REG_R3,
-    TCG_REG_R4,
-    TCG_REG_R5,
-    TCG_REG_R6,
-    TCG_REG_R7,
-    TCG_REG_R8,
-    TCG_REG_R9,
-    TCG_REG_R10,
-    TCG_REG_R11,
-    TCG_REG_R12,
-    TCG_REG_R13,
-    TCG_REG_R14,
-    TCG_REG_R15,
-    TCG_REG_R16,
-    TCG_REG_R17,
-    TCG_REG_R18,
-    TCG_REG_R19,
-    TCG_REG_R20,
-    TCG_REG_R21,
-    TCG_REG_R22,
-    TCG_REG_R23,
-    TCG_REG_R24,
-    TCG_REG_R25,
-    TCG_REG_R26,
-    TCG_REG_R27,
-    TCG_REG_R28,
-    TCG_REG_R29,
-    TCG_REG_R30,
-    TCG_REG_R31
-};
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK TCG_REG_R1
-#define TCG_TARGET_STACK_ALIGN 16
-#define TCG_TARGET_CALL_STACK_OFFSET 48
-
-/* optional instructions */
-#define TCG_TARGET_HAS_div_i32
-/* #define TCG_TARGET_HAS_rot_i32 */
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-/* #define TCG_TARGET_HAS_ext8u_i32 */
-/* #define TCG_TARGET_HAS_ext16u_i32 */
-/* #define TCG_TARGET_HAS_bswap16_i32 */
-/* #define TCG_TARGET_HAS_bswap32_i32 */
-/* #define TCG_TARGET_HAS_not_i32 */
-#define TCG_TARGET_HAS_neg_i32
-/* #define TCG_TARGET_HAS_andc_i32 */
-/* #define TCG_TARGET_HAS_orc_i32 */
-/* #define TCG_TARGET_HAS_eqv_i32 */
-/* #define TCG_TARGET_HAS_nand_i32 */
-/* #define TCG_TARGET_HAS_nor_i32 */
-
-#define TCG_TARGET_HAS_div_i64
-/* #define TCG_TARGET_HAS_rot_i64 */
-#define TCG_TARGET_HAS_ext8s_i64
-#define TCG_TARGET_HAS_ext16s_i64
-#define TCG_TARGET_HAS_ext32s_i64
-/* #define TCG_TARGET_HAS_ext8u_i64 */
-/* #define TCG_TARGET_HAS_ext16u_i64 */
-/* #define TCG_TARGET_HAS_ext32u_i64 */
-/* #define TCG_TARGET_HAS_bswap16_i64 */
-/* #define TCG_TARGET_HAS_bswap32_i64 */
-/* #define TCG_TARGET_HAS_bswap64_i64 */
-/* #define TCG_TARGET_HAS_not_i64 */
-#define TCG_TARGET_HAS_neg_i64
-/* #define TCG_TARGET_HAS_andc_i64 */
-/* #define TCG_TARGET_HAS_orc_i64 */
-/* #define TCG_TARGET_HAS_eqv_i64 */
-/* #define TCG_TARGET_HAS_nand_i64 */
-/* #define TCG_TARGET_HAS_nor_i64 */
-
-#define TCG_AREG0 TCG_REG_R27
-
-#define TCG_TARGET_HAS_GUEST_BASE
-#define TCG_TARGET_EXTEND_ARGS 1
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
deleted file mode 100644
index 5f1353a..0000000
--- a/tcg/sparc/tcg-target.c
+++ /dev/null
@@ -1,1569 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 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 NDEBUG
-static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
-    "%g0",
-    "%g1",
-    "%g2",
-    "%g3",
-    "%g4",
-    "%g5",
-    "%g6",
-    "%g7",
-    "%o0",
-    "%o1",
-    "%o2",
-    "%o3",
-    "%o4",
-    "%o5",
-    "%o6",
-    "%o7",
-    "%l0",
-    "%l1",
-    "%l2",
-    "%l3",
-    "%l4",
-    "%l5",
-    "%l6",
-    "%l7",
-    "%i0",
-    "%i1",
-    "%i2",
-    "%i3",
-    "%i4",
-    "%i5",
-    "%i6",
-    "%i7",
-};
-#endif
-
-static const int tcg_target_reg_alloc_order[] = {
-    TCG_REG_L0,
-    TCG_REG_L1,
-    TCG_REG_L2,
-    TCG_REG_L3,
-    TCG_REG_L4,
-    TCG_REG_L5,
-    TCG_REG_L6,
-    TCG_REG_L7,
-    TCG_REG_I0,
-    TCG_REG_I1,
-    TCG_REG_I2,
-    TCG_REG_I3,
-    TCG_REG_I4,
-};
-
-static const int tcg_target_call_iarg_regs[6] = {
-    TCG_REG_O0,
-    TCG_REG_O1,
-    TCG_REG_O2,
-    TCG_REG_O3,
-    TCG_REG_O4,
-    TCG_REG_O5,
-};
-
-static const int tcg_target_call_oarg_regs[2] = {
-    TCG_REG_O0,
-    TCG_REG_O1,
-};
-
-static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
-{
-    return (val << ((sizeof(tcg_target_long) * 8 - bits))
-            >> (sizeof(tcg_target_long) * 8 - bits)) == val;
-}
-
-static inline int check_fit_i32(uint32_t val, unsigned int bits)
-{
-    return ((val << (32 - bits)) >> (32 - bits)) == val;
-}
-
-static void patch_reloc(uint8_t *code_ptr, int type,
-                        tcg_target_long value, tcg_target_long addend)
-{
-    value += addend;
-    switch (type) {
-    case R_SPARC_32:
-        if (value != (uint32_t)value)
-            tcg_abort();
-        *(uint32_t *)code_ptr = value;
-        break;
-    case R_SPARC_WDISP22:
-        value -= (long)code_ptr;
-        value >>= 2;
-        if (!check_fit_tl(value, 22))
-            tcg_abort();
-        *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x3fffff) | value;
-        break;
-    case R_SPARC_WDISP19:
-        value -= (long)code_ptr;
-        value >>= 2;
-        if (!check_fit_tl(value, 19))
-            tcg_abort();
-        *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x7ffff) | value;
-        break;
-    default:
-        tcg_abort();
-    }
-}
-
-/* maximum number of register used for input function arguments */
-static inline int tcg_target_get_call_iarg_regs_count(int flags)
-{
-    return 6;
-}
-
-/* parse target specific constraints */
-static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
-{
-    const char *ct_str;
-
-    ct_str = *pct_str;
-    switch (ct_str[0]) {
-    case 'r':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
-        break;
-    case 'L': /* qemu_ld/st constraint */
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
-        // Helper args
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
-        break;
-    case 'I':
-        ct->ct |= TCG_CT_CONST_S11;
-        break;
-    case 'J':
-        ct->ct |= TCG_CT_CONST_S13;
-        break;
-    default:
-        return -1;
-    }
-    ct_str++;
-    *pct_str = ct_str;
-    return 0;
-}
-
-/* test if a constant matches the constraint */
-static inline int tcg_target_const_match(tcg_target_long val,
-                                         const TCGArgConstraint *arg_ct)
-{
-    int ct;
-
-    ct = arg_ct->ct;
-    if (ct & TCG_CT_CONST)
-        return 1;
-    else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11))
-        return 1;
-    else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13))
-        return 1;
-    else
-        return 0;
-}
-
-#define INSN_OP(x)  ((x) << 30)
-#define INSN_OP2(x) ((x) << 22)
-#define INSN_OP3(x) ((x) << 19)
-#define INSN_OPF(x) ((x) << 5)
-#define INSN_RD(x)  ((x) << 25)
-#define INSN_RS1(x) ((x) << 14)
-#define INSN_RS2(x) (x)
-#define INSN_ASI(x) ((x) << 5)
-
-#define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff))
-#define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
-#define INSN_OFF19(x) (((x) >> 2) & 0x07ffff)
-#define INSN_OFF22(x) (((x) >> 2) & 0x3fffff)
-
-#define INSN_COND(x, a) (((x) << 25) | ((a) << 29))
-#define COND_N     0x0
-#define COND_E     0x1
-#define COND_LE    0x2
-#define COND_L     0x3
-#define COND_LEU   0x4
-#define COND_CS    0x5
-#define COND_NEG   0x6
-#define COND_VS    0x7
-#define COND_A     0x8
-#define COND_NE    0x9
-#define COND_G     0xa
-#define COND_GE    0xb
-#define COND_GU    0xc
-#define COND_CC    0xd
-#define COND_POS   0xe
-#define COND_VC    0xf
-#define BA         (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2))
-
-#define MOVCC_ICC  (1 << 18)
-#define MOVCC_XCC  (1 << 18 | 1 << 12)
-
-#define ARITH_ADD  (INSN_OP(2) | INSN_OP3(0x00))
-#define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10))
-#define ARITH_AND  (INSN_OP(2) | INSN_OP3(0x01))
-#define ARITH_ANDN (INSN_OP(2) | INSN_OP3(0x05))
-#define ARITH_OR   (INSN_OP(2) | INSN_OP3(0x02))
-#define ARITH_ORCC (INSN_OP(2) | INSN_OP3(0x12))
-#define ARITH_ORN  (INSN_OP(2) | INSN_OP3(0x06))
-#define ARITH_XOR  (INSN_OP(2) | INSN_OP3(0x03))
-#define ARITH_SUB  (INSN_OP(2) | INSN_OP3(0x04))
-#define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
-#define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x10))
-#define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c))
-#define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
-#define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e))
-#define ARITH_SDIV (INSN_OP(2) | INSN_OP3(0x0f))
-#define ARITH_MULX (INSN_OP(2) | INSN_OP3(0x09))
-#define ARITH_UDIVX (INSN_OP(2) | INSN_OP3(0x0d))
-#define ARITH_SDIVX (INSN_OP(2) | INSN_OP3(0x2d))
-#define ARITH_MOVCC (INSN_OP(2) | INSN_OP3(0x2c))
-
-#define SHIFT_SLL  (INSN_OP(2) | INSN_OP3(0x25))
-#define SHIFT_SRL  (INSN_OP(2) | INSN_OP3(0x26))
-#define SHIFT_SRA  (INSN_OP(2) | INSN_OP3(0x27))
-
-#define SHIFT_SLLX (INSN_OP(2) | INSN_OP3(0x25) | (1 << 12))
-#define SHIFT_SRLX (INSN_OP(2) | INSN_OP3(0x26) | (1 << 12))
-#define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12))
-
-#define RDY        (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0))
-#define WRY        (INSN_OP(2) | INSN_OP3(0x30) | INSN_RD(0))
-#define JMPL       (INSN_OP(2) | INSN_OP3(0x38))
-#define SAVE       (INSN_OP(2) | INSN_OP3(0x3c))
-#define RESTORE    (INSN_OP(2) | INSN_OP3(0x3d))
-#define SETHI      (INSN_OP(0) | INSN_OP2(0x4))
-#define CALL       INSN_OP(1)
-#define LDUB       (INSN_OP(3) | INSN_OP3(0x01))
-#define LDSB       (INSN_OP(3) | INSN_OP3(0x09))
-#define LDUH       (INSN_OP(3) | INSN_OP3(0x02))
-#define LDSH       (INSN_OP(3) | INSN_OP3(0x0a))
-#define LDUW       (INSN_OP(3) | INSN_OP3(0x00))
-#define LDSW       (INSN_OP(3) | INSN_OP3(0x08))
-#define LDX        (INSN_OP(3) | INSN_OP3(0x0b))
-#define STB        (INSN_OP(3) | INSN_OP3(0x05))
-#define STH        (INSN_OP(3) | INSN_OP3(0x06))
-#define STW        (INSN_OP(3) | INSN_OP3(0x04))
-#define STX        (INSN_OP(3) | INSN_OP3(0x0e))
-#define LDUBA      (INSN_OP(3) | INSN_OP3(0x11))
-#define LDSBA      (INSN_OP(3) | INSN_OP3(0x19))
-#define LDUHA      (INSN_OP(3) | INSN_OP3(0x12))
-#define LDSHA      (INSN_OP(3) | INSN_OP3(0x1a))
-#define LDUWA      (INSN_OP(3) | INSN_OP3(0x10))
-#define LDSWA      (INSN_OP(3) | INSN_OP3(0x18))
-#define LDXA       (INSN_OP(3) | INSN_OP3(0x1b))
-#define STBA       (INSN_OP(3) | INSN_OP3(0x15))
-#define STHA       (INSN_OP(3) | INSN_OP3(0x16))
-#define STWA       (INSN_OP(3) | INSN_OP3(0x14))
-#define STXA       (INSN_OP(3) | INSN_OP3(0x1e))
-
-#ifndef ASI_PRIMARY_LITTLE
-#define ASI_PRIMARY_LITTLE 0x88
-#endif
-
-static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2,
-                                 int op)
-{
-    tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
-              INSN_RS2(rs2));
-}
-
-static inline void tcg_out_arithi(TCGContext *s, int rd, int rs1,
-                                  uint32_t offset, int op)
-{
-    tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
-              INSN_IMM13(offset));
-}
-
-static void tcg_out_arithc(TCGContext *s, int rd, int rs1,
-			   int val2, int val2const, int op)
-{
-    tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1)
-              | (val2const ? INSN_IMM13(val2) : INSN_RS2(val2)));
-}
-
-static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg)
-{
-    tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR);
-}
-
-static inline void tcg_out_sethi(TCGContext *s, int ret, uint32_t arg)
-{
-    tcg_out32(s, SETHI | INSN_RD(ret) | ((arg & 0xfffffc00) >> 10));
-}
-
-static inline void tcg_out_movi_imm13(TCGContext *s, int ret, uint32_t arg)
-{
-    tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR);
-}
-
-static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t arg)
-{
-    if (check_fit_tl(arg, 13))
-        tcg_out_movi_imm13(s, ret, arg);
-    else {
-        tcg_out_sethi(s, ret, arg);
-        if (arg & 0x3ff)
-            tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
-    }
-}
-
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
-                                int ret, tcg_target_long arg)
-{
-    /* All 32-bit constants, as well as 64-bit constants with
-       no high bits set go through movi_imm32.  */
-    if (TCG_TARGET_REG_BITS == 32
-        || type == TCG_TYPE_I32
-        || (arg & ~(tcg_target_long)0xffffffff) == 0) {
-        tcg_out_movi_imm32(s, ret, arg);
-    } else if (check_fit_tl(arg, 13)) {
-        /* A 13-bit constant sign-extended to 64-bits.  */
-        tcg_out_movi_imm13(s, ret, arg);
-    } else if (check_fit_tl(arg, 32)) {
-        /* A 32-bit constant sign-extended to 64-bits.  */
-        tcg_out_sethi(s, ret, ~arg);
-        tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
-    } else {
-        tcg_out_movi_imm32(s, TCG_REG_I4, arg >> (TCG_TARGET_REG_BITS / 2));
-        tcg_out_arithi(s, TCG_REG_I4, TCG_REG_I4, 32, SHIFT_SLLX);
-        tcg_out_movi_imm32(s, ret, arg);
-        tcg_out_arith(s, ret, ret, TCG_REG_I4, ARITH_OR);
-    }
-}
-
-static inline void tcg_out_ld_raw(TCGContext *s, int ret,
-                                  tcg_target_long arg)
-{
-    tcg_out_sethi(s, ret, arg);
-    tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
-              INSN_IMM13(arg & 0x3ff));
-}
-
-static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
-                                  tcg_target_long arg)
-{
-    if (!check_fit_tl(arg, 10))
-        tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ffULL);
-    if (TCG_TARGET_REG_BITS == 64) {
-        tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) |
-                  INSN_IMM13(arg & 0x3ff));
-    } else {
-        tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
-                  INSN_IMM13(arg & 0x3ff));
-    }
-}
-
-static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op)
-{
-    if (check_fit_tl(offset, 13))
-        tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
-                  INSN_IMM13(offset));
-    else {
-        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
-        tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
-                  INSN_RS2(addr));
-    }
-}
-
-static inline void tcg_out_ldst_asi(TCGContext *s, int ret, int addr,
-                                    int offset, int op, int asi)
-{
-    tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
-    tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
-              INSN_ASI(asi) | INSN_RS2(addr));
-}
-
-static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
-                              int arg1, tcg_target_long arg2)
-{
-    if (type == TCG_TYPE_I32)
-        tcg_out_ldst(s, ret, arg1, arg2, LDUW);
-    else
-        tcg_out_ldst(s, ret, arg1, arg2, LDX);
-}
-
-static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
-                              int arg1, tcg_target_long arg2)
-{
-    if (type == TCG_TYPE_I32)
-        tcg_out_ldst(s, arg, arg1, arg2, STW);
-    else
-        tcg_out_ldst(s, arg, arg1, arg2, STX);
-}
-
-static inline void tcg_out_sety(TCGContext *s, int rs)
-{
-    tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs));
-}
-
-static inline void tcg_out_rdy(TCGContext *s, int rd)
-{
-    tcg_out32(s, RDY | INSN_RD(rd));
-}
-
-static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
-    if (val != 0) {
-        if (check_fit_tl(val, 13))
-            tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
-        else {
-            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, val);
-            tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_ADD);
-        }
-    }
-}
-
-static inline void tcg_out_andi(TCGContext *s, int reg, tcg_target_long val)
-{
-    if (val != 0) {
-        if (check_fit_tl(val, 13))
-            tcg_out_arithi(s, reg, reg, val, ARITH_AND);
-        else {
-            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, val);
-            tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_AND);
-        }
-    }
-}
-
-static void tcg_out_div32(TCGContext *s, int rd, int rs1,
-                          int val2, int val2const, int uns)
-{
-    /* Load Y with the sign/zero extension of RS1 to 64-bits.  */
-    if (uns) {
-        tcg_out_sety(s, TCG_REG_G0);
-    } else {
-        tcg_out_arithi(s, TCG_REG_I5, rs1, 31, SHIFT_SRA);
-        tcg_out_sety(s, TCG_REG_I5);
-    }
-
-    tcg_out_arithc(s, rd, rs1, val2, val2const,
-                   uns ? ARITH_UDIV : ARITH_SDIV);
-}
-
-static inline void tcg_out_nop(TCGContext *s)
-{
-    tcg_out_sethi(s, TCG_REG_G0, 0);
-}
-
-static void tcg_out_branch_i32(TCGContext *s, int opc, int label_index)
-{
-    int32_t val;
-    TCGLabel *l = &s->labels[label_index];
-
-    if (l->has_value) {
-        val = l->u.value - (tcg_target_long)s->code_ptr;
-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2)
-                      | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr)));
-    } else {
-        tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP22, label_index, 0);
-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | 0));
-    }
-}
-
-#if TCG_TARGET_REG_BITS == 64
-static void tcg_out_branch_i64(TCGContext *s, int opc, int label_index)
-{
-    int32_t val;
-    TCGLabel *l = &s->labels[label_index];
-
-    if (l->has_value) {
-        val = l->u.value - (tcg_target_long)s->code_ptr;
-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
-                      (0x5 << 19) |
-                      INSN_OFF19(l->u.value - (unsigned long)s->code_ptr)));
-    } else {
-        tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label_index, 0);
-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
-                      (0x5 << 19) | 0));
-    }
-}
-#endif
-
-static const uint8_t tcg_cond_to_bcond[10] = {
-    [TCG_COND_EQ] = COND_E,
-    [TCG_COND_NE] = COND_NE,
-    [TCG_COND_LT] = COND_L,
-    [TCG_COND_GE] = COND_GE,
-    [TCG_COND_LE] = COND_LE,
-    [TCG_COND_GT] = COND_G,
-    [TCG_COND_LTU] = COND_CS,
-    [TCG_COND_GEU] = COND_CC,
-    [TCG_COND_LEU] = COND_LEU,
-    [TCG_COND_GTU] = COND_GU,
-};
-
-static void tcg_out_cmp(TCGContext *s, TCGArg c1, TCGArg c2, int c2const)
-{
-    tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
-}
-
-static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond,
-                               TCGArg arg1, TCGArg arg2, int const_arg2,
-                               int label_index)
-{
-    tcg_out_cmp(s, arg1, arg2, const_arg2);
-    tcg_out_branch_i32(s, tcg_cond_to_bcond[cond], label_index);
-    tcg_out_nop(s);
-}
-
-#if TCG_TARGET_REG_BITS == 64
-static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond,
-                               TCGArg arg1, TCGArg arg2, int const_arg2,
-                               int label_index)
-{
-    tcg_out_cmp(s, arg1, arg2, const_arg2);
-    tcg_out_branch_i64(s, tcg_cond_to_bcond[cond], label_index);
-    tcg_out_nop(s);
-}
-#else
-static void tcg_out_brcond2_i32(TCGContext *s, TCGCond cond,
-                                TCGArg al, TCGArg ah,
-                                TCGArg bl, int blconst,
-                                TCGArg bh, int bhconst, int label_dest)
-{
-    int cc, label_next = gen_new_label();
-
-    tcg_out_cmp(s, ah, bh, bhconst);
-
-    /* Note that we fill one of the delay slots with the second compare.  */
-    switch (cond) {
-    case TCG_COND_EQ:
-        cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
-        tcg_out_branch_i32(s, cc, label_next);
-        tcg_out_cmp(s, al, bl, blconst);
-        cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_EQ], 0);
-        tcg_out_branch_i32(s, cc, label_dest);
-        break;
-
-    case TCG_COND_NE:
-        cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
-        tcg_out_branch_i32(s, cc, label_dest);
-        tcg_out_cmp(s, al, bl, blconst);
-        tcg_out_branch_i32(s, cc, label_dest);
-        break;
-
-    default:
-        /* ??? One could fairly easily special-case 64-bit unsigned
-           compares against 32-bit zero-extended constants.  For instance,
-           we know that (unsigned)AH < 0 is false and need not emit it.
-           Similarly, (unsigned)AH > 0 being true implies AH != 0, so the
-           second branch will never be taken.  */
-        cc = INSN_COND(tcg_cond_to_bcond[cond], 0);
-        tcg_out_branch_i32(s, cc, label_dest);
-        tcg_out_nop(s);
-        cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
-        tcg_out_branch_i32(s, cc, label_next);
-        tcg_out_cmp(s, al, bl, blconst);
-        cc = INSN_COND(tcg_cond_to_bcond[tcg_unsigned_cond(cond)], 0);
-        tcg_out_branch_i32(s, cc, label_dest);
-        break;
-    }
-    tcg_out_nop(s);
-
-    tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr);
-}
-#endif
-
-static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
-                                TCGArg c1, TCGArg c2, int c2const)
-{
-    TCGArg t;
-
-    /* For 32-bit comparisons, we can play games with ADDX/SUBX.  */
-    switch (cond) {
-    case TCG_COND_EQ:
-    case TCG_COND_NE:
-        if (c2 != 0) {
-            tcg_out_arithc(s, ret, c1, c2, c2const, ARITH_XOR);
-        }
-        c1 = TCG_REG_G0, c2 = ret, c2const = 0;
-        cond = (cond == TCG_COND_EQ ? TCG_COND_LEU : TCG_COND_LTU);
-	break;
-
-    case TCG_COND_GTU:
-    case TCG_COND_GEU:
-        if (c2const && c2 != 0) {
-            tcg_out_movi_imm13(s, TCG_REG_I5, c2);
-            c2 = TCG_REG_I5;
-        }
-        t = c1, c1 = c2, c2 = t, c2const = 0;
-        cond = tcg_swap_cond(cond);
-        break;
-
-    case TCG_COND_LTU:
-    case TCG_COND_LEU:
-        break;
-
-    default:
-        tcg_out_cmp(s, c1, c2, c2const);
-#if defined(__sparc_v9__) || defined(__sparc_v8plus__)
-        tcg_out_movi_imm13(s, ret, 0);
-        tcg_out32 (s, ARITH_MOVCC | INSN_RD(ret)
-                   | INSN_RS1(tcg_cond_to_bcond[cond])
-                   | MOVCC_ICC | INSN_IMM11(1));
-#else
-        t = gen_new_label();
-        tcg_out_branch_i32(s, INSN_COND(tcg_cond_to_bcond[cond], 1), t);
-        tcg_out_movi_imm13(s, ret, 1);
-        tcg_out_movi_imm13(s, ret, 0);
-        tcg_out_label(s, t, (tcg_target_long)s->code_ptr);
-#endif
-        return;
-    }
-
-    tcg_out_cmp(s, c1, c2, c2const);
-    if (cond == TCG_COND_LTU) {
-        tcg_out_arithi(s, ret, TCG_REG_G0, 0, ARITH_ADDX);
-    } else {
-        tcg_out_arithi(s, ret, TCG_REG_G0, -1, ARITH_SUBX);
-    }
-}
-
-#if TCG_TARGET_REG_BITS == 64
-static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGArg ret,
-                                TCGArg c1, TCGArg c2, int c2const)
-{
-    tcg_out_cmp(s, c1, c2, c2const);
-    tcg_out_movi_imm13(s, ret, 0);
-    tcg_out32 (s, ARITH_MOVCC | INSN_RD(ret)
-               | INSN_RS1(tcg_cond_to_bcond[cond])
-               | MOVCC_XCC | INSN_IMM11(1));
-}
-#else
-static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
-                                 TCGArg al, TCGArg ah,
-                                 TCGArg bl, int blconst,
-                                 TCGArg bh, int bhconst)
-{
-    int lab;
-
-    switch (cond) {
-    case TCG_COND_EQ:
-        tcg_out_setcond_i32(s, TCG_COND_EQ, TCG_REG_I5, al, bl, blconst);
-        tcg_out_setcond_i32(s, TCG_COND_EQ, ret, ah, bh, bhconst);
-        tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_AND);
-        break;
-
-    case TCG_COND_NE:
-        tcg_out_setcond_i32(s, TCG_COND_NE, TCG_REG_I5, al, al, blconst);
-        tcg_out_setcond_i32(s, TCG_COND_NE, ret, ah, bh, bhconst);
-        tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_OR);
-        break;
-
-    default:
-        lab = gen_new_label();
-
-        tcg_out_cmp(s, ah, bh, bhconst);
-        tcg_out_branch_i32(s, INSN_COND(tcg_cond_to_bcond[cond], 1), lab);
-        tcg_out_movi_imm13(s, ret, 1);
-        tcg_out_branch_i32(s, INSN_COND(COND_NE, 1), lab);
-        tcg_out_movi_imm13(s, ret, 0);
-
-        tcg_out_setcond_i32(s, tcg_unsigned_cond(cond), ret, al, bl, blconst);
-
-        tcg_out_label(s, lab, (tcg_target_long)s->code_ptr);
-        break;
-    }
-}
-#endif
-
-/* Generate global QEMU prologue and epilogue code */
-static void tcg_target_qemu_prologue(TCGContext *s)
-{
-    tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
-              INSN_IMM13(-TCG_TARGET_STACK_MINFRAME));
-    tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I0) |
-              INSN_RS2(TCG_REG_G0));
-    tcg_out_nop(s);
-}
-
-#if defined(CONFIG_SOFTMMU)
-
-#include "../../softmmu_defs.h"
-
-static const void * const qemu_ld_helpers[4] = {
-    __ldb_mmu,
-    __ldw_mmu,
-    __ldl_mmu,
-    __ldq_mmu,
-};
-
-static const void * const qemu_st_helpers[4] = {
-    __stb_mmu,
-    __stw_mmu,
-    __stl_mmu,
-    __stq_mmu,
-};
-#endif
-
-#if TARGET_LONG_BITS == 32
-#define TARGET_LD_OP LDUW
-#else
-#define TARGET_LD_OP LDX
-#endif
-
-#if defined(CONFIG_SOFTMMU)
-#if HOST_LONG_BITS == 32
-#define TARGET_ADDEND_LD_OP LDUW
-#else
-#define TARGET_ADDEND_LD_OP LDX
-#endif
-#endif
-
-#ifdef __arch64__
-#define HOST_LD_OP LDX
-#define HOST_ST_OP STX
-#define HOST_SLL_OP SHIFT_SLLX
-#define HOST_SRA_OP SHIFT_SRAX
-#else
-#define HOST_LD_OP LDUW
-#define HOST_ST_OP STW
-#define HOST_SLL_OP SHIFT_SLL
-#define HOST_SRA_OP SHIFT_SRA
-#endif
-
-static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
-                            int opc)
-{
-    int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
-#if defined(CONFIG_SOFTMMU)
-    uint32_t *label1_ptr, *label2_ptr;
-#endif
-
-    data_reg = *args++;
-    addr_reg = *args++;
-    mem_index = *args;
-    s_bits = opc & 3;
-
-    arg0 = TCG_REG_O0;
-    arg1 = TCG_REG_O1;
-    arg2 = TCG_REG_O2;
-
-#if defined(CONFIG_SOFTMMU)
-    /* srl addr_reg, x, arg1 */
-    tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
-                   SHIFT_SRL);
-    /* and addr_reg, x, arg0 */
-    tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
-                   ARITH_AND);
-
-    /* and arg1, x, arg1 */
-    tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
-    /* add arg1, x, arg1 */
-    tcg_out_addi(s, arg1, offsetof(CPUState,
-                                   tlb_table[mem_index][0].addr_read));
-
-    /* add env, arg1, arg1 */
-    tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
-
-    /* ld [arg1], arg2 */
-    tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
-              INSN_RS2(TCG_REG_G0));
-
-    /* subcc arg0, arg2, %g0 */
-    tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
-
-    /* will become:
-       be label1
-        or
-       be,pt %xcc label1 */
-    label1_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, 0);
-
-    /* mov (delay slot) */
-    tcg_out_mov(s, TCG_TYPE_PTR, arg0, addr_reg);
-
-    /* mov */
-    tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
-
-    /* XXX: move that code at the end of the TB */
-    /* qemu_ld_helper[s_bits](arg0, arg1) */
-    tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
-                           - (tcg_target_ulong)s->code_ptr) >> 2)
-                         & 0x3fffffff));
-    /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
-       global registers */
-    // delay slot
-    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
-                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
-                 sizeof(long), HOST_ST_OP);
-    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
-                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
-                 sizeof(long), HOST_LD_OP);
-
-    /* data_reg = sign_extend(arg0) */
-    switch(opc) {
-    case 0 | 4:
-        /* sll arg0, 24/56, data_reg */
-        tcg_out_arithi(s, data_reg, arg0, (int)sizeof(tcg_target_long) * 8 - 8,
-                       HOST_SLL_OP);
-        /* sra data_reg, 24/56, data_reg */
-        tcg_out_arithi(s, data_reg, data_reg,
-                       (int)sizeof(tcg_target_long) * 8 - 8, HOST_SRA_OP);
-        break;
-    case 1 | 4:
-        /* sll arg0, 16/48, data_reg */
-        tcg_out_arithi(s, data_reg, arg0,
-                       (int)sizeof(tcg_target_long) * 8 - 16, HOST_SLL_OP);
-        /* sra data_reg, 16/48, data_reg */
-        tcg_out_arithi(s, data_reg, data_reg,
-                       (int)sizeof(tcg_target_long) * 8 - 16, HOST_SRA_OP);
-        break;
-    case 2 | 4:
-        /* sll arg0, 32, data_reg */
-        tcg_out_arithi(s, data_reg, arg0, 32, HOST_SLL_OP);
-        /* sra data_reg, 32, data_reg */
-        tcg_out_arithi(s, data_reg, data_reg, 32, HOST_SRA_OP);
-        break;
-    case 0:
-    case 1:
-    case 2:
-    case 3:
-    default:
-        /* mov */
-        tcg_out_mov(s, TCG_TYPE_REG, data_reg, arg0);
-        break;
-    }
-
-    /* will become:
-       ba label2 */
-    label2_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, 0);
-
-    /* nop (delay slot */
-    tcg_out_nop(s);
-
-    /* label1: */
-#if TARGET_LONG_BITS == 32
-    /* be label1 */
-    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
-                   INSN_OFF22((unsigned long)s->code_ptr -
-                              (unsigned long)label1_ptr));
-#else
-    /* be,pt %xcc label1 */
-    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
-                   (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
-                              (unsigned long)label1_ptr));
-#endif
-
-    /* ld [arg1 + x], arg1 */
-    tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
-                 offsetof(CPUTLBEntry, addr_read), TARGET_ADDEND_LD_OP);
-
-#if TARGET_LONG_BITS == 32
-    /* and addr_reg, x, arg0 */
-    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
-    tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
-    /* add arg0, arg1, arg0 */
-    tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
-#else
-    /* add addr_reg, arg1, arg0 */
-    tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
-#endif
-
-#else
-    arg0 = addr_reg;
-#endif
-
-    switch(opc) {
-    case 0:
-        /* ldub [arg0], data_reg */
-        tcg_out_ldst(s, data_reg, arg0, 0, LDUB);
-        break;
-    case 0 | 4:
-        /* ldsb [arg0], data_reg */
-        tcg_out_ldst(s, data_reg, arg0, 0, LDSB);
-        break;
-    case 1:
-#ifdef TARGET_WORDS_BIGENDIAN
-        /* lduh [arg0], data_reg */
-        tcg_out_ldst(s, data_reg, arg0, 0, LDUH);
-#else
-        /* lduha [arg0] ASI_PRIMARY_LITTLE, data_reg */
-        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUHA, ASI_PRIMARY_LITTLE);
-#endif
-        break;
-    case 1 | 4:
-#ifdef TARGET_WORDS_BIGENDIAN
-        /* ldsh [arg0], data_reg */
-        tcg_out_ldst(s, data_reg, arg0, 0, LDSH);
-#else
-        /* ldsha [arg0] ASI_PRIMARY_LITTLE, data_reg */
-        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSHA, ASI_PRIMARY_LITTLE);
-#endif
-        break;
-    case 2:
-#ifdef TARGET_WORDS_BIGENDIAN
-        /* lduw [arg0], data_reg */
-        tcg_out_ldst(s, data_reg, arg0, 0, LDUW);
-#else
-        /* lduwa [arg0] ASI_PRIMARY_LITTLE, data_reg */
-        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUWA, ASI_PRIMARY_LITTLE);
-#endif
-        break;
-    case 2 | 4:
-#ifdef TARGET_WORDS_BIGENDIAN
-        /* ldsw [arg0], data_reg */
-        tcg_out_ldst(s, data_reg, arg0, 0, LDSW);
-#else
-        /* ldswa [arg0] ASI_PRIMARY_LITTLE, data_reg */
-        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSWA, ASI_PRIMARY_LITTLE);
-#endif
-        break;
-    case 3:
-#ifdef TARGET_WORDS_BIGENDIAN
-        /* ldx [arg0], data_reg */
-        tcg_out_ldst(s, data_reg, arg0, 0, LDX);
-#else
-        /* ldxa [arg0] ASI_PRIMARY_LITTLE, data_reg */
-        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDXA, ASI_PRIMARY_LITTLE);
-#endif
-        break;
-    default:
-        tcg_abort();
-    }
-
-#if defined(CONFIG_SOFTMMU)
-    /* label2: */
-    *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
-                   INSN_OFF22((unsigned long)s->code_ptr -
-                              (unsigned long)label2_ptr));
-#endif
-}
-
-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
-                            int opc)
-{
-    int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
-#if defined(CONFIG_SOFTMMU)
-    uint32_t *label1_ptr, *label2_ptr;
-#endif
-
-    data_reg = *args++;
-    addr_reg = *args++;
-    mem_index = *args;
-
-    s_bits = opc;
-
-    arg0 = TCG_REG_O0;
-    arg1 = TCG_REG_O1;
-    arg2 = TCG_REG_O2;
-
-#if defined(CONFIG_SOFTMMU)
-    /* srl addr_reg, x, arg1 */
-    tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
-                   SHIFT_SRL);
-
-    /* and addr_reg, x, arg0 */
-    tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
-                   ARITH_AND);
-
-    /* and arg1, x, arg1 */
-    tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
-    /* add arg1, x, arg1 */
-    tcg_out_addi(s, arg1, offsetof(CPUState,
-                                   tlb_table[mem_index][0].addr_write));
-
-    /* add env, arg1, arg1 */
-    tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
-
-    /* ld [arg1], arg2 */
-    tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
-              INSN_RS2(TCG_REG_G0));
-
-    /* subcc arg0, arg2, %g0 */
-    tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
-
-    /* will become:
-       be label1
-        or
-       be,pt %xcc label1 */
-    label1_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, 0);
-
-    /* mov (delay slot) */
-    tcg_out_mov(s, TCG_TYPE_PTR, arg0, addr_reg);
-
-    /* mov */
-    tcg_out_mov(s, TCG_TYPE_REG, arg1, data_reg);
-
-    /* mov */
-    tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
-
-    /* XXX: move that code at the end of the TB */
-    /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
-    tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits]
-                           - (tcg_target_ulong)s->code_ptr) >> 2)
-                         & 0x3fffffff));
-    /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
-       global registers */
-    // delay slot
-    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
-                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
-                 sizeof(long), HOST_ST_OP);
-    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
-                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
-                 sizeof(long), HOST_LD_OP);
-
-    /* will become:
-       ba label2 */
-    label2_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, 0);
-
-    /* nop (delay slot) */
-    tcg_out_nop(s);
-
-#if TARGET_LONG_BITS == 32
-    /* be label1 */
-    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
-                   INSN_OFF22((unsigned long)s->code_ptr -
-                              (unsigned long)label1_ptr));
-#else
-    /* be,pt %xcc label1 */
-    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
-                   (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
-                              (unsigned long)label1_ptr));
-#endif
-
-    /* ld [arg1 + x], arg1 */
-    tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
-                 offsetof(CPUTLBEntry, addr_write), TARGET_ADDEND_LD_OP);
-
-#if TARGET_LONG_BITS == 32
-    /* and addr_reg, x, arg0 */
-    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
-    tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
-    /* add arg0, arg1, arg0 */
-    tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
-#else
-    /* add addr_reg, arg1, arg0 */
-    tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
-#endif
-
-#else
-    arg0 = addr_reg;
-#endif
-
-    switch(opc) {
-    case 0:
-        /* stb data_reg, [arg0] */
-        tcg_out_ldst(s, data_reg, arg0, 0, STB);
-        break;
-    case 1:
-#ifdef TARGET_WORDS_BIGENDIAN
-        /* sth data_reg, [arg0] */
-        tcg_out_ldst(s, data_reg, arg0, 0, STH);
-#else
-        /* stha data_reg, [arg0] ASI_PRIMARY_LITTLE */
-        tcg_out_ldst_asi(s, data_reg, arg0, 0, STHA, ASI_PRIMARY_LITTLE);
-#endif
-        break;
-    case 2:
-#ifdef TARGET_WORDS_BIGENDIAN
-        /* stw data_reg, [arg0] */
-        tcg_out_ldst(s, data_reg, arg0, 0, STW);
-#else
-        /* stwa data_reg, [arg0] ASI_PRIMARY_LITTLE */
-        tcg_out_ldst_asi(s, data_reg, arg0, 0, STWA, ASI_PRIMARY_LITTLE);
-#endif
-        break;
-    case 3:
-#ifdef TARGET_WORDS_BIGENDIAN
-        /* stx data_reg, [arg0] */
-        tcg_out_ldst(s, data_reg, arg0, 0, STX);
-#else
-        /* stxa data_reg, [arg0] ASI_PRIMARY_LITTLE */
-        tcg_out_ldst_asi(s, data_reg, arg0, 0, STXA, ASI_PRIMARY_LITTLE);
-#endif
-        break;
-    default:
-        tcg_abort();
-    }
-
-#if defined(CONFIG_SOFTMMU)
-    /* label2: */
-    *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
-                   INSN_OFF22((unsigned long)s->code_ptr -
-                              (unsigned long)label2_ptr));
-#endif
-}
-
-static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
-                              const int *const_args)
-{
-    int c;
-
-    switch (opc) {
-    case INDEX_op_exit_tb:
-        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);
-        tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I7) |
-                  INSN_IMM13(8));
-        tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) |
-                      INSN_RS2(TCG_REG_G0));
-        break;
-    case INDEX_op_goto_tb:
-        if (s->tb_jmp_offset) {
-            /* direct jump method */
-            tcg_out_sethi(s, TCG_REG_I5, args[0] & 0xffffe000);
-            tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
-                      INSN_IMM13((args[0] & 0x1fff)));
-            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
-        } else {
-            /* indirect jump method */
-            tcg_out_ld_ptr(s, TCG_REG_I5, (tcg_target_long)(s->tb_next + args[0]));
-            tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
-                      INSN_RS2(TCG_REG_G0));
-        }
-        tcg_out_nop(s);
-        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
-        break;
-    case INDEX_op_call:
-        if (const_args[0])
-            tcg_out32(s, CALL | ((((tcg_target_ulong)args[0]
-                                   - (tcg_target_ulong)s->code_ptr) >> 2)
-                                 & 0x3fffffff));
-        else {
-            tcg_out_ld_ptr(s, TCG_REG_I5,
-                           (tcg_target_long)(s->tb_next + args[0]));
-            tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_I5) |
-                      INSN_RS2(TCG_REG_G0));
-        }
-        /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
-           global registers */
-        // delay slot
-        tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
-                     TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
-                     sizeof(long), HOST_ST_OP);
-        tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
-                     TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
-                     sizeof(long), HOST_LD_OP);
-        break;
-    case INDEX_op_jmp:
-    case INDEX_op_br:
-        tcg_out_branch_i32(s, COND_A, args[0]);
-        tcg_out_nop(s);
-        break;
-    case INDEX_op_movi_i32:
-        tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
-        break;
-
-#if TCG_TARGET_REG_BITS == 64
-#define OP_32_64(x)                             \
-        glue(glue(case INDEX_op_, x), _i32):    \
-        glue(glue(case INDEX_op_, x), _i64)
-#else
-#define OP_32_64(x)                             \
-        glue(glue(case INDEX_op_, x), _i32)
-#endif
-    OP_32_64(ld8u):
-        tcg_out_ldst(s, args[0], args[1], args[2], LDUB);
-        break;
-    OP_32_64(ld8s):
-        tcg_out_ldst(s, args[0], args[1], args[2], LDSB);
-        break;
-    OP_32_64(ld16u):
-        tcg_out_ldst(s, args[0], args[1], args[2], LDUH);
-        break;
-    OP_32_64(ld16s):
-        tcg_out_ldst(s, args[0], args[1], args[2], LDSH);
-        break;
-    case INDEX_op_ld_i32:
-#if TCG_TARGET_REG_BITS == 64
-    case INDEX_op_ld32u_i64:
-#endif
-        tcg_out_ldst(s, args[0], args[1], args[2], LDUW);
-        break;
-    OP_32_64(st8):
-        tcg_out_ldst(s, args[0], args[1], args[2], STB);
-        break;
-    OP_32_64(st16):
-        tcg_out_ldst(s, args[0], args[1], args[2], STH);
-        break;
-    case INDEX_op_st_i32:
-#if TCG_TARGET_REG_BITS == 64
-    case INDEX_op_st32_i64:
-#endif
-        tcg_out_ldst(s, args[0], args[1], args[2], STW);
-        break;
-    OP_32_64(add):
-        c = ARITH_ADD;
-        goto gen_arith;
-    OP_32_64(sub):
-        c = ARITH_SUB;
-        goto gen_arith;
-    OP_32_64(and):
-        c = ARITH_AND;
-        goto gen_arith;
-    OP_32_64(andc):
-        c = ARITH_ANDN;
-        goto gen_arith;
-    OP_32_64(or):
-        c = ARITH_OR;
-        goto gen_arith;
-    OP_32_64(orc):
-        c = ARITH_ORN;
-        goto gen_arith;
-    OP_32_64(xor):
-        c = ARITH_XOR;
-        goto gen_arith;
-    case INDEX_op_shl_i32:
-        c = SHIFT_SLL;
-        goto gen_arith;
-    case INDEX_op_shr_i32:
-        c = SHIFT_SRL;
-        goto gen_arith;
-    case INDEX_op_sar_i32:
-        c = SHIFT_SRA;
-        goto gen_arith;
-    case INDEX_op_mul_i32:
-        c = ARITH_UMUL;
-        goto gen_arith;
-
-    OP_32_64(neg):
-	c = ARITH_SUB;
-	goto gen_arith1;
-    OP_32_64(not):
-	c = ARITH_ORN;
-	goto gen_arith1;
-
-    case INDEX_op_div_i32:
-        tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 0);
-        break;
-    case INDEX_op_divu_i32:
-        tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 1);
-        break;
-
-    case INDEX_op_rem_i32:
-    case INDEX_op_remu_i32:
-        tcg_out_div32(s, TCG_REG_I5, args[1], args[2], const_args[2],
-                      opc == INDEX_op_remu_i32);
-        tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
-                       ARITH_UMUL);
-        tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
-        break;
-
-    case INDEX_op_brcond_i32:
-        tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1],
-                           args[3]);
-        break;
-    case INDEX_op_setcond_i32:
-        tcg_out_setcond_i32(s, args[3], args[0], args[1],
-                            args[2], const_args[2]);
-        break;
-
-#if TCG_TARGET_REG_BITS == 32
-    case INDEX_op_brcond2_i32:
-        tcg_out_brcond2_i32(s, args[4], args[0], args[1],
-                            args[2], const_args[2],
-                            args[3], const_args[3], args[5]);
-        break;
-    case INDEX_op_setcond2_i32:
-        tcg_out_setcond2_i32(s, args[5], args[0], args[1], args[2],
-                             args[3], const_args[3],
-                             args[4], const_args[4]);
-        break;
-    case INDEX_op_add2_i32:
-        tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
-                       ARITH_ADDCC);
-        tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
-                       ARITH_ADDX);
-        break;
-    case INDEX_op_sub2_i32:
-        tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
-                       ARITH_SUBCC);
-        tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
-                       ARITH_SUBX);
-        break;
-    case INDEX_op_mulu2_i32:
-        tcg_out_arithc(s, args[0], args[2], args[3], const_args[3],
-                       ARITH_UMUL);
-        tcg_out_rdy(s, args[1]);
-        break;
-#endif
-
-    case INDEX_op_qemu_ld8u:
-        tcg_out_qemu_ld(s, args, 0);
-        break;
-    case INDEX_op_qemu_ld8s:
-        tcg_out_qemu_ld(s, args, 0 | 4);
-        break;
-    case INDEX_op_qemu_ld16u:
-        tcg_out_qemu_ld(s, args, 1);
-        break;
-    case INDEX_op_qemu_ld16s:
-        tcg_out_qemu_ld(s, args, 1 | 4);
-        break;
-    case INDEX_op_qemu_ld32:
-#if TCG_TARGET_REG_BITS == 64
-    case INDEX_op_qemu_ld32u:
-#endif
-        tcg_out_qemu_ld(s, args, 2);
-        break;
-#if TCG_TARGET_REG_BITS == 64
-    case INDEX_op_qemu_ld32s:
-        tcg_out_qemu_ld(s, args, 2 | 4);
-        break;
-#endif
-    case INDEX_op_qemu_st8:
-        tcg_out_qemu_st(s, args, 0);
-        break;
-    case INDEX_op_qemu_st16:
-        tcg_out_qemu_st(s, args, 1);
-        break;
-    case INDEX_op_qemu_st32:
-        tcg_out_qemu_st(s, args, 2);
-        break;
-
-#if TCG_TARGET_REG_BITS == 64
-    case INDEX_op_movi_i64:
-        tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
-        break;
-    case INDEX_op_ld32s_i64:
-        tcg_out_ldst(s, args[0], args[1], args[2], LDSW);
-        break;
-    case INDEX_op_ld_i64:
-        tcg_out_ldst(s, args[0], args[1], args[2], LDX);
-        break;
-    case INDEX_op_st_i64:
-        tcg_out_ldst(s, args[0], args[1], args[2], STX);
-        break;
-    case INDEX_op_shl_i64:
-        c = SHIFT_SLLX;
-        goto gen_arith;
-    case INDEX_op_shr_i64:
-        c = SHIFT_SRLX;
-        goto gen_arith;
-    case INDEX_op_sar_i64:
-        c = SHIFT_SRAX;
-        goto gen_arith;
-    case INDEX_op_mul_i64:
-        c = ARITH_MULX;
-        goto gen_arith;
-    case INDEX_op_div_i64:
-        c = ARITH_SDIVX;
-        goto gen_arith;
-    case INDEX_op_divu_i64:
-        c = ARITH_UDIVX;
-        goto gen_arith;
-    case INDEX_op_rem_i64:
-    case INDEX_op_remu_i64:
-        tcg_out_arithc(s, TCG_REG_I5, args[1], args[2], const_args[2],
-                       opc == INDEX_op_rem_i64 ? ARITH_SDIVX : ARITH_UDIVX);
-        tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
-                       ARITH_MULX);
-        tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
-        break;
-    case INDEX_op_ext32s_i64:
-        if (const_args[1]) {
-            tcg_out_movi(s, TCG_TYPE_I64, args[0], (int32_t)args[1]);
-        } else {
-            tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRA);
-        }
-        break;
-    case INDEX_op_ext32u_i64:
-        if (const_args[1]) {
-            tcg_out_movi_imm32(s, args[0], args[1]);
-        } else {
-            tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRL);
-        }
-        break;
-
-    case INDEX_op_brcond_i64:
-        tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
-                           args[3]);
-        break;
-    case INDEX_op_setcond_i64:
-        tcg_out_setcond_i64(s, args[3], args[0], args[1],
-                            args[2], const_args[2]);
-        break;
-
-    case INDEX_op_qemu_ld64:
-        tcg_out_qemu_ld(s, args, 3);
-        break;
-    case INDEX_op_qemu_st64:
-        tcg_out_qemu_st(s, args, 3);
-        break;
-
-#endif
-    gen_arith:
-        tcg_out_arithc(s, args[0], args[1], args[2], const_args[2], c);
-        break;
-
-    gen_arith1:
-	tcg_out_arithc(s, args[0], TCG_REG_G0, args[1], const_args[1], c);
-	break;
-
-    default:
-        fprintf(stderr, "unknown opcode 0x%x\n", opc);
-        tcg_abort();
-    }
-}
-
-static const TCGTargetOpDef sparc_op_defs[] = {
-    { INDEX_op_exit_tb, { } },
-    { INDEX_op_goto_tb, { } },
-    { INDEX_op_call, { "ri" } },
-    { INDEX_op_jmp, { "ri" } },
-    { INDEX_op_br, { } },
-
-    { INDEX_op_mov_i32, { "r", "r" } },
-    { INDEX_op_movi_i32, { "r" } },
-    { INDEX_op_ld8u_i32, { "r", "r" } },
-    { INDEX_op_ld8s_i32, { "r", "r" } },
-    { INDEX_op_ld16u_i32, { "r", "r" } },
-    { INDEX_op_ld16s_i32, { "r", "r" } },
-    { INDEX_op_ld_i32, { "r", "r" } },
-    { INDEX_op_st8_i32, { "r", "r" } },
-    { INDEX_op_st16_i32, { "r", "r" } },
-    { INDEX_op_st_i32, { "r", "r" } },
-
-    { INDEX_op_add_i32, { "r", "r", "rJ" } },
-    { INDEX_op_mul_i32, { "r", "r", "rJ" } },
-    { INDEX_op_div_i32, { "r", "r", "rJ" } },
-    { INDEX_op_divu_i32, { "r", "r", "rJ" } },
-    { INDEX_op_rem_i32, { "r", "r", "rJ" } },
-    { INDEX_op_remu_i32, { "r", "r", "rJ" } },
-    { INDEX_op_sub_i32, { "r", "r", "rJ" } },
-    { INDEX_op_and_i32, { "r", "r", "rJ" } },
-    { INDEX_op_andc_i32, { "r", "r", "rJ" } },
-    { INDEX_op_or_i32, { "r", "r", "rJ" } },
-    { INDEX_op_orc_i32, { "r", "r", "rJ" } },
-    { INDEX_op_xor_i32, { "r", "r", "rJ" } },
-
-    { INDEX_op_shl_i32, { "r", "r", "rJ" } },
-    { INDEX_op_shr_i32, { "r", "r", "rJ" } },
-    { INDEX_op_sar_i32, { "r", "r", "rJ" } },
-
-    { INDEX_op_neg_i32, { "r", "rJ" } },
-    { INDEX_op_not_i32, { "r", "rJ" } },
-
-    { INDEX_op_brcond_i32, { "r", "rJ" } },
-    { INDEX_op_setcond_i32, { "r", "r", "rJ" } },
-
-#if TCG_TARGET_REG_BITS == 32
-    { INDEX_op_brcond2_i32, { "r", "r", "rJ", "rJ" } },
-    { INDEX_op_setcond2_i32, { "r", "r", "r", "rJ", "rJ" } },
-    { INDEX_op_add2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
-    { INDEX_op_sub2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
-    { INDEX_op_mulu2_i32, { "r", "r", "r", "rJ" } },
-#endif
-
-    { INDEX_op_qemu_ld8u, { "r", "L" } },
-    { INDEX_op_qemu_ld8s, { "r", "L" } },
-    { INDEX_op_qemu_ld16u, { "r", "L" } },
-    { INDEX_op_qemu_ld16s, { "r", "L" } },
-    { INDEX_op_qemu_ld32, { "r", "L" } },
-#if TCG_TARGET_REG_BITS == 64
-    { INDEX_op_qemu_ld32u, { "r", "L" } },
-    { INDEX_op_qemu_ld32s, { "r", "L" } },
-#endif
-
-    { INDEX_op_qemu_st8, { "L", "L" } },
-    { INDEX_op_qemu_st16, { "L", "L" } },
-    { INDEX_op_qemu_st32, { "L", "L" } },
-
-#if TCG_TARGET_REG_BITS == 64
-    { INDEX_op_mov_i64, { "r", "r" } },
-    { INDEX_op_movi_i64, { "r" } },
-    { INDEX_op_ld8u_i64, { "r", "r" } },
-    { INDEX_op_ld8s_i64, { "r", "r" } },
-    { INDEX_op_ld16u_i64, { "r", "r" } },
-    { 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_st8_i64, { "r", "r" } },
-    { INDEX_op_st16_i64, { "r", "r" } },
-    { INDEX_op_st32_i64, { "r", "r" } },
-    { INDEX_op_st_i64, { "r", "r" } },
-    { INDEX_op_qemu_ld64, { "L", "L" } },
-    { INDEX_op_qemu_st64, { "L", "L" } },
-
-    { INDEX_op_add_i64, { "r", "r", "rJ" } },
-    { INDEX_op_mul_i64, { "r", "r", "rJ" } },
-    { INDEX_op_div_i64, { "r", "r", "rJ" } },
-    { INDEX_op_divu_i64, { "r", "r", "rJ" } },
-    { INDEX_op_rem_i64, { "r", "r", "rJ" } },
-    { INDEX_op_remu_i64, { "r", "r", "rJ" } },
-    { INDEX_op_sub_i64, { "r", "r", "rJ" } },
-    { INDEX_op_and_i64, { "r", "r", "rJ" } },
-    { INDEX_op_andc_i64, { "r", "r", "rJ" } },
-    { INDEX_op_or_i64, { "r", "r", "rJ" } },
-    { INDEX_op_orc_i64, { "r", "r", "rJ" } },
-    { INDEX_op_xor_i64, { "r", "r", "rJ" } },
-
-    { INDEX_op_shl_i64, { "r", "r", "rJ" } },
-    { INDEX_op_shr_i64, { "r", "r", "rJ" } },
-    { INDEX_op_sar_i64, { "r", "r", "rJ" } },
-
-    { INDEX_op_neg_i64, { "r", "rJ" } },
-    { INDEX_op_not_i64, { "r", "rJ" } },
-
-    { INDEX_op_ext32s_i64, { "r", "ri" } },
-    { INDEX_op_ext32u_i64, { "r", "ri" } },
-
-    { INDEX_op_brcond_i64, { "r", "rJ" } },
-    { INDEX_op_setcond_i64, { "r", "r", "rJ" } },
-#endif
-    { -1 },
-};
-
-static void tcg_target_init(TCGContext *s)
-{
-    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
-#if TCG_TARGET_REG_BITS == 64
-    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
-#endif
-    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
-                     (1 << TCG_REG_G1) |
-                     (1 << TCG_REG_G2) |
-                     (1 << TCG_REG_G3) |
-                     (1 << TCG_REG_G4) |
-                     (1 << TCG_REG_G5) |
-                     (1 << TCG_REG_G6) |
-                     (1 << TCG_REG_G7) |
-                     (1 << TCG_REG_O0) |
-                     (1 << TCG_REG_O1) |
-                     (1 << TCG_REG_O2) |
-                     (1 << TCG_REG_O3) |
-                     (1 << TCG_REG_O4) |
-                     (1 << TCG_REG_O5) |
-                     (1 << TCG_REG_O7));
-
-    tcg_regset_clear(s->reserved_regs);
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0);
-#if TCG_TARGET_REG_BITS == 64
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I4); // for internal use
-#endif
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I5); // for internal use
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6);
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7);
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6);
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
-    tcg_add_target_add_op_defs(sparc_op_defs);
-}
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
deleted file mode 100644
index df0785e..0000000
--- a/tcg/sparc/tcg-target.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define TCG_TARGET_SPARC 1
-
-#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
-#define TCG_TARGET_REG_BITS 64
-#else
-#define TCG_TARGET_REG_BITS 32
-#endif
-
-#define TCG_TARGET_WORDS_BIGENDIAN
-
-#define TCG_TARGET_NB_REGS 32
-
-enum {
-    TCG_REG_G0 = 0,
-    TCG_REG_G1,
-    TCG_REG_G2,
-    TCG_REG_G3,
-    TCG_REG_G4,
-    TCG_REG_G5,
-    TCG_REG_G6,
-    TCG_REG_G7,
-    TCG_REG_O0,
-    TCG_REG_O1,
-    TCG_REG_O2,
-    TCG_REG_O3,
-    TCG_REG_O4,
-    TCG_REG_O5,
-    TCG_REG_O6,
-    TCG_REG_O7,
-    TCG_REG_L0,
-    TCG_REG_L1,
-    TCG_REG_L2,
-    TCG_REG_L3,
-    TCG_REG_L4,
-    TCG_REG_L5,
-    TCG_REG_L6,
-    TCG_REG_L7,
-    TCG_REG_I0,
-    TCG_REG_I1,
-    TCG_REG_I2,
-    TCG_REG_I3,
-    TCG_REG_I4,
-    TCG_REG_I5,
-    TCG_REG_I6,
-    TCG_REG_I7,
-};
-
-#define TCG_CT_CONST_S11 0x100
-#define TCG_CT_CONST_S13 0x200
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK TCG_REG_I6
-#ifdef __arch64__
-// Reserve space for AREG0
-#define TCG_TARGET_STACK_MINFRAME (176 + 4 * (int)sizeof(long) + \
-                                   TCG_STATIC_CALL_ARGS_SIZE)
-#define TCG_TARGET_CALL_STACK_OFFSET (2047 - 16)
-#define TCG_TARGET_STACK_ALIGN 16
-#else
-// AREG0 + one word for alignment
-#define TCG_TARGET_STACK_MINFRAME (92 + (2 + 1) * (int)sizeof(long) + \
-                                   TCG_STATIC_CALL_ARGS_SIZE)
-#define TCG_TARGET_CALL_STACK_OFFSET TCG_TARGET_STACK_MINFRAME
-#define TCG_TARGET_STACK_ALIGN 8
-#endif
-
-#ifdef __arch64__
-#define TCG_TARGET_EXTEND_ARGS 1
-#endif
-
-/* optional instructions */
-#define TCG_TARGET_HAS_div_i32
-// #define TCG_TARGET_HAS_rot_i32
-// #define TCG_TARGET_HAS_ext8s_i32
-// #define TCG_TARGET_HAS_ext16s_i32
-// #define TCG_TARGET_HAS_ext8u_i32
-// #define TCG_TARGET_HAS_ext16u_i32
-// #define TCG_TARGET_HAS_bswap16_i32
-// #define TCG_TARGET_HAS_bswap32_i32
-#define TCG_TARGET_HAS_neg_i32
-#define TCG_TARGET_HAS_not_i32
-#define TCG_TARGET_HAS_andc_i32
-#define TCG_TARGET_HAS_orc_i32
-// #define TCG_TARGET_HAS_eqv_i32
-// #define TCG_TARGET_HAS_nand_i32
-// #define TCG_TARGET_HAS_nor_i32
-
-#if TCG_TARGET_REG_BITS == 64
-#define TCG_TARGET_HAS_div_i64
-// #define TCG_TARGET_HAS_rot_i64
-// #define TCG_TARGET_HAS_ext8s_i64
-// #define TCG_TARGET_HAS_ext16s_i64
-#define TCG_TARGET_HAS_ext32s_i64
-// #define TCG_TARGET_HAS_ext8u_i64
-// #define TCG_TARGET_HAS_ext16u_i64
-#define TCG_TARGET_HAS_ext32u_i64
-// #define TCG_TARGET_HAS_bswap16_i64
-// #define TCG_TARGET_HAS_bswap32_i64
-// #define TCG_TARGET_HAS_bswap64_i64
-#define TCG_TARGET_HAS_neg_i64
-#define TCG_TARGET_HAS_not_i64
-#define TCG_TARGET_HAS_andc_i64
-#define TCG_TARGET_HAS_orc_i64
-// #define TCG_TARGET_HAS_eqv_i64
-// #define TCG_TARGET_HAS_nand_i64
-// #define TCG_TARGET_HAS_nor_i64
-#endif
-
-/* Note: must be synced with dyngen-exec.h */
-#ifdef CONFIG_SOLARIS
-#define TCG_AREG0 TCG_REG_G2
-#elif defined(__sparc_v9__)
-#define TCG_AREG0 TCG_REG_G5
-#else
-#define TCG_AREG0 TCG_REG_G6
-#endif
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-    unsigned long p;
-
-    p = start & ~(8UL - 1UL);
-    stop = (stop + (8UL - 1UL)) & ~(8UL - 1UL);
-
-    for (; p < stop; p += 8)
-        __asm__ __volatile__("flush\t%0" : : "r" (p));
-}
diff --git a/tcg/tcg.c b/tcg/tcg.c
index b0d4c95..3c9346d 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2042,7 +2042,7 @@
 #ifdef DEBUG_DISAS
     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
         qemu_log("OP:\n");
-        tcg_dump_ops(s, logfile);
+        tcg_dump_ops(s, qemu_logfile);
         qemu_log("\n");
     }
 #endif
@@ -2058,7 +2058,7 @@
 #ifdef DEBUG_DISAS
     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
         qemu_log("OP after liveness analysis:\n");
-        tcg_dump_ops(s, logfile);
+        tcg_dump_ops(s, qemu_logfile);
         qemu_log("\n");
     }
 #endif
diff --git a/tcg/x86_64/tcg-target.c b/tcg/x86_64/tcg-target.c
index 6e7a6a4..03ec23e 100644
--- a/tcg/x86_64/tcg-target.c
+++ b/tcg/x86_64/tcg-target.c
@@ -594,7 +594,7 @@
 
     /* lea offset(r1, env), r1 */
     tcg_out_modrm_offset2(s, 0x8d | P_REXW, r1, r1, TCG_AREG0, 0,
-                          offsetof(CPUState, tlb_table[mem_index][0].addr_read));
+                          offsetof(CPUOldState, tlb_table[mem_index][0].addr_read));
 
     /* cmp 0(r1), r0 */
     tcg_out_modrm_offset(s, 0x3b | rexw, r0, r1, 0);
@@ -789,7 +789,7 @@
 
     /* lea offset(r1, env), r1 */
     tcg_out_modrm_offset2(s, 0x8d | P_REXW, r1, r1, TCG_AREG0, 0,
-                          offsetof(CPUState, tlb_table[mem_index][0].addr_write));
+                          offsetof(CPUOldState, tlb_table[mem_index][0].addr_write));
 
     /* cmp 0(r1), r0 */
     tcg_out_modrm_offset(s, 0x3b | rexw, r0, r1, 0);
diff --git a/telephony/android_modem.c b/telephony/android_modem.c
index 52d5f9c..4b06d69 100644
--- a/telephony/android_modem.c
+++ b/telephony/android_modem.c
@@ -11,7 +11,7 @@
 */
 #include "android/android.h"
 #include "android_modem.h"
-#include "android/config.h"
+#include "android/config-file.h"
 #include "android/config/config.h"
 #include "android/snapshot.h"
 #include "android/utils/debug.h"
diff --git a/trace_common.h b/trace_common.h
deleted file mode 100644
index fcbf0b8..0000000
--- a/trace_common.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/* This file should be removed once we update the Android qtools to
- * include 'android-trace_common.h' directly.
- */
-#include "android/trace_common.h"
diff --git a/translate-all.c b/translate-all.c
index 5a44cf3..bb369c0 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -86,7 +86,7 @@
 void cpu_gen_init(void)
 {
     tcg_context_init(&tcg_ctx);
-    tcg_set_frame(&tcg_ctx, TCG_AREG0, offsetof(CPUState, temp_buf),
+    tcg_set_frame(&tcg_ctx, TCG_AREG0, offsetof(CPUOldState, temp_buf),
                   CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
 
@@ -96,7 +96,7 @@
    '*gen_code_size_ptr' contains the size of the generated code (host
    code).
 */
-int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr)
+int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr)
 {
     TCGContext *s = &tcg_ctx;
     uint8_t *gen_code_buf;
@@ -172,7 +172,7 @@
 /* The cpu state corresponding to 'searched_pc' is restored.
  */
 int cpu_restore_state(TranslationBlock *tb,
-                      CPUState *env, unsigned long searched_pc)
+                      CPUArchState *env, unsigned long searched_pc)
 {
     TCGContext *s = &tcg_ctx;
     int j;
@@ -224,3 +224,18 @@
 #endif
     return 0;
 }
+
+void tb_flush_jmp_cache(CPUArchState *env, target_ulong addr)
+{
+    unsigned int i;
+
+    /* Discard jump cache entries for any tb which might potentially
+       overlap the flushed page.  */
+    i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
+    memset (&env->tb_jmp_cache[i], 0,
+            TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
+
+    i = tb_jmp_cache_hash_page(addr);
+    memset (&env->tb_jmp_cache[i], 0,
+            TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
+}
diff --git a/ui/d3des.h b/ui/d3des.h
index ea3da44..70cb6b5 100644
--- a/ui/d3des.h
+++ b/ui/d3des.h
@@ -9,6 +9,8 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
+#ifndef D3DES_H
+#define D3DES_H 1
 
 /* d3des.h -
  *
@@ -22,25 +24,25 @@
 #define EN0	0	/* MODE == encrypt */
 #define DE1	1	/* MODE == decrypt */
 
-extern void deskey(unsigned char *, int);
+void deskey(unsigned char *, int);
 /*		      hexkey[8]     MODE
  * Sets the internal key register according to the hexadecimal
  * key contained in the 8 bytes of hexkey, according to the DES,
  * for encryption or decryption according to MODE.
  */
 
-extern void usekey(unsigned long *);
+void usekey(unsigned long *);
 /*		    cookedkey[32]
  * Loads the internal key register with the data in cookedkey.
  */
 
-extern void cpkey(unsigned long *);
+void cpkey(unsigned long *);
 /*		   cookedkey[32]
  * Copies the contents of the internal key register into the storage
  * located at &cookedkey[0].
  */
 
-extern void des(unsigned char *, unsigned char *);
+void des(unsigned char *, unsigned char *);
 /*		    from[8]	      to[8]
  * Encrypts/Decrypts (according to the key currently loaded in the
  * internal key register) one block of eight bytes at address 'from'
@@ -49,3 +51,5 @@
 
 /* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
  ********************************************************************/
+
+#endif
diff --git a/ui/input.c b/ui/input.c
index f4b9bed..a27649f 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -80,7 +80,7 @@
 
     if (is_absolute != current_is_absolute ||
         has_absolute != current_has_absolute) {
-        notifier_list_notify(&mouse_mode_notifiers);
+        notifier_list_notify(&mouse_mode_notifiers, NULL);
     }
 
     current_is_absolute = is_absolute;
@@ -312,5 +312,5 @@
 
 void qemu_remove_mouse_mode_change_notifier(Notifier *notify)
 {
-    notifier_list_remove(&mouse_mode_notifiers, notify);
+    notifier_remove(notify);
 }
diff --git a/ui/vnc-android.c b/ui/vnc-android.c
index ff54557..af7674e 100644
--- a/ui/vnc-android.c
+++ b/ui/vnc-android.c
@@ -28,7 +28,9 @@
 #include "sysemu/sysemu.h"
 #include "qemu/sockets.h"
 #include "qemu/timer.h"
+#ifdef CONFIG_VNC_TLS
 #include "qemu/acl.h"
+#endif
 
 #define VNC_REFRESH_INTERVAL (1000 / 30)
 
diff --git a/util/acl.c b/util/acl.c
deleted file mode 100644
index a462727..0000000
--- a/util/acl.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * QEMU access control list management
- *
- * Copyright (C) 2009 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-#include "qemu-common.h"
-#include "qemu/acl.h"
-
-#ifdef CONFIG_FNMATCH
-#include <fnmatch.h>
-#endif
-
-
-static unsigned int nacls = 0;
-static qemu_acl **acls = NULL;
-
-
-
-qemu_acl *qemu_acl_find(const char *aclname)
-{
-    int i;
-    for (i = 0 ; i < nacls ; i++) {
-        if (strcmp(acls[i]->aclname, aclname) == 0)
-            return acls[i];
-    }
-
-    return NULL;
-}
-
-qemu_acl *qemu_acl_init(const char *aclname)
-{
-    qemu_acl *acl;
-
-    acl = qemu_acl_find(aclname);
-    if (acl)
-        return acl;
-
-    acl = g_malloc(sizeof(*acl));
-    acl->aclname = g_strdup(aclname);
-    /* Deny by default, so there is no window of "open
-     * access" between QEMU starting, and the user setting
-     * up ACLs in the monitor */
-    acl->defaultDeny = 1;
-
-    acl->nentries = 0;
-    QTAILQ_INIT(&acl->entries);
-
-    acls = g_realloc(acls, sizeof(*acls) * (nacls +1));
-    acls[nacls] = acl;
-    nacls++;
-
-    return acl;
-}
-
-int qemu_acl_party_is_allowed(qemu_acl *acl,
-                              const char *party)
-{
-    qemu_acl_entry *entry;
-
-    QTAILQ_FOREACH(entry, &acl->entries, next) {
-#ifdef CONFIG_FNMATCH
-        if (fnmatch(entry->match, party, 0) == 0)
-            return entry->deny ? 0 : 1;
-#else
-        /* No fnmatch, so fallback to exact string matching
-         * instead of allowing wildcards */
-        if (strcmp(entry->match, party) == 0)
-            return entry->deny ? 0 : 1;
-#endif
-    }
-
-    return acl->defaultDeny ? 0 : 1;
-}
-
-
-void qemu_acl_reset(qemu_acl *acl)
-{
-    qemu_acl_entry *entry;
-
-    /* Put back to deny by default, so there is no window
-     * of "open access" while the user re-initializes the
-     * access control list */
-    acl->defaultDeny = 1;
-    QTAILQ_FOREACH(entry, &acl->entries, next) {
-        QTAILQ_REMOVE(&acl->entries, entry, next);
-        free(entry->match);
-        free(entry);
-    }
-    acl->nentries = 0;
-}
-
-
-int qemu_acl_append(qemu_acl *acl,
-                    int deny,
-                    const char *match)
-{
-    qemu_acl_entry *entry;
-
-    entry = g_malloc(sizeof(*entry));
-    entry->match = g_strdup(match);
-    entry->deny = deny;
-
-    QTAILQ_INSERT_TAIL(&acl->entries, entry, next);
-    acl->nentries++;
-
-    return acl->nentries;
-}
-
-
-int qemu_acl_insert(qemu_acl *acl,
-                    int deny,
-                    const char *match,
-                    int index)
-{
-    qemu_acl_entry *entry;
-    qemu_acl_entry *tmp;
-    int i = 0;
-
-    if (index <= 0)
-        return -1;
-    if (index >= acl->nentries)
-        return qemu_acl_append(acl, deny, match);
-
-
-    entry = g_malloc(sizeof(*entry));
-    entry->match = g_strdup(match);
-    entry->deny = deny;
-
-    QTAILQ_FOREACH(tmp, &acl->entries, next) {
-        i++;
-        if (i == index) {
-            QTAILQ_INSERT_BEFORE(tmp, entry, next);
-            acl->nentries++;
-            break;
-        }
-    }
-
-    return i;
-}
-
-int qemu_acl_remove(qemu_acl *acl,
-                    const char *match)
-{
-    qemu_acl_entry *entry;
-    int i = 0;
-
-    QTAILQ_FOREACH(entry, &acl->entries, next) {
-        i++;
-        if (strcmp(entry->match, match) == 0) {
-            QTAILQ_REMOVE(&acl->entries, entry, next);
-            return i;
-        }
-    }
-    return -1;
-}
-
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
diff --git a/util/aes.c b/util/aes.c
index 54c7b98..4b4d88e 100644
--- a/util/aes.c
+++ b/util/aes.c
@@ -30,12 +30,7 @@
 #include "qemu-common.h"
 #include "qemu/aes.h"
 
-#ifndef NDEBUG
-#define NDEBUG
-#endif
-
 typedef uint32_t u32;
-typedef uint16_t u16;
 typedef uint8_t u8;
 
 /* This controls loop-unrolling in aes_core.c */
@@ -44,20 +39,20 @@
 # define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
 
 /*
-Te0[x] = S [x].[02, 01, 01, 03];
-Te1[x] = S [x].[03, 02, 01, 01];
-Te2[x] = S [x].[01, 03, 02, 01];
-Te3[x] = S [x].[01, 01, 03, 02];
-Te4[x] = S [x].[01, 01, 01, 01];
+AES_Te0[x] = S [x].[02, 01, 01, 03];
+AES_Te1[x] = S [x].[03, 02, 01, 01];
+AES_Te2[x] = S [x].[01, 03, 02, 01];
+AES_Te3[x] = S [x].[01, 01, 03, 02];
+AES_Te4[x] = S [x].[01, 01, 01, 01];
 
-Td0[x] = Si[x].[0e, 09, 0d, 0b];
-Td1[x] = Si[x].[0b, 0e, 09, 0d];
-Td2[x] = Si[x].[0d, 0b, 0e, 09];
-Td3[x] = Si[x].[09, 0d, 0b, 0e];
-Td4[x] = Si[x].[01, 01, 01, 01];
+AES_Td0[x] = Si[x].[0e, 09, 0d, 0b];
+AES_Td1[x] = Si[x].[0b, 0e, 09, 0d];
+AES_Td2[x] = Si[x].[0d, 0b, 0e, 09];
+AES_Td3[x] = Si[x].[09, 0d, 0b, 0e];
+AES_Td4[x] = Si[x].[01, 01, 01, 01];
 */
 
-static const u32 Te0[256] = {
+const uint32_t AES_Te0[256] = {
     0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
     0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
     0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
@@ -123,7 +118,7 @@
     0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
     0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
 };
-static const u32 Te1[256] = {
+const uint32_t AES_Te1[256] = {
     0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
     0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
     0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
@@ -189,7 +184,7 @@
     0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
     0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
 };
-static const u32 Te2[256] = {
+const uint32_t AES_Te2[256] = {
     0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
     0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
     0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
@@ -255,7 +250,7 @@
     0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
     0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
 };
-static const u32 Te3[256] = {
+const uint32_t AES_Te3[256] = {
 
     0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
     0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
@@ -322,7 +317,7 @@
     0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
     0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
 };
-static const u32 Te4[256] = {
+const uint32_t AES_Te4[256] = {
     0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
     0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
     0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
@@ -388,7 +383,7 @@
     0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
     0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
 };
-static const u32 Td0[256] = {
+const uint32_t AES_Td0[256] = {
     0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
     0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
     0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
@@ -454,7 +449,7 @@
     0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
     0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
 };
-static const u32 Td1[256] = {
+const uint32_t AES_Td1[256] = {
     0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
     0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
     0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
@@ -520,7 +515,7 @@
     0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
     0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
 };
-static const u32 Td2[256] = {
+const uint32_t AES_Td2[256] = {
     0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
     0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
     0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
@@ -587,7 +582,7 @@
     0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
     0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
 };
-static const u32 Td3[256] = {
+const uint32_t AES_Td3[256] = {
     0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
     0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
     0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
@@ -653,7 +648,7 @@
     0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
     0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
 };
-static const u32 Td4[256] = {
+const uint32_t AES_Td4[256] = {
     0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
     0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
     0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
@@ -757,10 +752,10 @@
 		while (1) {
 			temp  = rk[3];
 			rk[4] = rk[0] ^
-				(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
-				(Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
-				(Te4[(temp      ) & 0xff] & 0x0000ff00) ^
-				(Te4[(temp >> 24)       ] & 0x000000ff) ^
+                                (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                                (AES_Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                                (AES_Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+                                (AES_Te4[(temp >> 24)       ] & 0x000000ff) ^
 				rcon[i];
 			rk[5] = rk[1] ^ rk[4];
 			rk[6] = rk[2] ^ rk[5];
@@ -777,10 +772,10 @@
 		while (1) {
 			temp = rk[ 5];
 			rk[ 6] = rk[ 0] ^
-				(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
-				(Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
-				(Te4[(temp      ) & 0xff] & 0x0000ff00) ^
-				(Te4[(temp >> 24)       ] & 0x000000ff) ^
+                                (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                                (AES_Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                                (AES_Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+                                (AES_Te4[(temp >> 24)       ] & 0x000000ff) ^
 				rcon[i];
 			rk[ 7] = rk[ 1] ^ rk[ 6];
 			rk[ 8] = rk[ 2] ^ rk[ 7];
@@ -799,10 +794,10 @@
 		while (1) {
 			temp = rk[ 7];
 			rk[ 8] = rk[ 0] ^
-				(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
-				(Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
-				(Te4[(temp      ) & 0xff] & 0x0000ff00) ^
-				(Te4[(temp >> 24)       ] & 0x000000ff) ^
+                                (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                                (AES_Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                                (AES_Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+                                (AES_Te4[(temp >> 24)       ] & 0x000000ff) ^
 				rcon[i];
 			rk[ 9] = rk[ 1] ^ rk[ 8];
 			rk[10] = rk[ 2] ^ rk[ 9];
@@ -812,10 +807,10 @@
 			}
 			temp = rk[11];
 			rk[12] = rk[ 4] ^
-				(Te4[(temp >> 24)       ] & 0xff000000) ^
-				(Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
-				(Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^
-				(Te4[(temp      ) & 0xff] & 0x000000ff);
+                                (AES_Te4[(temp >> 24)       ] & 0xff000000) ^
+                                (AES_Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+                                (AES_Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^
+                                (AES_Te4[(temp      ) & 0xff] & 0x000000ff);
 			rk[13] = rk[ 5] ^ rk[12];
 			rk[14] = rk[ 6] ^ rk[13];
 			rk[15] = rk[ 7] ^ rk[14];
@@ -854,25 +849,25 @@
 	for (i = 1; i < (key->rounds); i++) {
 		rk += 4;
 		rk[0] =
-			Td0[Te4[(rk[0] >> 24)       ] & 0xff] ^
-			Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
-			Td2[Te4[(rk[0] >>  8) & 0xff] & 0xff] ^
-			Td3[Te4[(rk[0]      ) & 0xff] & 0xff];
+                        AES_Td0[AES_Te4[(rk[0] >> 24)       ] & 0xff] ^
+                        AES_Td1[AES_Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
+                        AES_Td2[AES_Te4[(rk[0] >>  8) & 0xff] & 0xff] ^
+                        AES_Td3[AES_Te4[(rk[0]      ) & 0xff] & 0xff];
 		rk[1] =
-			Td0[Te4[(rk[1] >> 24)       ] & 0xff] ^
-			Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
-			Td2[Te4[(rk[1] >>  8) & 0xff] & 0xff] ^
-			Td3[Te4[(rk[1]      ) & 0xff] & 0xff];
+                        AES_Td0[AES_Te4[(rk[1] >> 24)       ] & 0xff] ^
+                        AES_Td1[AES_Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
+                        AES_Td2[AES_Te4[(rk[1] >>  8) & 0xff] & 0xff] ^
+                        AES_Td3[AES_Te4[(rk[1]      ) & 0xff] & 0xff];
 		rk[2] =
-			Td0[Te4[(rk[2] >> 24)       ] & 0xff] ^
-			Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
-			Td2[Te4[(rk[2] >>  8) & 0xff] & 0xff] ^
-			Td3[Te4[(rk[2]      ) & 0xff] & 0xff];
+                        AES_Td0[AES_Te4[(rk[2] >> 24)       ] & 0xff] ^
+                        AES_Td1[AES_Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
+                        AES_Td2[AES_Te4[(rk[2] >>  8) & 0xff] & 0xff] ^
+                        AES_Td3[AES_Te4[(rk[2]      ) & 0xff] & 0xff];
 		rk[3] =
-			Td0[Te4[(rk[3] >> 24)       ] & 0xff] ^
-			Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
-			Td2[Te4[(rk[3] >>  8) & 0xff] & 0xff] ^
-			Td3[Te4[(rk[3]      ) & 0xff] & 0xff];
+                        AES_Td0[AES_Te4[(rk[3] >> 24)       ] & 0xff] ^
+                        AES_Td1[AES_Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
+                        AES_Td2[AES_Te4[(rk[3] >>  8) & 0xff] & 0xff] ^
+                        AES_Td3[AES_Te4[(rk[3]      ) & 0xff] & 0xff];
 	}
 	return 0;
 }
@@ -904,72 +899,72 @@
 	s3 = GETU32(in + 12) ^ rk[3];
 #ifdef FULL_UNROLL
 	/* round 1: */
-   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
-   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
-   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
-   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
+        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[ 4];
+        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[ 5];
+        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[ 6];
+        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[ 7];
    	/* round 2: */
-   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
-   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
-   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
-   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
+        s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[ 8];
+        s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[ 9];
+        s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[10];
+        s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[11];
 	/* round 3: */
-   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
-   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
-   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
-   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
+        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[12];
+        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[13];
+        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[14];
+        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[15];
    	/* round 4: */
-   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
-   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
-   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
-   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
+        s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[16];
+        s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[17];
+        s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[18];
+        s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[19];
 	/* round 5: */
-   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
-   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
-   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
-   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
+        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[20];
+        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[21];
+        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[22];
+        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[23];
    	/* round 6: */
-   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
-   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
-   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
-   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
+        s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[24];
+        s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[25];
+        s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[26];
+        s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[27];
 	/* round 7: */
-   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
-   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
-   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
-   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
+        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[28];
+        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[29];
+        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[30];
+        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[31];
    	/* round 8: */
-   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
-   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
-   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
-   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
+        s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[32];
+        s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[33];
+        s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[34];
+        s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[35];
 	/* round 9: */
-   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
-   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
-   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
-   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
+        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[36];
+        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[37];
+        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[38];
+        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[39];
     if (key->rounds > 10) {
         /* round 10: */
-        s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
-        s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
-        s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
-        s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+        s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[40];
+        s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[41];
+        s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[42];
+        s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[43];
         /* round 11: */
-        t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
-        t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
-        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
-        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[44];
+        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[45];
+        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[46];
+        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[47];
         if (key->rounds > 12) {
             /* round 12: */
-            s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
-            s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
-            s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
-            s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+            s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[48];
+            s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[49];
+            s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[50];
+            s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[51];
             /* round 13: */
-            t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
-            t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
-            t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
-            t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+            t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[52];
+            t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[53];
+            t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[54];
+            t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[55];
         }
     }
     rk += key->rounds << 2;
@@ -980,28 +975,28 @@
     r = key->rounds >> 1;
     for (;;) {
         t0 =
-            Te0[(s0 >> 24)       ] ^
-            Te1[(s1 >> 16) & 0xff] ^
-            Te2[(s2 >>  8) & 0xff] ^
-            Te3[(s3      ) & 0xff] ^
+            AES_Te0[(s0 >> 24)       ] ^
+            AES_Te1[(s1 >> 16) & 0xff] ^
+            AES_Te2[(s2 >>  8) & 0xff] ^
+            AES_Te3[(s3      ) & 0xff] ^
             rk[4];
         t1 =
-            Te0[(s1 >> 24)       ] ^
-            Te1[(s2 >> 16) & 0xff] ^
-            Te2[(s3 >>  8) & 0xff] ^
-            Te3[(s0      ) & 0xff] ^
+            AES_Te0[(s1 >> 24)       ] ^
+            AES_Te1[(s2 >> 16) & 0xff] ^
+            AES_Te2[(s3 >>  8) & 0xff] ^
+            AES_Te3[(s0      ) & 0xff] ^
             rk[5];
         t2 =
-            Te0[(s2 >> 24)       ] ^
-            Te1[(s3 >> 16) & 0xff] ^
-            Te2[(s0 >>  8) & 0xff] ^
-            Te3[(s1      ) & 0xff] ^
+            AES_Te0[(s2 >> 24)       ] ^
+            AES_Te1[(s3 >> 16) & 0xff] ^
+            AES_Te2[(s0 >>  8) & 0xff] ^
+            AES_Te3[(s1      ) & 0xff] ^
             rk[6];
         t3 =
-            Te0[(s3 >> 24)       ] ^
-            Te1[(s0 >> 16) & 0xff] ^
-            Te2[(s1 >>  8) & 0xff] ^
-            Te3[(s2      ) & 0xff] ^
+            AES_Te0[(s3 >> 24)       ] ^
+            AES_Te1[(s0 >> 16) & 0xff] ^
+            AES_Te2[(s1 >>  8) & 0xff] ^
+            AES_Te3[(s2      ) & 0xff] ^
             rk[7];
 
         rk += 8;
@@ -1010,28 +1005,28 @@
         }
 
         s0 =
-            Te0[(t0 >> 24)       ] ^
-            Te1[(t1 >> 16) & 0xff] ^
-            Te2[(t2 >>  8) & 0xff] ^
-            Te3[(t3      ) & 0xff] ^
+            AES_Te0[(t0 >> 24)       ] ^
+            AES_Te1[(t1 >> 16) & 0xff] ^
+            AES_Te2[(t2 >>  8) & 0xff] ^
+            AES_Te3[(t3      ) & 0xff] ^
             rk[0];
         s1 =
-            Te0[(t1 >> 24)       ] ^
-            Te1[(t2 >> 16) & 0xff] ^
-            Te2[(t3 >>  8) & 0xff] ^
-            Te3[(t0      ) & 0xff] ^
+            AES_Te0[(t1 >> 24)       ] ^
+            AES_Te1[(t2 >> 16) & 0xff] ^
+            AES_Te2[(t3 >>  8) & 0xff] ^
+            AES_Te3[(t0      ) & 0xff] ^
             rk[1];
         s2 =
-            Te0[(t2 >> 24)       ] ^
-            Te1[(t3 >> 16) & 0xff] ^
-            Te2[(t0 >>  8) & 0xff] ^
-            Te3[(t1      ) & 0xff] ^
+            AES_Te0[(t2 >> 24)       ] ^
+            AES_Te1[(t3 >> 16) & 0xff] ^
+            AES_Te2[(t0 >>  8) & 0xff] ^
+            AES_Te3[(t1      ) & 0xff] ^
             rk[2];
         s3 =
-            Te0[(t3 >> 24)       ] ^
-            Te1[(t0 >> 16) & 0xff] ^
-            Te2[(t1 >>  8) & 0xff] ^
-            Te3[(t2      ) & 0xff] ^
+            AES_Te0[(t3 >> 24)       ] ^
+            AES_Te1[(t0 >> 16) & 0xff] ^
+            AES_Te2[(t1 >>  8) & 0xff] ^
+            AES_Te3[(t2      ) & 0xff] ^
             rk[3];
     }
 #endif /* ?FULL_UNROLL */
@@ -1040,31 +1035,31 @@
 	 * map cipher state to byte array block:
 	 */
 	s0 =
-		(Te4[(t0 >> 24)       ] & 0xff000000) ^
-		(Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
-		(Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
-		(Te4[(t3      ) & 0xff] & 0x000000ff) ^
+                (AES_Te4[(t0 >> 24)       ] & 0xff000000) ^
+                (AES_Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+                (AES_Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+                (AES_Te4[(t3      ) & 0xff] & 0x000000ff) ^
 		rk[0];
 	PUTU32(out     , s0);
 	s1 =
-		(Te4[(t1 >> 24)       ] & 0xff000000) ^
-		(Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
-		(Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
-		(Te4[(t0      ) & 0xff] & 0x000000ff) ^
+                (AES_Te4[(t1 >> 24)       ] & 0xff000000) ^
+                (AES_Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+                (AES_Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+                (AES_Te4[(t0      ) & 0xff] & 0x000000ff) ^
 		rk[1];
 	PUTU32(out +  4, s1);
 	s2 =
-		(Te4[(t2 >> 24)       ] & 0xff000000) ^
-		(Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
-		(Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
-		(Te4[(t1      ) & 0xff] & 0x000000ff) ^
+                (AES_Te4[(t2 >> 24)       ] & 0xff000000) ^
+                (AES_Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+                (AES_Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+                (AES_Te4[(t1      ) & 0xff] & 0x000000ff) ^
 		rk[2];
 	PUTU32(out +  8, s2);
 	s3 =
-		(Te4[(t3 >> 24)       ] & 0xff000000) ^
-		(Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
-		(Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
-		(Te4[(t2      ) & 0xff] & 0x000000ff) ^
+                (AES_Te4[(t3 >> 24)       ] & 0xff000000) ^
+                (AES_Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+                (AES_Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+                (AES_Te4[(t2      ) & 0xff] & 0x000000ff) ^
 		rk[3];
 	PUTU32(out + 12, s3);
 }
@@ -1095,72 +1090,72 @@
     s3 = GETU32(in + 12) ^ rk[3];
 #ifdef FULL_UNROLL
     /* round 1: */
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
+    t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[ 4];
+    t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[ 5];
+    t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[ 6];
+    t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[ 7];
     /* round 2: */
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
+    s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[ 8];
+    s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[ 9];
+    s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[10];
+    s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[11];
     /* round 3: */
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
+    t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[12];
+    t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[13];
+    t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[14];
+    t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[15];
     /* round 4: */
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
+    s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[16];
+    s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[17];
+    s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[18];
+    s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[19];
     /* round 5: */
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
+    t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[20];
+    t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[21];
+    t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[22];
+    t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[23];
     /* round 6: */
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
+    s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[24];
+    s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[25];
+    s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[26];
+    s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[27];
     /* round 7: */
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
+    t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[28];
+    t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[29];
+    t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[30];
+    t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[31];
     /* round 8: */
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
+    s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[32];
+    s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[33];
+    s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[34];
+    s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[35];
     /* round 9: */
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
+    t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[36];
+    t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[37];
+    t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[38];
+    t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[39];
     if (key->rounds > 10) {
         /* round 10: */
-        s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
-        s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
-        s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
-        s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
+        s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[40];
+        s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[41];
+        s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[42];
+        s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[43];
         /* round 11: */
-        t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
-        t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
-        t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
-        t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
+        t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[44];
+        t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[45];
+        t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[46];
+        t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[47];
         if (key->rounds > 12) {
             /* round 12: */
-            s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
-            s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
-            s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
-            s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+            s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[48];
+            s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[49];
+            s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[50];
+            s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[51];
             /* round 13: */
-            t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
-            t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
-            t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
-            t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+            t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[52];
+            t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[53];
+            t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[54];
+            t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[55];
         }
     }
 	rk += key->rounds << 2;
@@ -1171,28 +1166,28 @@
     r = key->rounds >> 1;
     for (;;) {
         t0 =
-            Td0[(s0 >> 24)       ] ^
-            Td1[(s3 >> 16) & 0xff] ^
-            Td2[(s2 >>  8) & 0xff] ^
-            Td3[(s1      ) & 0xff] ^
+            AES_Td0[(s0 >> 24)       ] ^
+            AES_Td1[(s3 >> 16) & 0xff] ^
+            AES_Td2[(s2 >>  8) & 0xff] ^
+            AES_Td3[(s1      ) & 0xff] ^
             rk[4];
         t1 =
-            Td0[(s1 >> 24)       ] ^
-            Td1[(s0 >> 16) & 0xff] ^
-            Td2[(s3 >>  8) & 0xff] ^
-            Td3[(s2      ) & 0xff] ^
+            AES_Td0[(s1 >> 24)       ] ^
+            AES_Td1[(s0 >> 16) & 0xff] ^
+            AES_Td2[(s3 >>  8) & 0xff] ^
+            AES_Td3[(s2      ) & 0xff] ^
             rk[5];
         t2 =
-            Td0[(s2 >> 24)       ] ^
-            Td1[(s1 >> 16) & 0xff] ^
-            Td2[(s0 >>  8) & 0xff] ^
-            Td3[(s3      ) & 0xff] ^
+            AES_Td0[(s2 >> 24)       ] ^
+            AES_Td1[(s1 >> 16) & 0xff] ^
+            AES_Td2[(s0 >>  8) & 0xff] ^
+            AES_Td3[(s3      ) & 0xff] ^
             rk[6];
         t3 =
-            Td0[(s3 >> 24)       ] ^
-            Td1[(s2 >> 16) & 0xff] ^
-            Td2[(s1 >>  8) & 0xff] ^
-            Td3[(s0      ) & 0xff] ^
+            AES_Td0[(s3 >> 24)       ] ^
+            AES_Td1[(s2 >> 16) & 0xff] ^
+            AES_Td2[(s1 >>  8) & 0xff] ^
+            AES_Td3[(s0      ) & 0xff] ^
             rk[7];
 
         rk += 8;
@@ -1201,28 +1196,28 @@
         }
 
         s0 =
-            Td0[(t0 >> 24)       ] ^
-            Td1[(t3 >> 16) & 0xff] ^
-            Td2[(t2 >>  8) & 0xff] ^
-            Td3[(t1      ) & 0xff] ^
+            AES_Td0[(t0 >> 24)       ] ^
+            AES_Td1[(t3 >> 16) & 0xff] ^
+            AES_Td2[(t2 >>  8) & 0xff] ^
+            AES_Td3[(t1      ) & 0xff] ^
             rk[0];
         s1 =
-            Td0[(t1 >> 24)       ] ^
-            Td1[(t0 >> 16) & 0xff] ^
-            Td2[(t3 >>  8) & 0xff] ^
-            Td3[(t2      ) & 0xff] ^
+            AES_Td0[(t1 >> 24)       ] ^
+            AES_Td1[(t0 >> 16) & 0xff] ^
+            AES_Td2[(t3 >>  8) & 0xff] ^
+            AES_Td3[(t2      ) & 0xff] ^
             rk[1];
         s2 =
-            Td0[(t2 >> 24)       ] ^
-            Td1[(t1 >> 16) & 0xff] ^
-            Td2[(t0 >>  8) & 0xff] ^
-            Td3[(t3      ) & 0xff] ^
+            AES_Td0[(t2 >> 24)       ] ^
+            AES_Td1[(t1 >> 16) & 0xff] ^
+            AES_Td2[(t0 >>  8) & 0xff] ^
+            AES_Td3[(t3      ) & 0xff] ^
             rk[2];
         s3 =
-            Td0[(t3 >> 24)       ] ^
-            Td1[(t2 >> 16) & 0xff] ^
-            Td2[(t1 >>  8) & 0xff] ^
-            Td3[(t0      ) & 0xff] ^
+            AES_Td0[(t3 >> 24)       ] ^
+            AES_Td1[(t2 >> 16) & 0xff] ^
+            AES_Td2[(t1 >>  8) & 0xff] ^
+            AES_Td3[(t0      ) & 0xff] ^
             rk[3];
     }
 #endif /* ?FULL_UNROLL */
@@ -1231,31 +1226,31 @@
 	 * map cipher state to byte array block:
 	 */
    	s0 =
-   		(Td4[(t0 >> 24)       ] & 0xff000000) ^
-   		(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
-   		(Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
-   		(Td4[(t1      ) & 0xff] & 0x000000ff) ^
+                (AES_Td4[(t0 >> 24)       ] & 0xff000000) ^
+                (AES_Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+                (AES_Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+                (AES_Td4[(t1      ) & 0xff] & 0x000000ff) ^
    		rk[0];
 	PUTU32(out     , s0);
    	s1 =
-   		(Td4[(t1 >> 24)       ] & 0xff000000) ^
-   		(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
-   		(Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
-   		(Td4[(t2      ) & 0xff] & 0x000000ff) ^
+                (AES_Td4[(t1 >> 24)       ] & 0xff000000) ^
+                (AES_Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+                (AES_Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+                (AES_Td4[(t2      ) & 0xff] & 0x000000ff) ^
    		rk[1];
 	PUTU32(out +  4, s1);
    	s2 =
-   		(Td4[(t2 >> 24)       ] & 0xff000000) ^
-   		(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
-   		(Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
-   		(Td4[(t3      ) & 0xff] & 0x000000ff) ^
+                (AES_Td4[(t2 >> 24)       ] & 0xff000000) ^
+                (AES_Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+                (AES_Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+                (AES_Td4[(t3      ) & 0xff] & 0x000000ff) ^
    		rk[2];
 	PUTU32(out +  8, s2);
    	s3 =
-   		(Td4[(t3 >> 24)       ] & 0xff000000) ^
-   		(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
-   		(Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
-   		(Td4[(t0      ) & 0xff] & 0x000000ff) ^
+                (AES_Td4[(t3 >> 24)       ] & 0xff000000) ^
+                (AES_Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+                (AES_Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+                (AES_Td4[(t0      ) & 0xff] & 0x000000ff) ^
    		rk[3];
 	PUTU32(out + 12, s3);
 }
diff --git a/util/cache-utils.c b/util/cache-utils.c
index b95cd8d..0470030 100644
--- a/util/cache-utils.c
+++ b/util/cache-utils.c
@@ -1,3 +1,4 @@
+#include "qemu-common.h"
 #include "qemu/cache-utils.h"
 
 #if defined(_ARCH_PPC)
@@ -9,31 +10,33 @@
 #if defined _AIX
 #include <sys/systemcfg.h>
 
-static void ppc_init_cacheline_sizes(void)
+void qemu_cache_utils_init(void)
 {
     qemu_cache_conf.icache_bsize = _system_configuration.icache_line;
     qemu_cache_conf.dcache_bsize = _system_configuration.dcache_line;
 }
 
 #elif defined __linux__
+#include "qemu/osdep.h"
+#include "elf.h"
 
-#define QEMU_AT_NULL        0
-#define QEMU_AT_DCACHEBSIZE 19
-#define QEMU_AT_ICACHEBSIZE 20
-
-static void ppc_init_cacheline_sizes(char **envp)
+void qemu_cache_utils_init(void)
 {
-    unsigned long *auxv;
+    unsigned long dsize = qemu_getauxval(AT_DCACHEBSIZE);
+    unsigned long isize = qemu_getauxval(AT_ICACHEBSIZE);
 
-    while (*envp++);
-
-    for (auxv = (unsigned long *) envp; *auxv != QEMU_AT_NULL; auxv += 2) {
-        switch (*auxv) {
-        case QEMU_AT_DCACHEBSIZE: qemu_cache_conf.dcache_bsize = auxv[1]; break;
-        case QEMU_AT_ICACHEBSIZE: qemu_cache_conf.icache_bsize = auxv[1]; break;
-        default: break;
+    if (dsize == 0 || isize == 0) {
+        if (dsize == 0) {
+            fprintf(stderr, "getauxval AT_DCACHEBSIZE failed\n");
         }
+        if (isize == 0) {
+            fprintf(stderr, "getauxval AT_ICACHEBSIZE failed\n");
+        }
+        exit(1);
+
     }
+    qemu_cache_conf.dcache_bsize = dsize;
+    qemu_cache_conf.icache_bsize = isize;
 }
 
 #elif defined __APPLE__
@@ -41,7 +44,7 @@
 #include <sys/types.h>
 #include <sys/sysctl.h>
 
-static void ppc_init_cacheline_sizes(void)
+void qemu_cache_utils_init(void)
 {
     size_t len;
     unsigned cacheline;
@@ -55,9 +58,8 @@
         qemu_cache_conf.icache_bsize = cacheline;
     }
 }
-#endif
 
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -65,7 +67,7 @@
 #include <sys/types.h>
 #include <sys/sysctl.h>
 
-static void ppc_init_cacheline_sizes(void)
+void qemu_cache_utils_init(void)
 {
     size_t len = 4;
     unsigned cacheline;
@@ -79,19 +81,6 @@
     qemu_cache_conf.dcache_bsize = cacheline;
     qemu_cache_conf.icache_bsize = cacheline;
 }
-#endif    
-
-#ifdef __linux__
-void qemu_cache_utils_init(char **envp)
-{
-    ppc_init_cacheline_sizes(envp);
-}
-#else
-void qemu_cache_utils_init(char **envp)
-{
-    (void) envp;
-    ppc_init_cacheline_sizes();
-}
 #endif
 
 #endif /* _ARCH_PPC */
diff --git a/util/compatfd.c b/util/compatfd.c
index 3ba9931..430a41c 100644
--- a/util/compatfd.c
+++ b/util/compatfd.c
@@ -9,13 +9,15 @@
  * 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.
  */
 
 #include "qemu-common.h"
 #include "qemu/compatfd.h"
+#include "qemu/thread.h"
 
 #include <sys/syscall.h>
-#include <pthread.h>
 
 struct sigfd_compat_info
 {
@@ -26,10 +28,6 @@
 static void *sigwait_compat(void *opaque)
 {
     struct sigfd_compat_info *info = opaque;
-    sigset_t all;
-
-    sigfillset(&all);
-    sigprocmask(SIG_BLOCK, &all, NULL);
 
     while (1) {
         int sig;
@@ -69,9 +67,8 @@
 
 static int qemu_signalfd_compat(const sigset_t *mask)
 {
-    pthread_attr_t attr;
-    pthread_t tid;
     struct sigfd_compat_info *info;
+    QemuThread thread;
     int fds[2];
 
     info = malloc(sizeof(*info));
@@ -91,12 +88,7 @@
     memcpy(&info->mask, mask, sizeof(*mask));
     info->fd = fds[1];
 
-    pthread_attr_init(&attr);
-    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-    pthread_create(&tid, &attr, sigwait_compat, info);
-
-    pthread_attr_destroy(&attr);
+    qemu_thread_create(&thread, sigwait_compat, info, QEMU_THREAD_DETACHED);
 
     return fds[0];
 }
@@ -115,3 +107,22 @@
 
     return qemu_signalfd_compat(mask);
 }
+
+bool qemu_signalfd_available(void)
+{
+#ifdef CONFIG_SIGNALFD
+    sigset_t mask;
+    int fd;
+    bool ok;
+    sigemptyset(&mask);
+    errno = 0;
+    fd = syscall(SYS_signalfd, -1, &mask, _NSIG / 8);
+    ok = (errno != ENOSYS);
+    if (fd >= 0) {
+        close(fd);
+    }
+    return ok;
+#else
+    return false;
+#endif
+}
diff --git a/util/cutils.c b/util/cutils.c
index 833f13d..0116fcd 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -25,6 +25,16 @@
 #include "qemu/host-utils.h"
 #include <math.h>
 
+#include "qemu/sockets.h"
+#include "qemu/iov.h"
+
+void strpadcpy(char *buf, int buf_size, const char *str, char pad)
+{
+    int len = qemu_strnlen(str, buf_size);
+    memcpy(buf, str, len);
+    memset(buf + len, pad, buf_size - len);
+}
+
 void pstrcpy(char *buf, int buf_size, const char *str)
 {
     int c;
@@ -97,6 +107,27 @@
     return i;
 }
 
+char *qemu_strsep(char **input, const char *delim)
+{
+    char *result = *input;
+    if (result != NULL) {
+        char *p;
+
+        for (p = result; *p != '\0'; p++) {
+            if (strchr(delim, *p)) {
+                break;
+            }
+        }
+        if (*p == '\0') {
+            *input = NULL;
+        } else {
+            *p = '\0';
+            *input = p + 1;
+        }
+    }
+    return result;
+}
+
 time_t mktimegm(struct tm *tm)
 {
     time_t t;
@@ -105,7 +136,7 @@
         m += 12;
         y--;
     }
-    t = 86400 * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + 
+    t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + 
                  y / 400 - 719469);
     t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
     return t;
@@ -132,170 +163,99 @@
 #endif
 }
 
-/* io vectors */
+/*
+ * Searches for an area with non-zero content in a buffer
+ *
+ * Attention! The len must be a multiple of
+ * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE)
+ * and addr must be a multiple of sizeof(VECTYPE) due to
+ * restriction of optimizations in this function.
+ *
+ * can_use_buffer_find_nonzero_offset() can be used to check
+ * these requirements.
+ *
+ * The return value is the offset of the non-zero area rounded
+ * down to a multiple of sizeof(VECTYPE) for the first
+ * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR chunks and down to
+ * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE)
+ * afterwards.
+ *
+ * If the buffer is all zero the return value is equal to len.
+ */
 
-void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)
+size_t buffer_find_nonzero_offset(const void *buf, size_t len)
 {
-    qiov->iov = g_malloc(alloc_hint * sizeof(struct iovec));
-    qiov->niov = 0;
-    qiov->nalloc = alloc_hint;
-    qiov->size = 0;
-}
+    const VECTYPE *p = buf;
+    const VECTYPE zero = (VECTYPE){0};
+    size_t i;
 
-void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov)
-{
-    int i;
+    assert(can_use_buffer_find_nonzero_offset(buf, len));
 
-    qiov->iov = iov;
-    qiov->niov = niov;
-    qiov->nalloc = -1;
-    qiov->size = 0;
-    for (i = 0; i < niov; i++)
-        qiov->size += iov[i].iov_len;
-}
-
-void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
-{
-    assert(qiov->nalloc != -1);
-
-    if (qiov->niov == qiov->nalloc) {
-        qiov->nalloc = 2 * qiov->nalloc + 1;
-        qiov->iov = g_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec));
+    if (!len) {
+        return 0;
     }
-    qiov->iov[qiov->niov].iov_base = base;
-    qiov->iov[qiov->niov].iov_len = len;
-    qiov->size += len;
-    ++qiov->niov;
+
+    for (i = 0; i < BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i++) {
+        if (!ALL_EQ(p[i], zero)) {
+            return i * sizeof(VECTYPE);
+        }
+    }
+
+    for (i = BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR;
+         i < len / sizeof(VECTYPE);
+         i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) {
+        VECTYPE tmp0 = p[i + 0] | p[i + 1];
+        VECTYPE tmp1 = p[i + 2] | p[i + 3];
+        VECTYPE tmp2 = p[i + 4] | p[i + 5];
+        VECTYPE tmp3 = p[i + 6] | p[i + 7];
+        VECTYPE tmp01 = tmp0 | tmp1;
+        VECTYPE tmp23 = tmp2 | tmp3;
+        if (!ALL_EQ(tmp01 | tmp23, zero)) {
+            break;
+        }
+    }
+
+    return i * sizeof(VECTYPE);
 }
 
 /*
- * Copies iovecs from src to the end of dst. It starts copying after skipping
- * the given number of bytes in src and copies until src is completely copied
- * or the total size of the copied iovec reaches size.The size of the last
- * copied iovec is changed in order to fit the specified total size if it isn't
- * a perfect fit already.
+ * Checks if a buffer is all zeroes
+ *
+ * Attention! The len must be a multiple of 4 * sizeof(long) due to
+ * restriction of optimizations in this function.
  */
-void qemu_iovec_copy(QEMUIOVector *dst, QEMUIOVector *src, uint64_t skip,
-    size_t size)
+bool buffer_is_zero(const void *buf, size_t len)
 {
-    int i;
-    size_t done;
-    void *iov_base;
-    uint64_t iov_len;
+    /*
+     * Use long as the biggest available internal data type that fits into the
+     * CPU register and unroll the loop to smooth out the effect of memory
+     * latency.
+     */
 
-    assert(dst->nalloc != -1);
+    size_t i;
+    long d0, d1, d2, d3;
+    const long * const data = buf;
 
-    done = 0;
-    for (i = 0; (i < src->niov) && (done != size); i++) {
-        if (skip >= src->iov[i].iov_len) {
-            /* Skip the whole iov */
-            skip -= src->iov[i].iov_len;
-            continue;
-        } else {
-            /* Skip only part (or nothing) of the iov */
-            iov_base = (uint8_t*) src->iov[i].iov_base + skip;
-            iov_len = src->iov[i].iov_len - skip;
-            skip = 0;
+    /* use vector optimized zero check if possible */
+    if (can_use_buffer_find_nonzero_offset(buf, len)) {
+        return buffer_find_nonzero_offset(buf, len) == len;
+    }
+
+    assert(len % (4 * sizeof(long)) == 0);
+    len /= sizeof(long);
+
+    for (i = 0; i < len; i += 4) {
+        d0 = data[i + 0];
+        d1 = data[i + 1];
+        d2 = data[i + 2];
+        d3 = data[i + 3];
+
+        if (d0 || d1 || d2 || d3) {
+            return false;
         }
-
-        if (done + iov_len > size) {
-            qemu_iovec_add(dst, iov_base, size - done);
-            break;
-        } else {
-            qemu_iovec_add(dst, iov_base, iov_len);
-        }
-        done += iov_len;
     }
-}
 
-void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size)
-{
-    qemu_iovec_copy(dst, src, 0, size);
-}
-
-void qemu_iovec_destroy(QEMUIOVector *qiov)
-{
-    assert(qiov->nalloc != -1);
-
-    g_free(qiov->iov);
-}
-
-void qemu_iovec_reset(QEMUIOVector *qiov)
-{
-    assert(qiov->nalloc != -1);
-
-    qiov->niov = 0;
-    qiov->size = 0;
-}
-
-void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf)
-{
-    uint8_t *p = (uint8_t *)buf;
-    int i;
-
-    for (i = 0; i < qiov->niov; ++i) {
-        memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
-        p += qiov->iov[i].iov_len;
-    }
-}
-
-void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count)
-{
-    const uint8_t *p = (const uint8_t *)buf;
-    size_t copy;
-    int i;
-
-    for (i = 0; i < qiov->niov && count; ++i) {
-        copy = count;
-        if (copy > qiov->iov[i].iov_len)
-            copy = qiov->iov[i].iov_len;
-        memcpy(qiov->iov[i].iov_base, p, copy);
-        p     += copy;
-        count -= copy;
-    }
-}
-
-void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count)
-{
-    size_t n;
-    int i;
-
-    for (i = 0; i < qiov->niov && count; ++i) {
-        n = MIN(count, qiov->iov[i].iov_len);
-        memset(qiov->iov[i].iov_base, c, n);
-        count -= n;
-    }
-}
-
-void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count,
-                            size_t skip)
-{
-    int i;
-    size_t done;
-    void *iov_base;
-    uint64_t iov_len;
-
-    done = 0;
-    for (i = 0; (i < qiov->niov) && (done != count); i++) {
-        if (skip >= qiov->iov[i].iov_len) {
-            /* Skip the whole iov */
-            skip -= qiov->iov[i].iov_len;
-            continue;
-        } else {
-            /* Skip only part (or nothing) of the iov */
-            iov_base = (uint8_t*) qiov->iov[i].iov_base + skip;
-            iov_len = qiov->iov[i].iov_len - skip;
-            skip = 0;
-        }
-
-        if (done + iov_len > count) {
-            memset(iov_base, c, count - done);
-            break;
-        } else {
-            memset(iov_base, c, iov_len);
-        }
-        done += iov_len;
-    }
+    return true;
 }
 
 #ifndef _WIN32
@@ -315,18 +275,39 @@
 }
 #endif
 
+static int64_t suffix_mul(char suffix, int64_t unit)
+{
+    switch (qemu_toupper(suffix)) {
+    case STRTOSZ_DEFSUFFIX_B:
+        return 1;
+    case STRTOSZ_DEFSUFFIX_KB:
+        return unit;
+    case STRTOSZ_DEFSUFFIX_MB:
+        return unit * unit;
+    case STRTOSZ_DEFSUFFIX_GB:
+        return unit * unit * unit;
+    case STRTOSZ_DEFSUFFIX_TB:
+        return unit * unit * unit * unit;
+    case STRTOSZ_DEFSUFFIX_PB:
+        return unit * unit * unit * unit * unit;
+    case STRTOSZ_DEFSUFFIX_EB:
+        return unit * unit * unit * unit * unit * unit;
+    }
+    return -1;
+}
+
 /*
  * Convert string to bytes, allowing either B/b for bytes, K/k for KB,
- * M/m for MB, G/g for GB or T/t for TB. Default without any postfix
- * is MB. End pointer will be returned in *end, if not NULL. A valid
- * value must be terminated by whitespace, ',' or '\0'. Return -1 on
- * error.
+ * M/m for MB, G/g for GB or T/t for TB. End pointer will be returned
+ * in *end, if not NULL. Return -ERANGE on overflow, Return -EINVAL on
+ * other error.
  */
-int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
+int64_t strtosz_suffix_unit(const char *nptr, char **end,
+                            const char default_suffix, int64_t unit)
 {
-    int64_t retval = -1;
+    int64_t retval = -EINVAL;
     char *endptr;
-    unsigned char c, d;
+    unsigned char c;
     int mul_required = 0;
     double val, mul, integral, fraction;
 
@@ -339,60 +320,19 @@
     if (fraction != 0) {
         mul_required = 1;
     }
-    /*
-     * Any whitespace character is fine for terminating the number,
-     * in addition we accept ',' to handle strings where the size is
-     * part of a multi token argument.
-     */
     c = *endptr;
-    d = c;
-    if (qemu_isspace(c) || c == '\0' || c == ',') {
-        c = 0;
-        if (default_suffix) {
-            d = default_suffix;
-        } else {
-            d = c;
-        }
+    mul = suffix_mul(c, unit);
+    if (mul >= 0) {
+        endptr++;
+    } else {
+        mul = suffix_mul(default_suffix, unit);
+        assert(mul >= 0);
     }
-    switch (qemu_toupper(d)) {
-    case STRTOSZ_DEFSUFFIX_B:
-        mul = 1;
-        if (mul_required) {
-            goto fail;
-        }
-        break;
-    case STRTOSZ_DEFSUFFIX_KB:
-        mul = 1 << 10;
-        break;
-    case 0:
-        if (mul_required) {
-            goto fail;
-        }
-    case STRTOSZ_DEFSUFFIX_MB:
-        mul = 1ULL << 20;
-        break;
-    case STRTOSZ_DEFSUFFIX_GB:
-        mul = 1ULL << 30;
-        break;
-    case STRTOSZ_DEFSUFFIX_TB:
-        mul = 1ULL << 40;
-        break;
-    default:
+    if (mul == 1 && mul_required) {
         goto fail;
     }
-    /*
-     * If not terminated by whitespace, ',', or \0, increment endptr
-     * to point to next character, then check that we are terminated
-     * by an appropriate separating character, ie. whitespace, ',', or
-     * \0. If not, we are seeing trailing garbage, thus fail.
-     */
-    if (c != 0) {
-        endptr++;
-        if (!qemu_isspace(*endptr) && *endptr != ',' && *endptr != 0) {
-            goto fail;
-        }
-    }
     if ((val * mul >= INT64_MAX) || val < 0) {
+        retval = -ERANGE;
         goto fail;
     }
     retval = val * mul;
@@ -405,7 +345,188 @@
     return retval;
 }
 
+int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
+{
+    return strtosz_suffix_unit(nptr, end, default_suffix, 1024);
+}
+
 int64_t strtosz(const char *nptr, char **end)
 {
     return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB);
 }
+
+/**
+ * parse_uint:
+ *
+ * @s: String to parse
+ * @value: Destination for parsed integer value
+ * @endptr: Destination for pointer to first character not consumed
+ * @base: integer base, between 2 and 36 inclusive, or 0
+ *
+ * Parse unsigned integer
+ *
+ * Parsed syntax is like strtoull()'s: arbitrary whitespace, a single optional
+ * '+' or '-', an optional "0x" if @base is 0 or 16, one or more digits.
+ *
+ * If @s is null, or @base is invalid, or @s doesn't start with an
+ * integer in the syntax above, set *@value to 0, *@endptr to @s, and
+ * return -EINVAL.
+ *
+ * Set *@endptr to point right beyond the parsed integer (even if the integer
+ * overflows or is negative, all digits will be parsed and *@endptr will
+ * point right beyond them).
+ *
+ * If the integer is negative, set *@value to 0, and return -ERANGE.
+ *
+ * If the integer overflows unsigned long long, set *@value to
+ * ULLONG_MAX, and return -ERANGE.
+ *
+ * Else, set *@value to the parsed integer, and return 0.
+ */
+int parse_uint(const char *s, unsigned long long *value, char **endptr,
+               int base)
+{
+    int r = 0;
+    char *endp = (char *)s;
+    unsigned long long val = 0;
+
+    if (!s) {
+        r = -EINVAL;
+        goto out;
+    }
+
+    errno = 0;
+    val = strtoull(s, &endp, base);
+    if (errno) {
+        r = -errno;
+        goto out;
+    }
+
+    if (endp == s) {
+        r = -EINVAL;
+        goto out;
+    }
+
+    /* make sure we reject negative numbers: */
+    while (isspace((unsigned char)*s)) {
+        s++;
+    }
+    if (*s == '-') {
+        val = 0;
+        r = -ERANGE;
+        goto out;
+    }
+
+out:
+    *value = val;
+    *endptr = endp;
+    return r;
+}
+
+/**
+ * parse_uint_full:
+ *
+ * @s: String to parse
+ * @value: Destination for parsed integer value
+ * @base: integer base, between 2 and 36 inclusive, or 0
+ *
+ * Parse unsigned integer from entire string
+ *
+ * Have the same behavior of parse_uint(), but with an additional check
+ * for additional data after the parsed number. If extra characters are present
+ * after the parsed number, the function will return -EINVAL, and *@v will
+ * be set to 0.
+ */
+int parse_uint_full(const char *s, unsigned long long *value, int base)
+{
+    char *endp;
+    int r;
+
+    r = parse_uint(s, value, &endp, base);
+    if (r < 0) {
+        return r;
+    }
+    if (*endp) {
+        *value = 0;
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+int qemu_parse_fd(const char *param)
+{
+    int fd;
+    char *endptr = NULL;
+
+    fd = strtol(param, &endptr, 10);
+    if (*endptr || (fd == 0 && param == endptr)) {
+        return -1;
+    }
+    return fd;
+}
+
+/* round down to the nearest power of 2*/
+int64_t pow2floor(int64_t value)
+{
+    if (!is_power_of_2(value)) {
+        value = 0x8000000000000000ULL >> clz64(value);
+    }
+    return value;
+}
+
+/*
+ * Implementation of  ULEB128 (http://en.wikipedia.org/wiki/LEB128)
+ * Input is limited to 14-bit numbers
+ */
+int uleb128_encode_small(uint8_t *out, uint32_t n)
+{
+    g_assert(n <= 0x3fff);
+    if (n < 0x80) {
+        *out++ = n;
+        return 1;
+    } else {
+        *out++ = (n & 0x7f) | 0x80;
+        *out++ = n >> 7;
+        return 2;
+    }
+}
+
+int uleb128_decode_small(const uint8_t *in, uint32_t *n)
+{
+    if (!(*in & 0x80)) {
+        *n = *in++;
+        return 1;
+    } else {
+        *n = *in++ & 0x7f;
+        /* we exceed 14 bit number */
+        if (*in & 0x80) {
+            return -1;
+        }
+        *n |= *in++ << 7;
+        return 2;
+    }
+}
+
+/*
+ * helper to parse debug environment variables
+ */
+int parse_debug_env(const char *name, int max, int initial)
+{
+    char *debug_env = getenv(name);
+    char *inv = NULL;
+    int debug;
+
+    if (!debug_env) {
+        return initial;
+    }
+    debug = strtol(debug_env, &inv, 10);
+    if (inv == debug_env) {
+        return initial;
+    }
+    if (debug < 0 || debug > max) {
+        fprintf(stderr, "warning: %s not in [0, %d]", name, max);
+        return initial;
+    }
+    return debug;
+}
diff --git a/util/envlist.c b/util/envlist.c
index ff99fc4..ebc06cf 100644
--- a/util/envlist.c
+++ b/util/envlist.c
@@ -1,9 +1,4 @@
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
+#include "qemu-common.h"
 #include "qemu/queue.h"
 #include "qemu/envlist.h"
 
diff --git a/util/error.c b/util/error.c
new file mode 100644
index 0000000..3ee362a
--- /dev/null
+++ b/util/error.c
@@ -0,0 +1,161 @@
+/*
+ * QEMU Error Objects
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.  See
+ * the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qjson.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi-types.h"
+#include "qapi/qmp/qerror.h"
+
+struct Error
+{
+    char *msg;
+    ErrorClass err_class;
+};
+
+void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
+{
+    Error *err;
+    va_list ap;
+    int saved_errno = errno;
+
+    if (errp == NULL) {
+        return;
+    }
+    assert(*errp == NULL);
+
+    err = g_malloc0(sizeof(*err));
+
+    va_start(ap, fmt);
+    err->msg = g_strdup_vprintf(fmt, ap);
+    va_end(ap);
+    err->err_class = err_class;
+
+    *errp = err;
+
+    errno = saved_errno;
+}
+
+void error_set_errno(Error **errp, int os_errno, ErrorClass err_class,
+                     const char *fmt, ...)
+{
+    Error *err;
+    char *msg1;
+    va_list ap;
+    int saved_errno = errno;
+
+    if (errp == NULL) {
+        return;
+    }
+    assert(*errp == NULL);
+
+    err = g_malloc0(sizeof(*err));
+
+    va_start(ap, fmt);
+    msg1 = g_strdup_vprintf(fmt, ap);
+    if (os_errno != 0) {
+        err->msg = g_strdup_printf("%s: %s", msg1, strerror(os_errno));
+        g_free(msg1);
+    } else {
+        err->msg = msg1;
+    }
+    va_end(ap);
+    err->err_class = err_class;
+
+    *errp = err;
+
+    errno = saved_errno;
+}
+
+void error_setg_file_open(Error **errp, int os_errno, const char *filename)
+{
+    error_setg_errno(errp, os_errno, "Could not open '%s'", filename);
+}
+
+#ifdef _WIN32
+
+void error_set_win32(Error **errp, int win32_err, ErrorClass err_class,
+                     const char *fmt, ...)
+{
+    Error *err;
+    char *msg1;
+    va_list ap;
+
+    if (errp == NULL) {
+        return;
+    }
+    assert(*errp == NULL);
+
+    err = g_malloc0(sizeof(*err));
+
+    va_start(ap, fmt);
+    msg1 = g_strdup_vprintf(fmt, ap);
+    if (win32_err != 0) {
+        char *msg2 = g_win32_error_message(win32_err);
+        err->msg = g_strdup_printf("%s: %s (error: %x)", msg1, msg2,
+                                   (unsigned)win32_err);
+        g_free(msg2);
+        g_free(msg1);
+    } else {
+        err->msg = msg1;
+    }
+    va_end(ap);
+    err->err_class = err_class;
+
+    *errp = err;
+}
+
+#endif
+
+Error *error_copy(const Error *err)
+{
+    Error *err_new;
+
+    err_new = g_malloc0(sizeof(*err));
+    err_new->msg = g_strdup(err->msg);
+    err_new->err_class = err->err_class;
+
+    return err_new;
+}
+
+bool error_is_set(Error **errp)
+{
+    return (errp && *errp);
+}
+
+ErrorClass error_get_class(const Error *err)
+{
+    return err->err_class;
+}
+
+const char *error_get_pretty(Error *err)
+{
+    return err->msg;
+}
+
+void error_free(Error *err)
+{
+    if (err) {
+        g_free(err->msg);
+        g_free(err);
+    }
+}
+
+void error_propagate(Error **dst_err, Error *local_err)
+{
+    if (dst_err && !*dst_err) {
+        *dst_err = local_err;
+    } else if (local_err) {
+        error_free(local_err);
+    }
+}
diff --git a/util/hexdump.c b/util/hexdump.c
new file mode 100644
index 0000000..969b340
--- /dev/null
+++ b/util/hexdump.c
@@ -0,0 +1,37 @@
+/*
+ * Helper to hexdump a buffer
+ *
+ * Copyright (c) 2013 Red Hat, Inc.
+ * Copyright (c) 2013 Gerd Hoffmann <kraxel@redhat.com>
+ * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com>
+ * Copyright (c) 2013 Xilinx, Inc
+ *
+ * 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.
+ */
+
+#include "qemu-common.h"
+
+void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size)
+{
+    unsigned int b;
+
+    for (b = 0; b < size; b++) {
+        if ((b % 16) == 0) {
+            fprintf(fp, "%s: %04x:", prefix, b);
+        }
+        if ((b % 4) == 0) {
+            fprintf(fp, " ");
+        }
+        fprintf(fp, " %02x", (unsigned char)buf[b]);
+        if ((b % 16) == 15) {
+            fprintf(fp, "\n");
+        }
+    }
+    if ((b % 16) != 0) {
+        fprintf(fp, "\n");
+    }
+}
diff --git a/util/host-utils.c b/util/host-utils.c
index 5e3915a..f0784d6 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -27,79 +27,63 @@
 #include <stdint.h>
 #include "qemu/host-utils.h"
 
-//#define DEBUG_MULDIV
-
 /* Long integer helpers */
-#if !defined(__x86_64__)
-static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
+#ifndef CONFIG_INT128
+static inline void mul64(uint64_t *plow, uint64_t *phigh,
+                         uint64_t a, uint64_t b)
 {
-    *plow += a;
-    /* carry test */
-    if (*plow < a)
-        (*phigh)++;
-    *phigh += b;
-}
+    typedef union {
+        uint64_t ll;
+        struct {
+#ifdef HOST_WORDS_BIGENDIAN
+            uint32_t high, low;
+#else
+            uint32_t low, high;
+#endif
+        } l;
+    } LL;
+    LL rl, rm, rn, rh, a0, b0;
+    uint64_t c;
 
-static void neg128 (uint64_t *plow, uint64_t *phigh)
-{
-    *plow = ~*plow;
-    *phigh = ~*phigh;
-    add128(plow, phigh, 1, 0);
-}
+    a0.ll = a;
+    b0.ll = b;
 
-static void mul64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
-{
-    uint32_t a0, a1, b0, b1;
-    uint64_t v;
+    rl.ll = (uint64_t)a0.l.low * b0.l.low;
+    rm.ll = (uint64_t)a0.l.low * b0.l.high;
+    rn.ll = (uint64_t)a0.l.high * b0.l.low;
+    rh.ll = (uint64_t)a0.l.high * b0.l.high;
 
-    a0 = a;
-    a1 = a >> 32;
+    c = (uint64_t)rl.l.high + rm.l.low + rn.l.low;
+    rl.l.high = c;
+    c >>= 32;
+    c = c + rm.l.high + rn.l.high + rh.l.low;
+    rh.l.low = c;
+    rh.l.high += (uint32_t)(c >> 32);
 
-    b0 = b;
-    b1 = b >> 32;
-
-    v = (uint64_t)a0 * (uint64_t)b0;
-    *plow = v;
-    *phigh = 0;
-
-    v = (uint64_t)a0 * (uint64_t)b1;
-    add128(plow, phigh, v << 32, v >> 32);
-
-    v = (uint64_t)a1 * (uint64_t)b0;
-    add128(plow, phigh, v << 32, v >> 32);
-
-    v = (uint64_t)a1 * (uint64_t)b1;
-    *phigh += v;
+    *plow = rl.ll;
+    *phigh = rh.ll;
 }
 
 /* Unsigned 64x64 -> 128 multiplication */
 void mulu64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
 {
     mul64(plow, phigh, a, b);
-#if defined(DEBUG_MULDIV)
-    printf("mulu64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
-           a, b, *phigh, *plow);
-#endif
 }
 
 /* Signed 64x64 -> 128 multiplication */
 void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
 {
-    int sa, sb;
+    uint64_t rh;
 
-    sa = (a < 0);
-    if (sa)
-        a = -a;
-    sb = (b < 0);
-    if (sb)
-        b = -b;
-    mul64(plow, phigh, a, b);
-    if (sa ^ sb) {
-        neg128(plow, phigh);
+    mul64(plow, &rh, a, b);
+
+    /* Adjust for signs.  */
+    if (b < 0) {
+        rh -= a;
     }
-#if defined(DEBUG_MULDIV)
-    printf("muls64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
-           a, b, *phigh, *plow);
-#endif
+    if (a < 0) {
+        rh -= b;
+    }
+    *phigh = rh;
 }
-#endif /* !defined(__x86_64__) */
+#endif /* !CONFIG_INT128 */
diff --git a/util/iov.c b/util/iov.c
new file mode 100644
index 0000000..bb46c04
--- /dev/null
+++ b/util/iov.c
@@ -0,0 +1,430 @@
+/*
+ * Helpers for getting linearized buffers from iov / filling buffers into iovs
+ *
+ * Copyright IBM, Corp. 2007, 2008
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * Author(s):
+ *  Anthony Liguori <aliguori@us.ibm.com>
+ *  Amit Shah <amit.shah@redhat.com>
+ *  Michael Tokarev <mjt@tls.msk.ru>
+ *
+ * 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.
+ */
+
+#include "qemu/iov.h"
+
+#ifdef _WIN32
+# include <windows.h>
+# include <winsock2.h>
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+#endif
+
+size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
+                    size_t offset, const void *buf, size_t bytes)
+{
+    size_t done;
+    unsigned int i;
+    for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
+        if (offset < iov[i].iov_len) {
+            size_t len = MIN(iov[i].iov_len - offset, bytes - done);
+            memcpy(iov[i].iov_base + offset, buf + done, len);
+            done += len;
+            offset = 0;
+        } else {
+            offset -= iov[i].iov_len;
+        }
+    }
+    assert(offset == 0);
+    return done;
+}
+
+size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
+                  size_t offset, void *buf, size_t bytes)
+{
+    size_t done;
+    unsigned int i;
+    for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
+        if (offset < iov[i].iov_len) {
+            size_t len = MIN(iov[i].iov_len - offset, bytes - done);
+            memcpy(buf + done, iov[i].iov_base + offset, len);
+            done += len;
+            offset = 0;
+        } else {
+            offset -= iov[i].iov_len;
+        }
+    }
+    assert(offset == 0);
+    return done;
+}
+
+size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
+                  size_t offset, int fillc, size_t bytes)
+{
+    size_t done;
+    unsigned int i;
+    for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
+        if (offset < iov[i].iov_len) {
+            size_t len = MIN(iov[i].iov_len - offset, bytes - done);
+            memset(iov[i].iov_base + offset, fillc, len);
+            done += len;
+            offset = 0;
+        } else {
+            offset -= iov[i].iov_len;
+        }
+    }
+    assert(offset == 0);
+    return done;
+}
+
+size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt)
+{
+    size_t len;
+    unsigned int i;
+
+    len = 0;
+    for (i = 0; i < iov_cnt; i++) {
+        len += iov[i].iov_len;
+    }
+    return len;
+}
+
+/* helper function for iov_send_recv() */
+static ssize_t
+do_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt, bool do_send)
+{
+#ifdef CONFIG_POSIX
+    ssize_t ret;
+    struct msghdr msg;
+    memset(&msg, 0, sizeof(msg));
+    msg.msg_iov = iov;
+    msg.msg_iovlen = iov_cnt;
+    do {
+        ret = do_send
+            ? sendmsg(sockfd, &msg, 0)
+            : recvmsg(sockfd, &msg, 0);
+    } while (ret < 0 && errno == EINTR);
+    return ret;
+#else
+    /* else send piece-by-piece */
+    /*XXX Note: windows has WSASend() and WSARecv() */
+    unsigned i = 0;
+    ssize_t ret = 0;
+    while (i < iov_cnt) {
+        ssize_t r = do_send
+            ? send(sockfd, iov[i].iov_base, iov[i].iov_len, 0)
+            : recv(sockfd, iov[i].iov_base, iov[i].iov_len, 0);
+        if (r > 0) {
+            ret += r;
+        } else if (!r) {
+            break;
+        } else if (errno == EINTR) {
+            continue;
+        } else {
+            /* else it is some "other" error,
+             * only return if there was no data processed. */
+            if (ret == 0) {
+                ret = -1;
+            }
+            break;
+        }
+        i++;
+    }
+    return ret;
+#endif
+}
+
+ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt,
+                      size_t offset, size_t bytes,
+                      bool do_send)
+{
+    ssize_t total = 0;
+    ssize_t ret;
+    size_t orig_len, tail;
+    unsigned niov;
+
+    while (bytes > 0) {
+        /* Find the start position, skipping `offset' bytes:
+         * first, skip all full-sized vector elements, */
+        for (niov = 0; niov < iov_cnt && offset >= iov[niov].iov_len; ++niov) {
+            offset -= iov[niov].iov_len;
+        }
+
+        /* niov == iov_cnt would only be valid if bytes == 0, which
+         * we already ruled out in the loop condition.  */
+        assert(niov < iov_cnt);
+        iov += niov;
+        iov_cnt -= niov;
+
+        if (offset) {
+            /* second, skip `offset' bytes from the (now) first element,
+             * undo it on exit */
+            iov[0].iov_base += offset;
+            iov[0].iov_len -= offset;
+        }
+        /* Find the end position skipping `bytes' bytes: */
+        /* first, skip all full-sized elements */
+        tail = bytes;
+        for (niov = 0; niov < iov_cnt && iov[niov].iov_len <= tail; ++niov) {
+            tail -= iov[niov].iov_len;
+        }
+        if (tail) {
+            /* second, fixup the last element, and remember the original
+             * length */
+            assert(niov < iov_cnt);
+            assert(iov[niov].iov_len > tail);
+            orig_len = iov[niov].iov_len;
+            iov[niov++].iov_len = tail;
+            ret = do_send_recv(sockfd, iov, niov, do_send);
+            /* Undo the changes above before checking for errors */
+            iov[niov-1].iov_len = orig_len;
+        } else {
+            ret = do_send_recv(sockfd, iov, niov, do_send);
+        }
+        if (offset) {
+            iov[0].iov_base -= offset;
+            iov[0].iov_len += offset;
+        }
+
+        if (ret < 0) {
+            assert(errno != EINTR);
+            if (errno == EAGAIN && total > 0) {
+                return total;
+            }
+            return -1;
+        }
+
+        if (ret == 0 && !do_send) {
+            /* recv returns 0 when the peer has performed an orderly
+             * shutdown. */
+            break;
+        }
+
+        /* Prepare for the next iteration */
+        offset += ret;
+        total += ret;
+        bytes -= ret;
+    }
+
+    return total;
+}
+
+
+void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt,
+                 FILE *fp, const char *prefix, size_t limit)
+{
+    int v;
+    size_t size = 0;
+    char *buf;
+
+    for (v = 0; v < iov_cnt; v++) {
+        size += iov[v].iov_len;
+    }
+    size = size > limit ? limit : size;
+    buf = g_malloc(size);
+    iov_to_buf(iov, iov_cnt, 0, buf, size);
+    qemu_hexdump(buf, fp, prefix, size);
+    g_free(buf);
+}
+
+unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
+                 const struct iovec *iov, unsigned int iov_cnt,
+                 size_t offset, size_t bytes)
+{
+    size_t len;
+    unsigned int i, j;
+    for (i = 0, j = 0; i < iov_cnt && j < dst_iov_cnt && bytes; i++) {
+        if (offset >= iov[i].iov_len) {
+            offset -= iov[i].iov_len;
+            continue;
+        }
+        len = MIN(bytes, iov[i].iov_len - offset);
+
+        dst_iov[j].iov_base = iov[i].iov_base + offset;
+        dst_iov[j].iov_len = len;
+        j++;
+        bytes -= len;
+        offset = 0;
+    }
+    assert(offset == 0);
+    return j;
+}
+
+/* io vectors */
+
+void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)
+{
+    qiov->iov = g_malloc(alloc_hint * sizeof(struct iovec));
+    qiov->niov = 0;
+    qiov->nalloc = alloc_hint;
+    qiov->size = 0;
+}
+
+void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov)
+{
+    int i;
+
+    qiov->iov = iov;
+    qiov->niov = niov;
+    qiov->nalloc = -1;
+    qiov->size = 0;
+    for (i = 0; i < niov; i++)
+        qiov->size += iov[i].iov_len;
+}
+
+void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
+{
+    assert(qiov->nalloc != -1);
+
+    if (qiov->niov == qiov->nalloc) {
+        qiov->nalloc = 2 * qiov->nalloc + 1;
+        qiov->iov = g_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec));
+    }
+    qiov->iov[qiov->niov].iov_base = base;
+    qiov->iov[qiov->niov].iov_len = len;
+    qiov->size += len;
+    ++qiov->niov;
+}
+
+/*
+ * Concatenates (partial) iovecs from src_iov to the end of dst.
+ * It starts copying after skipping `soffset' bytes at the
+ * beginning of src and adds individual vectors from src to
+ * dst copies up to `sbytes' bytes total, or up to the end
+ * of src_iov if it comes first.  This way, it is okay to specify
+ * very large value for `sbytes' to indicate "up to the end
+ * of src".
+ * Only vector pointers are processed, not the actual data buffers.
+ */
+void qemu_iovec_concat_iov(QEMUIOVector *dst,
+                           struct iovec *src_iov, unsigned int src_cnt,
+                           size_t soffset, size_t sbytes)
+{
+    int i;
+    size_t done;
+
+    if (!sbytes) {
+        return;
+    }
+    assert(dst->nalloc != -1);
+    for (i = 0, done = 0; done < sbytes && i < src_cnt; i++) {
+        if (soffset < src_iov[i].iov_len) {
+            size_t len = MIN(src_iov[i].iov_len - soffset, sbytes - done);
+            qemu_iovec_add(dst, src_iov[i].iov_base + soffset, len);
+            done += len;
+            soffset = 0;
+        } else {
+            soffset -= src_iov[i].iov_len;
+        }
+    }
+    assert(soffset == 0); /* offset beyond end of src */
+}
+
+/*
+ * Concatenates (partial) iovecs from src to the end of dst.
+ * It starts copying after skipping `soffset' bytes at the
+ * beginning of src and adds individual vectors from src to
+ * dst copies up to `sbytes' bytes total, or up to the end
+ * of src if it comes first.  This way, it is okay to specify
+ * very large value for `sbytes' to indicate "up to the end
+ * of src".
+ * Only vector pointers are processed, not the actual data buffers.
+ */
+void qemu_iovec_concat(QEMUIOVector *dst,
+                       QEMUIOVector *src, size_t soffset, size_t sbytes)
+{
+    qemu_iovec_concat_iov(dst, src->iov, src->niov, soffset, sbytes);
+}
+
+void qemu_iovec_destroy(QEMUIOVector *qiov)
+{
+    assert(qiov->nalloc != -1);
+
+    qemu_iovec_reset(qiov);
+    g_free(qiov->iov);
+    qiov->nalloc = 0;
+    qiov->iov = NULL;
+}
+
+void qemu_iovec_reset(QEMUIOVector *qiov)
+{
+    assert(qiov->nalloc != -1);
+
+    qiov->niov = 0;
+    qiov->size = 0;
+}
+
+size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset,
+                         void *buf, size_t bytes)
+{
+    return iov_to_buf(qiov->iov, qiov->niov, offset, buf, bytes);
+}
+
+size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset,
+                           const void *buf, size_t bytes)
+{
+    return iov_from_buf(qiov->iov, qiov->niov, offset, buf, bytes);
+}
+
+size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
+                         int fillc, size_t bytes)
+{
+    return iov_memset(qiov->iov, qiov->niov, offset, fillc, bytes);
+}
+
+size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt,
+                         size_t bytes)
+{
+    size_t total = 0;
+    struct iovec *cur;
+
+    for (cur = *iov; *iov_cnt > 0; cur++) {
+        if (cur->iov_len > bytes) {
+            cur->iov_base += bytes;
+            cur->iov_len -= bytes;
+            total += bytes;
+            break;
+        }
+
+        bytes -= cur->iov_len;
+        total += cur->iov_len;
+        *iov_cnt -= 1;
+    }
+
+    *iov = cur;
+    return total;
+}
+
+size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt,
+                        size_t bytes)
+{
+    size_t total = 0;
+    struct iovec *cur;
+
+    if (*iov_cnt == 0) {
+        return 0;
+    }
+
+    cur = iov + (*iov_cnt - 1);
+
+    while (*iov_cnt > 0) {
+        if (cur->iov_len > bytes) {
+            cur->iov_len -= bytes;
+            total += bytes;
+            break;
+        }
+
+        bytes -= cur->iov_len;
+        total += cur->iov_len;
+        cur--;
+        *iov_cnt -= 1;
+    }
+
+    return total;
+}
diff --git a/util/module.c b/util/module.c
index 89c082b..7acc33d 100644
--- a/util/module.c
+++ b/util/module.c
@@ -9,6 +9,8 @@
  * 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.
  */
 
 #include "qemu-common.h"
@@ -17,7 +19,6 @@
 
 typedef struct ModuleEntry
 {
-    module_init_type type;
     void (*init)(void);
     QTAILQ_ENTRY(ModuleEntry) node;
 } ModuleEntry;
diff --git a/util/notify.c b/util/notify.c
index 94af3a8..f215dfc 100644
--- a/util/notify.c
+++ b/util/notify.c
@@ -9,6 +9,8 @@
  * 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.
  */
 
 #include "qemu-common.h"
@@ -16,24 +18,54 @@
 
 void notifier_list_init(NotifierList *list)
 {
-    QTAILQ_INIT(&list->notifiers);
+    QLIST_INIT(&list->notifiers);
 }
 
 void notifier_list_add(NotifierList *list, Notifier *notifier)
 {
-    QTAILQ_INSERT_HEAD(&list->notifiers, notifier, node);
+    QLIST_INSERT_HEAD(&list->notifiers, notifier, node);
 }
 
-void notifier_list_remove(NotifierList *list, Notifier *notifier)
+void notifier_remove(Notifier *notifier)
 {
-    QTAILQ_REMOVE(&list->notifiers, notifier, node);
+    QLIST_REMOVE(notifier, node);
 }
 
-void notifier_list_notify(NotifierList *list)
+void notifier_list_notify(NotifierList *list, void *data)
 {
     Notifier *notifier, *next;
 
-    QTAILQ_FOREACH_SAFE(notifier, &list->notifiers, node, next) {
-        notifier->notify(notifier);
+    QLIST_FOREACH_SAFE(notifier, &list->notifiers, node, next) {
+        notifier->notify(notifier, data);
     }
 }
+
+void notifier_with_return_list_init(NotifierWithReturnList *list)
+{
+    QLIST_INIT(&list->notifiers);
+}
+
+void notifier_with_return_list_add(NotifierWithReturnList *list,
+                                   NotifierWithReturn *notifier)
+{
+    QLIST_INSERT_HEAD(&list->notifiers, notifier, node);
+}
+
+void notifier_with_return_remove(NotifierWithReturn *notifier)
+{
+    QLIST_REMOVE(notifier, node);
+}
+
+int notifier_with_return_list_notify(NotifierWithReturnList *list, void *data)
+{
+    NotifierWithReturn *notifier, *next;
+    int ret = 0;
+
+    QLIST_FOREACH_SAFE(notifier, &list->notifiers, node, next) {
+        ret = notifier->notify(notifier, data);
+        if (ret != 0) {
+            break;
+        }
+    }
+    return ret;
+}
diff --git a/util/osdep.c b/util/osdep.c
index a4e5098..a02858a 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
@@ -44,27 +45,31 @@
 extern int madvise(caddr_t, size_t, int);
 #endif
 
-#ifdef _WIN32
-#include <windows.h>
-#elif defined(CONFIG_BSD)
-#include <stdlib.h>
-#else
-#include <malloc.h>
-#endif
-
-#ifdef CONFIG_ANDROID
-#ifdef WIN32
-#include <winsock2.h>
-#include <stdint.h>
-typedef int32_t socklen_t;
-#else
-#include <sys/socket.h>
-#endif
-#endif /* CONFIG_ANDROID */
-
 #include "qemu-common.h"
-#include "sysemu/sysemu.h"
+#include "trace.h"
 #include "qemu/sockets.h"
+#include "monitor/monitor.h"
+
+static bool fips_enabled = false;
+
+static const char *qemu_version = QEMU_VERSION;
+
+#ifndef CONFIG_ANDROID  // See android/sockets.c instead.
+int socket_set_cork(int fd, int v)
+{
+#if defined(SOL_TCP) && defined(TCP_CORK)
+    return qemu_setsockopt(fd, SOL_TCP, TCP_CORK, &v, sizeof(v));
+#else
+    return 0;
+#endif
+}
+
+int socket_set_nodelay(int fd)
+{
+    int v = 1;
+    return qemu_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
+}
+#endif  // !CONFIG_ANDROID
 
 int qemu_madvise(void *addr, size_t len, int advice)
 {
@@ -82,6 +87,69 @@
 #endif
 }
 
+#ifndef CONFIG_ANDROID
+#ifndef _WIN32
+/*
+ * Dups an fd and sets the flags
+ */
+static int qemu_dup_flags(int fd, int flags)
+{
+    int ret;
+    int serrno;
+    int dup_flags;
+
+#ifdef F_DUPFD_CLOEXEC
+    ret = fcntl(fd, F_DUPFD_CLOEXEC, 0);
+#else
+    ret = dup(fd);
+    if (ret != -1) {
+        qemu_set_cloexec(ret);
+    }
+#endif
+    if (ret == -1) {
+        goto fail;
+    }
+
+    dup_flags = fcntl(ret, F_GETFL);
+    if (dup_flags == -1) {
+        goto fail;
+    }
+
+    if ((flags & O_SYNC) != (dup_flags & O_SYNC)) {
+        errno = EINVAL;
+        goto fail;
+    }
+
+    /* Set/unset flags that we can with fcntl */
+    if (fcntl(ret, F_SETFL, flags) == -1) {
+        goto fail;
+    }
+
+    /* Truncate the file in the cases that open() would truncate it */
+    if (flags & O_TRUNC ||
+            ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) {
+        if (ftruncate(ret, 0) == -1) {
+            goto fail;
+        }
+    }
+
+    return ret;
+
+fail:
+    serrno = errno;
+    if (ret != -1) {
+        close(ret);
+    }
+    errno = serrno;
+    return -1;
+}
+
+static int qemu_parse_fdset(const char *param)
+{
+    return qemu_parse_fd(param);
+}
+#endif
+#endif  // !CONFIG_ANDROID
 
 /*
  * Opens a file with FD_CLOEXEC set
@@ -91,6 +159,42 @@
     int ret;
     int mode = 0;
 
+#ifndef CONFIG_ANDROID
+#ifndef _WIN32
+    const char *fdset_id_str;
+
+    /* Attempt dup of fd from fd set */
+    if (strstart(name, "/dev/fdset/", &fdset_id_str)) {
+        int64_t fdset_id;
+        int fd, dupfd;
+
+        fdset_id = qemu_parse_fdset(fdset_id_str);
+        if (fdset_id == -1) {
+            errno = EINVAL;
+            return -1;
+        }
+
+        fd = monitor_fdset_get_fd(fdset_id, flags);
+        if (fd == -1) {
+            return -1;
+        }
+
+        dupfd = qemu_dup_flags(fd, flags);
+        if (dupfd == -1) {
+            return -1;
+        }
+
+        ret = monitor_fdset_dup_fd_add(fdset_id, dupfd);
+        if (ret == -1) {
+            close(dupfd);
+            errno = EINVAL;
+            return -1;
+        }
+        return dupfd;
+    }
+#endif
+#endif  // !CONFIG_ANDROID
+
     if (flags & O_CREAT) {
         va_list ap;
 
@@ -108,9 +212,37 @@
     }
 #endif
 
+#ifdef O_DIRECT
+    if (ret == -1 && errno == EINVAL && (flags & O_DIRECT)) {
+        error_report("file system may not support O_DIRECT");
+        errno = EINVAL; /* in case it was clobbered */
+    }
+#endif /* O_DIRECT */
+
     return ret;
 }
 
+int qemu_close(int fd)
+{
+#ifndef CONFIG_ANDROID
+    int64_t fdset_id;
+
+    /* Close fd that was dup'd from an fdset */
+    fdset_id = monitor_fdset_dup_fd_find(fd);
+    if (fdset_id != -1) {
+        int ret;
+
+        ret = close(fd);
+        if (ret == 0) {
+            monitor_fdset_dup_fd_remove(fd);
+        }
+
+        return ret;
+    }
+#endif
+    return close(fd);
+}
+
 /*
  * A variant of write(2) which handles partial write.
  *
@@ -164,6 +296,7 @@
     return ret;
 }
 
+#ifndef CONFIG_ANDROID
 /*
  * Accept a connection and set FD_CLOEXEC
  */
@@ -184,6 +317,178 @@
 
     return ret;
 }
+#endif
+
+/*
+ * A variant of send(2) which handles partial write.
+ *
+ * Return the number of bytes transferred, which is only
+ * smaller than `count' if there is an error.
+ *
+ * This function won't work with non-blocking fd's.
+ * Any of the possibilities with non-bloking fd's is bad:
+ *   - return a short write (then name is wrong)
+ *   - busy wait adding (errno == EAGAIN) to the loop
+ */
+ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags)
+{
+    ssize_t ret = 0;
+    ssize_t total = 0;
+
+    while (count) {
+        ret = send(fd, buf, count, flags);
+        if (ret < 0) {
+            if (errno == EINTR) {
+                continue;
+            }
+            break;
+        }
+
+        count -= ret;
+        buf += ret;
+        total += ret;
+    }
+
+    return total;
+}
+
+/*
+ * A variant of recv(2) which handles partial write.
+ *
+ * Return the number of bytes transferred, which is only
+ * smaller than `count' if there is an error.
+ *
+ * This function won't work with non-blocking fd's.
+ * Any of the possibilities with non-bloking fd's is bad:
+ *   - return a short write (then name is wrong)
+ *   - busy wait adding (errno == EAGAIN) to the loop
+ */
+ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags)
+{
+    ssize_t ret = 0;
+    ssize_t total = 0;
+
+    while (count) {
+        ret = qemu_recv(fd, buf, count, flags);
+        if (ret <= 0) {
+            if (ret < 0 && errno == EINTR) {
+                continue;
+            }
+            break;
+        }
+
+        count -= ret;
+        buf += ret;
+        total += ret;
+    }
+
+    return total;
+}
+
+void qemu_set_version(const char *version)
+{
+    qemu_version = version;
+}
+
+const char *qemu_get_version(void)
+{
+    return qemu_version;
+}
+
+void fips_set_state(bool requested)
+{
+#ifdef __linux__
+    if (requested) {
+        FILE *fds = fopen("/proc/sys/crypto/fips_enabled", "r");
+        if (fds != NULL) {
+            fips_enabled = (fgetc(fds) == '1');
+            fclose(fds);
+        }
+    }
+#else
+    fips_enabled = false;
+#endif /* __linux__ */
+
+#ifdef _FIPS_DEBUG
+    fprintf(stderr, "FIPS mode %s (requested %s)\n",
+	    (fips_enabled ? "enabled" : "disabled"),
+	    (requested ? "enabled" : "disabled"));
+#endif
+}
+
+bool fips_get_state(void)
+{
+    return fips_enabled;
+}
+
+#ifndef CONFIG_ANDROID
+#ifdef _WIN32
+static void socket_cleanup(void)
+{
+    WSACleanup();
+}
+#endif
+
+int socket_init(void)
+{
+#ifdef _WIN32
+    WSADATA Data;
+    int ret, err;
+
+    ret = WSAStartup(MAKEWORD(2, 2), &Data);
+    if (ret != 0) {
+        err = WSAGetLastError();
+        fprintf(stderr, "WSAStartup: %d\n", err);
+        return -1;
+    }
+    atexit(socket_cleanup);
+#endif
+    return 0;
+}
+#endif  // !CONFIG_ANDROID
+
+#ifndef CONFIG_IOVEC
+/* helper function for iov_send_recv() */
+static ssize_t
+readv_writev(int fd, const struct iovec *iov, int iov_cnt, bool do_write)
+{
+    unsigned i = 0;
+    ssize_t ret = 0;
+    while (i < iov_cnt) {
+        ssize_t r = do_write
+            ? write(fd, iov[i].iov_base, iov[i].iov_len)
+            : read(fd, iov[i].iov_base, iov[i].iov_len);
+        if (r > 0) {
+            ret += r;
+        } else if (!r) {
+            break;
+        } else if (errno == EINTR) {
+            continue;
+        } else {
+            /* else it is some "other" error,
+             * only return if there was no data processed. */
+            if (ret == 0) {
+                ret = -1;
+            }
+            break;
+        }
+        i++;
+    }
+    return ret;
+}
+
+ssize_t
+readv(int fd, const struct iovec *iov, int iov_cnt)
+{
+    return readv_writev(fd, iov, iov_cnt, false);
+}
+
+ssize_t
+writev(int fd, const struct iovec *iov, int iov_cnt)
+{
+    return readv_writev(fd, iov, iov_cnt, true);
+}
+#endif
 
 #ifdef WIN32
 int asprintf( char **, const char *, ... );
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index b5e6886..a2f3439 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -26,10 +26,55 @@
  * THE SOFTWARE.
  */
 
+/* The following block of code temporarily renames the daemon() function so the
+   compiler does not see the warning associated with it in stdlib.h on OSX */
+#ifdef __APPLE__
+#define daemon qemu_fake_daemon_function
+#include <stdlib.h>
+#undef daemon
+extern int daemon(int, int);
+#endif
+
+#if defined(__linux__) && (defined(__x86_64__) || defined(__arm__))
+   /* Use 2 MiB alignment so transparent hugepages can be used by KVM.
+      Valgrind does not support alignments larger than 1 MiB,
+      therefore we need special code which handles running on Valgrind. */
+#  define QEMU_VMALLOC_ALIGN (512 * 4096)
+#elif defined(__linux__) && defined(__s390x__)
+   /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */
+#  define QEMU_VMALLOC_ALIGN (256 * 4096)
+#else
+#  define QEMU_VMALLOC_ALIGN getpagesize()
+#endif
+
+#include "config-host.h"
+#ifndef CONFIG_ANDROID
+#include <glib/gprintf.h>
+#endif
+
 #include "config-host.h"
 #include "sysemu/sysemu.h"
 #include "trace.h"
 #include "qemu/sockets.h"
+#include <sys/mman.h>
+
+#ifdef CONFIG_LINUX
+#include <sys/syscall.h>
+#endif
+
+int qemu_get_thread_id(void)
+{
+#if defined(__linux__)
+    return syscall(SYS_gettid);
+#else
+    return getpid();
+#endif
+}
+
+int qemu_daemon(int nochdir, int noclose)
+{
+    return daemon(nochdir, noclose);
+}
 
 void *qemu_oom_check(void *ptr)
 {
@@ -66,20 +111,76 @@
     return qemu_memalign(getpagesize(), size);
 }
 
+/* alloc shared memory pages */
+void *qemu_anon_ram_alloc(size_t size)
+{
+    size_t align = QEMU_VMALLOC_ALIGN;
+    size_t total = size + align - getpagesize();
+    void *ptr = mmap(0, total, PROT_READ | PROT_WRITE,
+                     MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+    size_t offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr;
+
+    if (ptr == MAP_FAILED) {
+        return NULL;
+    }
+
+    ptr += offset;
+    total -= offset;
+
+    if (offset > 0) {
+        munmap(ptr - offset, offset);
+    }
+    if (total > size) {
+        munmap(ptr + size, total - size);
+    }
+
+    //trace_qemu_anon_ram_alloc(size, ptr);
+    return ptr;
+}
+
 void qemu_vfree(void *ptr)
 {
     //trace_qemu_vfree(ptr);
     free(ptr);
 }
 
-#if 0 /* in sockets.c */
-void socket_set_nonblock(int fd)
+void qemu_anon_ram_free(void *ptr, size_t size)
+{
+    //trace_qemu_anon_ram_free(ptr, size);
+    if (ptr) {
+        munmap(ptr, size);
+    }
+}
+
+void qemu_set_block(int fd)
+{
+    int f;
+    f = fcntl(fd, F_GETFL);
+    fcntl(fd, F_SETFL, f & ~O_NONBLOCK);
+}
+
+void qemu_set_nonblock(int fd)
 {
     int f;
     f = fcntl(fd, F_GETFL);
     fcntl(fd, F_SETFL, f | O_NONBLOCK);
 }
+
+int socket_set_fast_reuse(int fd)
+{
+#ifdef CONFIG_ANDROID
+    return socket_set_xreuseaddr(fd);
+#else
+    int val = 1, ret;
+
+    ret = qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+                     (const char *)&val, sizeof(val));
+
+    assert(ret == 0);
+
+    return ret;
 #endif
+}
 
 void qemu_set_cloexec(int fd)
 {
@@ -110,8 +211,7 @@
     return ret;
 }
 
-int qemu_utimensat(int dirfd, const char *path, const struct timespec *times,
-                   int flags)
+int qemu_utimens(const char *path, const struct timespec *times)
 {
     struct timeval tv[2], tv_now;
     struct stat st;
@@ -119,7 +219,7 @@
 #ifdef CONFIG_UTIMENSAT
     int ret;
 
-    ret = utimensat(dirfd, path, times, flags);
+    ret = utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW);
     if (ret != -1 || errno != ENOSYS) {
         return ret;
     }
@@ -157,3 +257,14 @@
 
     return utimes(path, &tv[0]);
 }
+
+char *
+qemu_get_local_state_pathname(const char *relative_pathname)
+{
+#ifdef CONFIG_ANDROID
+    return NULL;
+#else
+    return g_strdup_printf("%s/%s", CONFIG_QEMU_LOCALSTATEDIR,
+                           relative_pathname);
+#endif
+}
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index d5455da..b2489c9 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -26,11 +26,16 @@
  * THE SOFTWARE.
  */
 #include <windows.h>
+#include <glib.h>
+#include <stdlib.h>
 #include "config-host.h"
 #include "sysemu/sysemu.h"
 #include "trace.h"
 #include "qemu/sockets.h"
 
+/* this must come after including "trace.h" */
+#include <shlobj.h>
+
 void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
@@ -67,19 +72,83 @@
     return ptr;
 }
 
+void *qemu_anon_ram_alloc(size_t size)
+{
+    void *ptr;
+
+    /* FIXME: this is not exactly optimal solution since VirtualAlloc
+       has 64Kb granularity, but at least it guarantees us that the
+       memory is page aligned. */
+    ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
+    //trace_qemu_anon_ram_alloc(size, ptr);
+    return ptr;
+}
+
 void qemu_vfree(void *ptr)
 {
     //trace_qemu_vfree(ptr);
-    VirtualFree(ptr, 0, MEM_RELEASE);
+    if (ptr) {
+        VirtualFree(ptr, 0, MEM_RELEASE);
+    }
 }
 
-#if 0 /* in sockets.c */
-void socket_set_nonblock(int fd)
+void qemu_anon_ram_free(void *ptr, size_t size)
+{
+    //trace_qemu_anon_ram_free(ptr, size);
+    if (ptr) {
+        VirtualFree(ptr, 0, MEM_RELEASE);
+    }
+}
+
+/* FIXME: add proper locking */
+struct tm *gmtime_r(const time_t *timep, struct tm *result)
+{
+    struct tm *p = gmtime(timep);
+    memset(result, 0, sizeof(*result));
+    if (p) {
+        *result = *p;
+        p = result;
+    }
+    return p;
+}
+
+/* FIXME: add proper locking */
+struct tm *localtime_r(const time_t *timep, struct tm *result)
+{
+    struct tm *p = localtime(timep);
+    memset(result, 0, sizeof(*result));
+    if (p) {
+        *result = *p;
+        p = result;
+    }
+    return p;
+}
+
+void qemu_set_block(int fd)
+{
+    unsigned long opt = 0;
+    WSAEventSelect(fd, NULL, 0);
+    ioctlsocket(fd, FIONBIO, &opt);
+}
+
+void qemu_set_nonblock(int fd)
 {
     unsigned long opt = 1;
     ioctlsocket(fd, FIONBIO, &opt);
-}
+#ifndef CONFIG_ANDROID
+    qemu_fd_register(fd);
 #endif
+}
+
+int socket_set_fast_reuse(int fd)
+{
+    /* Enabling the reuse of an endpoint that was used by a socket still in
+     * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
+     * fast reuse is the default and SO_REUSEADDR does strange things. So we
+     * don't have to do anything here. More info can be found at:
+     * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
+    return 0;
+}
 
 int inet_aton(const char *cp, struct in_addr *ia)
 {
@@ -114,3 +183,25 @@
      Do not set errno on error.  */
   return 0;
 }
+
+int qemu_get_thread_id(void)
+{
+    return GetCurrentThreadId();
+}
+
+char *
+qemu_get_local_state_pathname(const char *relative_pathname)
+{
+    HRESULT result;
+    char base_path[MAX_PATH+1] = "";
+
+    result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
+                             /* SHGFP_TYPE_CURRENT */ 0, base_path);
+    if (result != S_OK) {
+        /* misconfigured environment */
+        g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result);
+        abort();
+    }
+    return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path,
+                           relative_pathname);
+}
diff --git a/util/path.c b/util/path.c
index f0d703f..2868d15 100644
--- a/util/path.c
+++ b/util/path.c
@@ -42,7 +42,7 @@
 }
 
 static struct pathelem *add_entry(struct pathelem *root, const char *name,
-                                  unsigned char type);
+                                  unsigned type);
 
 static struct pathelem *new_entry(const char *root,
                                   struct pathelem *parent,
@@ -50,10 +50,7 @@
 {
     struct pathelem *new = malloc(sizeof(*new));
     new->name = strdup(name);
-    if (asprintf(&new->pathname, "%s/%s", root, name) == -1) {
-        printf("Cannot allocate memory\n");
-        exit(1);
-    }
+    new->pathname = g_strdup_printf("%s/%s", root, name);
     new->num_entries = 0;
     return new;
 }
@@ -61,9 +58,10 @@
 #define streq(a,b) (strcmp((a), (b)) == 0)
 
 /* Not all systems provide this feature */
-#if defined(DT_DIR) && defined(DT_UNKNOWN)
+#if defined(DT_DIR) && defined(DT_UNKNOWN) && defined(DT_LNK)
 # define dirent_type(dirent) ((dirent)->d_type)
-# define is_dir_maybe(type)  ((type) == DT_DIR || (type) == DT_UNKNOWN)
+# define is_dir_maybe(type) \
+    ((type) == DT_DIR || (type) == DT_UNKNOWN || (type) == DT_LNK)
 #else
 # define dirent_type(dirent) (1)
 # define is_dir_maybe(type)  (type)
@@ -87,7 +85,7 @@
 }
 
 static struct pathelem *add_entry(struct pathelem *root, const char *name,
-                                  unsigned char type)
+                                  unsigned type)
 {
     struct pathelem **e;
 
diff --git a/util/qemu-error.c b/util/qemu-error.c
index 642bff9..55bad09 100644
--- a/util/qemu-error.c
+++ b/util/qemu-error.c
@@ -157,6 +157,11 @@
     progname = p ? p + 1 : argv0;
 }
 
+const char *error_get_progname(void)
+{
+    return progname;
+}
+
 /*
  * Print current location to current monitor if we have one, else to stderr.
  */
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 16e0c44..a3103eb 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -180,11 +180,11 @@
             continue;
         }
 
-        setsockopt(slisten,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on));
+        qemu_setsockopt(slisten,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on));
 #ifdef IPV6_V6ONLY
         if (e->ai_family == PF_INET6) {
             /* listen on both ipv4 and ipv6 */
-            setsockopt(slisten,IPPROTO_IPV6,IPV6_V6ONLY,(void*)&off,
+            qemu_setsockopt(slisten,IPPROTO_IPV6,IPV6_V6ONLY,(void*)&off,
                 sizeof(off));
         }
 #endif
@@ -284,7 +284,7 @@
             inet_strfamily(e->ai_family), strerror(errno));
             continue;
         }
-        setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on));
+        qemu_setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on));
 
         /* connect to peer */
         if (connect(sock,e->ai_addr,e->ai_addrlen) < 0) {
@@ -377,7 +377,7 @@
                 inet_strfamily(peer->ai_family), strerror(errno));
         goto err;
     }
-    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on));
+    qemu_setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on));
 
     /* bind socket */
     if (getnameinfo((struct sockaddr*)local->ai_addr,local->ai_addrlen,
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
new file mode 100644
index 0000000..37dd298
--- /dev/null
+++ b/util/qemu-thread-posix.c
@@ -0,0 +1,447 @@
+/*
+ * Wrappers around mutex/cond/thread functions
+ *
+ * Copyright Red Hat, Inc. 2009
+ *
+ * Author:
+ *  Marcelo Tosatti <mtosatti@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 <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+#include <signal.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/time.h>
+#ifdef __linux__
+#include <sys/syscall.h>
+#include <linux/futex.h>
+#endif
+#include "qemu/thread.h"
+#include "qemu/atomic.h"
+
+static void error_exit(int err, const char *msg)
+{
+    fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
+    abort();
+}
+
+void qemu_mutex_init(QemuMutex *mutex)
+{
+    int err;
+    pthread_mutexattr_t mutexattr;
+
+    pthread_mutexattr_init(&mutexattr);
+    pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK);
+    err = pthread_mutex_init(&mutex->lock, &mutexattr);
+    pthread_mutexattr_destroy(&mutexattr);
+    if (err)
+        error_exit(err, __func__);
+}
+
+void qemu_mutex_destroy(QemuMutex *mutex)
+{
+    int err;
+
+    err = pthread_mutex_destroy(&mutex->lock);
+    if (err)
+        error_exit(err, __func__);
+}
+
+void qemu_mutex_lock(QemuMutex *mutex)
+{
+    int err;
+
+    err = pthread_mutex_lock(&mutex->lock);
+    if (err)
+        error_exit(err, __func__);
+}
+
+int qemu_mutex_trylock(QemuMutex *mutex)
+{
+    return pthread_mutex_trylock(&mutex->lock);
+}
+
+void qemu_mutex_unlock(QemuMutex *mutex)
+{
+    int err;
+
+    err = pthread_mutex_unlock(&mutex->lock);
+    if (err)
+        error_exit(err, __func__);
+}
+
+void qemu_cond_init(QemuCond *cond)
+{
+    int err;
+
+    err = pthread_cond_init(&cond->cond, NULL);
+    if (err)
+        error_exit(err, __func__);
+}
+
+void qemu_cond_destroy(QemuCond *cond)
+{
+    int err;
+
+    err = pthread_cond_destroy(&cond->cond);
+    if (err)
+        error_exit(err, __func__);
+}
+
+void qemu_cond_signal(QemuCond *cond)
+{
+    int err;
+
+    err = pthread_cond_signal(&cond->cond);
+    if (err)
+        error_exit(err, __func__);
+}
+
+void qemu_cond_broadcast(QemuCond *cond)
+{
+    int err;
+
+    err = pthread_cond_broadcast(&cond->cond);
+    if (err)
+        error_exit(err, __func__);
+}
+
+void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
+{
+    int err;
+
+    err = pthread_cond_wait(&cond->cond, &mutex->lock);
+    if (err)
+        error_exit(err, __func__);
+}
+
+void qemu_sem_init(QemuSemaphore *sem, int init)
+{
+    int rc;
+
+#if defined(__APPLE__) || defined(__NetBSD__)
+    rc = pthread_mutex_init(&sem->lock, NULL);
+    if (rc != 0) {
+        error_exit(rc, __func__);
+    }
+    rc = pthread_cond_init(&sem->cond, NULL);
+    if (rc != 0) {
+        error_exit(rc, __func__);
+    }
+    if (init < 0) {
+        error_exit(EINVAL, __func__);
+    }
+    sem->count = init;
+#else
+    rc = sem_init(&sem->sem, 0, init);
+    if (rc < 0) {
+        error_exit(errno, __func__);
+    }
+#endif
+}
+
+void qemu_sem_destroy(QemuSemaphore *sem)
+{
+    int rc;
+
+#if defined(__APPLE__) || defined(__NetBSD__)
+    rc = pthread_cond_destroy(&sem->cond);
+    if (rc < 0) {
+        error_exit(rc, __func__);
+    }
+    rc = pthread_mutex_destroy(&sem->lock);
+    if (rc < 0) {
+        error_exit(rc, __func__);
+    }
+#else
+    rc = sem_destroy(&sem->sem);
+    if (rc < 0) {
+        error_exit(errno, __func__);
+    }
+#endif
+}
+
+void qemu_sem_post(QemuSemaphore *sem)
+{
+    int rc;
+
+#if defined(__APPLE__) || defined(__NetBSD__)
+    pthread_mutex_lock(&sem->lock);
+    if (sem->count == UINT_MAX) {
+        rc = EINVAL;
+    } else {
+        sem->count++;
+        rc = pthread_cond_signal(&sem->cond);
+    }
+    pthread_mutex_unlock(&sem->lock);
+    if (rc != 0) {
+        error_exit(rc, __func__);
+    }
+#else
+    rc = sem_post(&sem->sem);
+    if (rc < 0) {
+        error_exit(errno, __func__);
+    }
+#endif
+}
+
+static void compute_abs_deadline(struct timespec *ts, int ms)
+{
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    ts->tv_nsec = tv.tv_usec * 1000 + (ms % 1000) * 1000000;
+    ts->tv_sec = tv.tv_sec + ms / 1000;
+    if (ts->tv_nsec >= 1000000000) {
+        ts->tv_sec++;
+        ts->tv_nsec -= 1000000000;
+    }
+}
+
+int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
+{
+    int rc;
+    struct timespec ts;
+
+#if defined(__APPLE__) || defined(__NetBSD__)
+    rc = 0;
+    compute_abs_deadline(&ts, ms);
+    pthread_mutex_lock(&sem->lock);
+    while (sem->count == 0) {
+        rc = pthread_cond_timedwait(&sem->cond, &sem->lock, &ts);
+        if (rc == ETIMEDOUT) {
+            break;
+        }
+        if (rc != 0) {
+            error_exit(rc, __func__);
+        }
+    }
+    if (rc != ETIMEDOUT) {
+        --sem->count;
+    }
+    pthread_mutex_unlock(&sem->lock);
+    return (rc == ETIMEDOUT ? -1 : 0);
+#else
+    if (ms <= 0) {
+        /* This is cheaper than sem_timedwait.  */
+        do {
+            rc = sem_trywait(&sem->sem);
+        } while (rc == -1 && errno == EINTR);
+        if (rc == -1 && errno == EAGAIN) {
+            return -1;
+        }
+    } else {
+        compute_abs_deadline(&ts, ms);
+        do {
+            rc = sem_timedwait(&sem->sem, &ts);
+        } while (rc == -1 && errno == EINTR);
+        if (rc == -1 && errno == ETIMEDOUT) {
+            return -1;
+        }
+    }
+    if (rc < 0) {
+        error_exit(errno, __func__);
+    }
+    return 0;
+#endif
+}
+
+void qemu_sem_wait(QemuSemaphore *sem)
+{
+    int rc;
+
+#if defined(__APPLE__) || defined(__NetBSD__)
+    pthread_mutex_lock(&sem->lock);
+    while (sem->count == 0) {
+        rc = pthread_cond_wait(&sem->cond, &sem->lock);
+        if (rc != 0) {
+            error_exit(rc, __func__);
+        }
+    }
+    --sem->count;
+    pthread_mutex_unlock(&sem->lock);
+#else
+    do {
+        rc = sem_wait(&sem->sem);
+    } while (rc == -1 && errno == EINTR);
+    if (rc < 0) {
+        error_exit(errno, __func__);
+    }
+#endif
+}
+
+#ifdef __linux__
+#define futex(...)              syscall(__NR_futex, __VA_ARGS__)
+
+static inline void futex_wake(QemuEvent *ev, int n)
+{
+    futex(ev, FUTEX_WAKE, n, NULL, NULL, 0);
+}
+
+static inline void futex_wait(QemuEvent *ev, unsigned val)
+{
+    futex(ev, FUTEX_WAIT, (int) val, NULL, NULL, 0);
+}
+#else
+static inline void futex_wake(QemuEvent *ev, int n)
+{
+    if (n == 1) {
+        pthread_cond_signal(&ev->cond);
+    } else {
+        pthread_cond_broadcast(&ev->cond);
+    }
+}
+
+static inline void futex_wait(QemuEvent *ev, unsigned val)
+{
+    pthread_mutex_lock(&ev->lock);
+    if (ev->value == val) {
+        pthread_cond_wait(&ev->cond, &ev->lock);
+    }
+    pthread_mutex_unlock(&ev->lock);
+}
+#endif
+
+/* Valid transitions:
+ * - free->set, when setting the event
+ * - busy->set, when setting the event, followed by futex_wake
+ * - set->free, when resetting the event
+ * - free->busy, when waiting
+ *
+ * set->busy does not happen (it can be observed from the outside but
+ * it really is set->free->busy).
+ *
+ * busy->free provably cannot happen; to enforce it, the set->free transition
+ * is done with an OR, which becomes a no-op if the event has concurrently
+ * transitioned to free or busy.
+ */
+
+#define EV_SET         0
+#define EV_FREE        1
+#define EV_BUSY       -1
+
+void qemu_event_init(QemuEvent *ev, bool init)
+{
+#ifndef __linux__
+    pthread_mutex_init(&ev->lock, NULL);
+    pthread_cond_init(&ev->cond, NULL);
+#endif
+
+    ev->value = (init ? EV_SET : EV_FREE);
+}
+
+void qemu_event_destroy(QemuEvent *ev)
+{
+#ifndef __linux__
+    pthread_mutex_destroy(&ev->lock);
+    pthread_cond_destroy(&ev->cond);
+#endif
+}
+
+void qemu_event_set(QemuEvent *ev)
+{
+    if (atomic_mb_read(&ev->value) != EV_SET) {
+        if (atomic_xchg(&ev->value, EV_SET) == EV_BUSY) {
+            /* There were waiters, wake them up.  */
+            futex_wake(ev, INT_MAX);
+        }
+    }
+}
+
+void qemu_event_reset(QemuEvent *ev)
+{
+    if (atomic_mb_read(&ev->value) == EV_SET) {
+        /*
+         * If there was a concurrent reset (or even reset+wait),
+         * do nothing.  Otherwise change EV_SET->EV_FREE.
+         */
+        atomic_or(&ev->value, EV_FREE);
+    }
+}
+
+void qemu_event_wait(QemuEvent *ev)
+{
+    unsigned value;
+
+    value = atomic_mb_read(&ev->value);
+    if (value != EV_SET) {
+        if (value == EV_FREE) {
+            /*
+             * Leave the event reset and tell qemu_event_set that there
+             * are waiters.  No need to retry, because there cannot be
+             * a concurent busy->free transition.  After the CAS, the
+             * event will be either set or busy.
+             */
+            if (atomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) {
+                return;
+            }
+        }
+        futex_wait(ev, EV_BUSY);
+    }
+}
+
+
+void qemu_thread_create(QemuThread *thread,
+                       void *(*start_routine)(void*),
+                       void *arg, int mode)
+{
+    sigset_t set, oldset;
+    int err;
+    pthread_attr_t attr;
+
+    err = pthread_attr_init(&attr);
+    if (err) {
+        error_exit(err, __func__);
+    }
+    if (mode == QEMU_THREAD_DETACHED) {
+        err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+        if (err) {
+            error_exit(err, __func__);
+        }
+    }
+
+    /* Leave signal handling to the iothread.  */
+    sigfillset(&set);
+    pthread_sigmask(SIG_SETMASK, &set, &oldset);
+    err = pthread_create(&thread->thread, &attr, start_routine, arg);
+    if (err)
+        error_exit(err, __func__);
+
+    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+
+    pthread_attr_destroy(&attr);
+}
+
+void qemu_thread_get_self(QemuThread *thread)
+{
+    thread->thread = pthread_self();
+}
+
+bool qemu_thread_is_self(QemuThread *thread)
+{
+   return pthread_equal(pthread_self(), thread->thread);
+}
+
+void qemu_thread_exit(void *retval)
+{
+    pthread_exit(retval);
+}
+
+void *qemu_thread_join(QemuThread *thread)
+{
+    int err;
+    void *ret;
+
+    err = pthread_join(thread->thread, &ret);
+    if (err) {
+        error_exit(err, __func__);
+    }
+    return ret;
+}
diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
new file mode 100644
index 0000000..27a5217
--- /dev/null
+++ b/util/qemu-thread-win32.c
@@ -0,0 +1,385 @@
+/*
+ * Win32 implementation for mutex/cond/thread functions
+ *
+ * Copyright Red Hat, Inc. 2010
+ *
+ * Author:
+ *  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 "qemu-common.h"
+#include "qemu/thread.h"
+#include <process.h>
+#include <assert.h>
+#include <limits.h>
+
+static void error_exit(int err, const char *msg)
+{
+    char *pstr;
+
+    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+                  NULL, err, 0, (LPTSTR)&pstr, 2, NULL);
+    fprintf(stderr, "qemu: %s: %s\n", msg, pstr);
+    LocalFree(pstr);
+    abort();
+}
+
+void qemu_mutex_init(QemuMutex *mutex)
+{
+    mutex->owner = 0;
+    InitializeCriticalSection(&mutex->lock);
+}
+
+void qemu_mutex_destroy(QemuMutex *mutex)
+{
+    assert(mutex->owner == 0);
+    DeleteCriticalSection(&mutex->lock);
+}
+
+void qemu_mutex_lock(QemuMutex *mutex)
+{
+    EnterCriticalSection(&mutex->lock);
+
+    /* Win32 CRITICAL_SECTIONs are recursive.  Assert that we're not
+     * using them as such.
+     */
+    assert(mutex->owner == 0);
+    mutex->owner = GetCurrentThreadId();
+}
+
+int qemu_mutex_trylock(QemuMutex *mutex)
+{
+    int owned;
+
+    owned = TryEnterCriticalSection(&mutex->lock);
+    if (owned) {
+        assert(mutex->owner == 0);
+        mutex->owner = GetCurrentThreadId();
+    }
+    return !owned;
+}
+
+void qemu_mutex_unlock(QemuMutex *mutex)
+{
+    assert(mutex->owner == GetCurrentThreadId());
+    mutex->owner = 0;
+    LeaveCriticalSection(&mutex->lock);
+}
+
+void qemu_cond_init(QemuCond *cond)
+{
+    memset(cond, 0, sizeof(*cond));
+
+    cond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
+    if (!cond->sema) {
+        error_exit(GetLastError(), __func__);
+    }
+    cond->continue_event = CreateEvent(NULL,    /* security */
+                                       FALSE,   /* auto-reset */
+                                       FALSE,   /* not signaled */
+                                       NULL);   /* name */
+    if (!cond->continue_event) {
+        error_exit(GetLastError(), __func__);
+    }
+}
+
+void qemu_cond_destroy(QemuCond *cond)
+{
+    BOOL result;
+    result = CloseHandle(cond->continue_event);
+    if (!result) {
+        error_exit(GetLastError(), __func__);
+    }
+    cond->continue_event = 0;
+    result = CloseHandle(cond->sema);
+    if (!result) {
+        error_exit(GetLastError(), __func__);
+    }
+    cond->sema = 0;
+}
+
+void qemu_cond_signal(QemuCond *cond)
+{
+    DWORD result;
+
+    /*
+     * Signal only when there are waiters.  cond->waiters is
+     * incremented by pthread_cond_wait under the external lock,
+     * so we are safe about that.
+     */
+    if (cond->waiters == 0) {
+        return;
+    }
+
+    /*
+     * Waiting threads decrement it outside the external lock, but
+     * only if another thread is executing pthread_cond_broadcast and
+     * has the mutex.  So, it also cannot be decremented concurrently
+     * with this particular access.
+     */
+    cond->target = cond->waiters - 1;
+    result = SignalObjectAndWait(cond->sema, cond->continue_event,
+                                 INFINITE, FALSE);
+    if (result == WAIT_ABANDONED || result == WAIT_FAILED) {
+        error_exit(GetLastError(), __func__);
+    }
+}
+
+void qemu_cond_broadcast(QemuCond *cond)
+{
+    BOOLEAN result;
+    /*
+     * As in pthread_cond_signal, access to cond->waiters and
+     * cond->target is locked via the external mutex.
+     */
+    if (cond->waiters == 0) {
+        return;
+    }
+
+    cond->target = 0;
+    result = ReleaseSemaphore(cond->sema, cond->waiters, NULL);
+    if (!result) {
+        error_exit(GetLastError(), __func__);
+    }
+
+    /*
+     * At this point all waiters continue. Each one takes its
+     * slice of the semaphore. Now it's our turn to wait: Since
+     * the external mutex is held, no thread can leave cond_wait,
+     * yet. For this reason, we can be sure that no thread gets
+     * a chance to eat *more* than one slice. OTOH, it means
+     * that the last waiter must send us a wake-up.
+     */
+    WaitForSingleObject(cond->continue_event, INFINITE);
+}
+
+void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
+{
+    /*
+     * This access is protected under the mutex.
+     */
+    cond->waiters++;
+
+    /*
+     * Unlock external mutex and wait for signal.
+     * NOTE: we've held mutex locked long enough to increment
+     * waiters count above, so there's no problem with
+     * leaving mutex unlocked before we wait on semaphore.
+     */
+    qemu_mutex_unlock(mutex);
+    WaitForSingleObject(cond->sema, INFINITE);
+
+    /* Now waiters must rendez-vous with the signaling thread and
+     * let it continue.  For cond_broadcast this has heavy contention
+     * and triggers thundering herd.  So goes life.
+     *
+     * Decrease waiters count.  The mutex is not taken, so we have
+     * to do this atomically.
+     *
+     * All waiters contend for the mutex at the end of this function
+     * until the signaling thread relinquishes it.  To ensure
+     * each waiter consumes exactly one slice of the semaphore,
+     * the signaling thread stops until it is told by the last
+     * waiter that it can go on.
+     */
+    if (InterlockedDecrement(&cond->waiters) == cond->target) {
+        SetEvent(cond->continue_event);
+    }
+
+    qemu_mutex_lock(mutex);
+}
+
+void qemu_sem_init(QemuSemaphore *sem, int init)
+{
+    /* Manual reset.  */
+    sem->sema = CreateSemaphore(NULL, init, LONG_MAX, NULL);
+}
+
+void qemu_sem_destroy(QemuSemaphore *sem)
+{
+    CloseHandle(sem->sema);
+}
+
+void qemu_sem_post(QemuSemaphore *sem)
+{
+    ReleaseSemaphore(sem->sema, 1, NULL);
+}
+
+int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
+{
+    int rc = WaitForSingleObject(sem->sema, ms);
+    if (rc == WAIT_OBJECT_0) {
+        return 0;
+    }
+    if (rc != WAIT_TIMEOUT) {
+        error_exit(GetLastError(), __func__);
+    }
+    return -1;
+}
+
+void qemu_sem_wait(QemuSemaphore *sem)
+{
+    if (WaitForSingleObject(sem->sema, INFINITE) != WAIT_OBJECT_0) {
+        error_exit(GetLastError(), __func__);
+    }
+}
+
+void qemu_event_init(QemuEvent *ev, bool init)
+{
+    /* Manual reset.  */
+    ev->event = CreateEvent(NULL, TRUE, init, NULL);
+}
+
+void qemu_event_destroy(QemuEvent *ev)
+{
+    CloseHandle(ev->event);
+}
+
+void qemu_event_set(QemuEvent *ev)
+{
+    SetEvent(ev->event);
+}
+
+void qemu_event_reset(QemuEvent *ev)
+{
+    ResetEvent(ev->event);
+}
+
+void qemu_event_wait(QemuEvent *ev)
+{
+    WaitForSingleObject(ev->event, INFINITE);
+}
+
+struct QemuThreadData {
+    /* Passed to win32_start_routine.  */
+    void             *(*start_routine)(void *);
+    void             *arg;
+    short             mode;
+
+    /* Only used for joinable threads. */
+    bool              exited;
+    void             *ret;
+    CRITICAL_SECTION  cs;
+};
+
+static __thread QemuThreadData *qemu_thread_data;
+
+static unsigned __stdcall win32_start_routine(void *arg)
+{
+    QemuThreadData *data = (QemuThreadData *) arg;
+    void *(*start_routine)(void *) = data->start_routine;
+    void *thread_arg = data->arg;
+
+    if (data->mode == QEMU_THREAD_DETACHED) {
+        g_free(data);
+        data = NULL;
+    }
+    qemu_thread_data = data;
+    qemu_thread_exit(start_routine(thread_arg));
+    abort();
+}
+
+void qemu_thread_exit(void *arg)
+{
+    QemuThreadData *data = qemu_thread_data;
+
+    if (data) {
+        assert(data->mode != QEMU_THREAD_DETACHED);
+        data->ret = arg;
+        EnterCriticalSection(&data->cs);
+        data->exited = true;
+        LeaveCriticalSection(&data->cs);
+    }
+    _endthreadex(0);
+}
+
+void *qemu_thread_join(QemuThread *thread)
+{
+    QemuThreadData *data;
+    void *ret;
+    HANDLE handle;
+
+    data = thread->data;
+    if (!data) {
+        return NULL;
+    }
+    /*
+     * Because multiple copies of the QemuThread can exist via
+     * qemu_thread_get_self, we need to store a value that cannot
+     * leak there.  The simplest, non racy way is to store the TID,
+     * discard the handle that _beginthreadex gives back, and
+     * get another copy of the handle here.
+     */
+    handle = qemu_thread_get_handle(thread);
+    if (handle) {
+        WaitForSingleObject(handle, INFINITE);
+        CloseHandle(handle);
+    }
+    ret = data->ret;
+    assert(data->mode != QEMU_THREAD_DETACHED);
+    DeleteCriticalSection(&data->cs);
+    g_free(data);
+    return ret;
+}
+
+void qemu_thread_create(QemuThread *thread,
+                       void *(*start_routine)(void *),
+                       void *arg, int mode)
+{
+    HANDLE hThread;
+    struct QemuThreadData *data;
+
+    data = g_malloc(sizeof *data);
+    data->start_routine = start_routine;
+    data->arg = arg;
+    data->mode = mode;
+    data->exited = false;
+
+    if (data->mode != QEMU_THREAD_DETACHED) {
+        InitializeCriticalSection(&data->cs);
+    }
+
+    hThread = (HANDLE) _beginthreadex(NULL, 0, win32_start_routine,
+                                      data, 0, &thread->tid);
+    if (!hThread) {
+        error_exit(GetLastError(), __func__);
+    }
+    CloseHandle(hThread);
+    thread->data = (mode == QEMU_THREAD_DETACHED) ? NULL : data;
+}
+
+void qemu_thread_get_self(QemuThread *thread)
+{
+    thread->data = qemu_thread_data;
+    thread->tid = GetCurrentThreadId();
+}
+
+HANDLE qemu_thread_get_handle(QemuThread *thread)
+{
+    QemuThreadData *data;
+    HANDLE handle;
+
+    data = thread->data;
+    if (!data) {
+        return NULL;
+    }
+
+    assert(data->mode != QEMU_THREAD_DETACHED);
+    EnterCriticalSection(&data->cs);
+    if (!data->exited) {
+        handle = OpenThread(SYNCHRONIZE | THREAD_SUSPEND_RESUME, FALSE,
+                            thread->tid);
+    } else {
+        handle = NULL;
+    }
+    LeaveCriticalSection(&data->cs);
+    return handle;
+}
+
+bool qemu_thread_is_self(QemuThread *thread)
+{
+    return GetCurrentThreadId() == thread->tid;
+}
diff --git a/util/qemu-thread.c b/util/qemu-thread.c
deleted file mode 100644
index 47bd62e..0000000
--- a/util/qemu-thread.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Wrappers around mutex/cond/thread functions
- *
- * Copyright Red Hat, Inc. 2009
- *
- * Author:
- *  Marcelo Tosatti <mtosatti@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 <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <time.h>
-#include <signal.h>
-#include <stdint.h>
-#include <string.h>
-#include "qemu/thread.h"
-
-static void error_exit(int err, const char *msg)
-{
-    fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
-    exit(1);
-}
-
-void qemu_mutex_init(QemuMutex *mutex)
-{
-    int err;
-
-    err = pthread_mutex_init(&mutex->lock, NULL);
-    if (err)
-        error_exit(err, __func__);
-}
-
-void qemu_mutex_destroy(QemuMutex *mutex)
-{
-    int err;
-
-    err = pthread_mutex_destroy(&mutex->lock);
-    if (err)
-        error_exit(err, __func__);
-}
-
-void qemu_mutex_lock(QemuMutex *mutex)
-{
-    int err;
-
-    err = pthread_mutex_lock(&mutex->lock);
-    if (err)
-        error_exit(err, __func__);
-}
-
-int qemu_mutex_trylock(QemuMutex *mutex)
-{
-    return pthread_mutex_trylock(&mutex->lock);
-}
-
-static void timespec_add_ms(struct timespec *ts, uint64_t msecs)
-{
-    ts->tv_sec = ts->tv_sec + (long)(msecs / 1000);
-    ts->tv_nsec = (ts->tv_nsec + ((long)msecs % 1000) * 1000000);
-    if (ts->tv_nsec >= 1000000000) {
-        ts->tv_nsec -= 1000000000;
-        ts->tv_sec++;
-    }
-}
-
-int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs)
-{
-    int err;
-    struct timespec ts;
-
-    clock_gettime(CLOCK_REALTIME, &ts);
-    timespec_add_ms(&ts, msecs);
-
-    err = pthread_mutex_timedlock(&mutex->lock, &ts);
-    if (err && err != ETIMEDOUT)
-        error_exit(err, __func__);
-    return err;
-}
-
-void qemu_mutex_unlock(QemuMutex *mutex)
-{
-    int err;
-
-    err = pthread_mutex_unlock(&mutex->lock);
-    if (err)
-        error_exit(err, __func__);
-}
-
-void qemu_cond_init(QemuCond *cond)
-{
-    int err;
-
-    err = pthread_cond_init(&cond->cond, NULL);
-    if (err)
-        error_exit(err, __func__);
-}
-
-void qemu_cond_destroy(QemuCond *cond)
-{
-    int err;
-
-    err = pthread_cond_destroy(&cond->cond);
-    if (err)
-        error_exit(err, __func__);
-}
-
-void qemu_cond_signal(QemuCond *cond)
-{
-    int err;
-
-    err = pthread_cond_signal(&cond->cond);
-    if (err)
-        error_exit(err, __func__);
-}
-
-void qemu_cond_broadcast(QemuCond *cond)
-{
-    int err;
-
-    err = pthread_cond_broadcast(&cond->cond);
-    if (err)
-        error_exit(err, __func__);
-}
-
-void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
-{
-    int err;
-
-    err = pthread_cond_wait(&cond->cond, &mutex->lock);
-    if (err)
-        error_exit(err, __func__);
-}
-
-int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs)
-{
-    struct timespec ts;
-    int err;
-
-    clock_gettime(CLOCK_REALTIME, &ts);
-    timespec_add_ms(&ts, msecs);
-
-    err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts);
-    if (err && err != ETIMEDOUT)
-        error_exit(err, __func__);
-    return err;
-}
-
-void qemu_thread_create(QemuThread *thread,
-                       void *(*start_routine)(void*),
-                       void *arg)
-{
-    int err;
-
-    /* Leave signal handling to the iothread.  */
-    sigset_t set, oldset;
-
-    sigfillset(&set);
-    pthread_sigmask(SIG_SETMASK, &set, &oldset);
-    err = pthread_create(&thread->thread, NULL, start_routine, arg);
-    if (err)
-        error_exit(err, __func__);
-
-    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
-}
-
-void qemu_thread_signal(QemuThread *thread, int sig)
-{
-    int err;
-
-    err = pthread_kill(thread->thread, sig);
-    if (err)
-        error_exit(err, __func__);
-}
-
-void qemu_thread_self(QemuThread *thread)
-{
-    thread->thread = pthread_self();
-}
-
-int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2)
-{
-   return pthread_equal(thread1->thread, thread2->thread);
-}
-
-void qemu_thread_exit(void *retval)
-{
-    pthread_exit(retval);
-}
diff --git a/qemu-timer-common.c b/util/qemu-timer-common.c
similarity index 100%
rename from qemu-timer-common.c
rename to util/qemu-timer-common.c
diff --git a/util/unicode.c b/util/unicode.c
new file mode 100644
index 0000000..d1c8658
--- /dev/null
+++ b/util/unicode.c
@@ -0,0 +1,100 @@
+/*
+ * Dealing with Unicode
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * Authors:
+ *  Markus Armbruster <armbru@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 "qemu-common.h"
+
+/**
+ * mod_utf8_codepoint:
+ * @s: string encoded in modified UTF-8
+ * @n: maximum number of bytes to read from @s, if less than 6
+ * @end: set to end of sequence on return
+ *
+ * Convert the modified UTF-8 sequence at the start of @s.  Modified
+ * UTF-8 is exactly like UTF-8, except U+0000 is encoded as
+ * "\xC0\x80".
+ *
+ * If @n is zero or @s points to a zero byte, the sequence is invalid,
+ * and @end is set to @s.
+ *
+ * If @s points to an impossible byte (0xFE or 0xFF) or a continuation
+ * byte, the sequence is invalid, and @end is set to @s + 1
+ *
+ * Else, the first byte determines how many continuation bytes are
+ * expected.  If there are fewer, the sequence is invalid, and @end is
+ * set to @s + 1 + actual number of continuation bytes.  Else, the
+ * sequence is well-formed, and @end is set to @s + 1 + expected
+ * number of continuation bytes.
+ *
+ * A well-formed sequence is valid unless it encodes a codepoint
+ * outside the Unicode range U+0000..U+10FFFF, one of Unicode's 66
+ * noncharacters, a surrogate codepoint, or is overlong.  Except the
+ * overlong sequence "\xC0\x80" is valid.
+ *
+ * Conversion succeeds if and only if the sequence is valid.
+ *
+ * Returns: the Unicode codepoint on success, -1 on failure.
+ */
+int mod_utf8_codepoint(const char *s, size_t n, char **end)
+{
+    static int min_cp[5] = { 0x80, 0x800, 0x10000, 0x200000, 0x4000000 };
+    const unsigned char *p;
+    unsigned byte, mask, len, i;
+    int cp;
+
+    if (n == 0 || *s == 0) {
+        /* empty sequence */
+        *end = (char *)s;
+        return -1;
+    }
+
+    p = (const unsigned char *)s;
+    byte = *p++;
+    if (byte < 0x80) {
+        cp = byte;              /* one byte sequence */
+    } else if (byte >= 0xFE) {
+        cp = -1;                /* impossible bytes 0xFE, 0xFF */
+    } else if ((byte & 0x40) == 0) {
+        cp = -1;                /* unexpected continuation byte */
+    } else {
+        /* multi-byte sequence */
+        len = 0;
+        for (mask = 0x80; byte & mask; mask >>= 1) {
+            len++;
+        }
+        assert(len > 1 && len < 7);
+        cp = byte & (mask - 1);
+        for (i = 1; i < len; i++) {
+            byte = i < n ? *p : 0;
+            if ((byte & 0xC0) != 0x80) {
+                cp = -1;        /* continuation byte missing */
+                goto out;
+            }
+            p++;
+            cp <<= 6;
+            cp |= byte & 0x3F;
+        }
+        if (cp > 0x10FFFF) {
+            cp = -1;            /* beyond Unicode range */
+        } else if ((cp >= 0xFDD0 && cp <= 0xFDEF)
+                   || (cp & 0xFFFE) == 0xFFFE) {
+            cp = -1;            /* noncharacter */
+        } else if (cp >= 0xD800 && cp <= 0xDFFF) {
+            cp = -1;            /* surrogate code point */
+        } else if (cp < min_cp[len - 2] && !(cp == 0 && len == 2)) {
+            cp = -1;            /* overlong, not \xC0\x80 */
+        }
+    }
+
+out:
+    *end = (char *)p;
+    return cp;
+}
diff --git a/util/yield-android.c b/util/yield-android.c
new file mode 100644
index 0000000..b553ab9
--- /dev/null
+++ b/util/yield-android.c
@@ -0,0 +1,20 @@
+#include <errno.h>
+#include <stddef.h>
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/select.h>
+#endif
+
+// Wait until file descriptor |fd| becomes readable.
+void yield_until_fd_readable(int fd) {
+    for (;;) {
+       fd_set read_fds;
+       FD_ZERO(&read_fds);
+       FD_SET(fd, &read_fds);
+       int ret = select(fd + 1, &read_fds, NULL, NULL, NULL);
+       if (ret == 1 || (ret < 0 && errno != -EINTR))
+           return;
+    }
+}
+
diff --git a/vl-android.c b/vl-android.c
index fdc2508..5fab2e8 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -41,6 +41,7 @@
 #include "ui/console.h"
 #include "sysemu/sysemu.h"
 #include "exec/gdbstub.h"
+#include "qemu/log.h"
 #include "qemu/timer.h"
 #include "sysemu/char.h"
 #include "sysemu/blockdev.h"
@@ -49,6 +50,7 @@
 #include "migration/qemu-file.h"
 #include "android/android.h"
 #include "android/charpipe.h"
+#include "android/log-rotate.h"
 #include "modem_driver.h"
 #include "android/gps.h"
 #include "android/hw-kmsg.h"
@@ -225,10 +227,6 @@
 
 #include "disas/disas.h"
 
-#ifdef CONFIG_TRACE
-#include "android/trace.h"
-#endif
-
 #include "qemu/sockets.h"
 
 #if defined(CONFIG_SLIRP)
@@ -402,7 +400,6 @@
 
 const char* dns_log_filename = NULL;
 const char* drop_log_filename = NULL;
-static int rotate_logs_requested = 0;
 
 const char* savevm_on_exit = NULL;
 
@@ -510,52 +507,6 @@
 #endif
 }
 
-/*
- * Sets a flag (rotate_logs_requested) to clear both the DNS and the
- * drop logs upon receiving a SIGUSR1 signal. We need to clear the logs
- * between the tasks that do not require restarting Qemu.
- */
-void rotate_qemu_logs_handler(int signum) {
-  rotate_logs_requested = 1;
-}
-
-/*
- * Resets the rotate_log_requested_flag. Normally called after qemu
- * logs has been rotated.
- */
-void reset_rotate_qemu_logs_request(void) {
-  rotate_logs_requested = 0;
-}
-
-/*
- * Clears the passed qemu log when the rotate_logs_requested
- * is set. We need to clear the logs between the tasks that do not
- * require restarting Qemu.
- */
-FILE* rotate_qemu_log(FILE* old_log_fd, const char* filename) {
-  FILE* new_log_fd = NULL;
-  if (old_log_fd) {
-    if (fclose(old_log_fd) == -1) {
-      fprintf(stderr, "Cannot close old_log fd\n");
-      exit(errno);
-    }
-  }
-
-  if (!filename) {
-    fprintf(stderr, "The log filename to be rotated is not provided");
-    exit(-1);
-  }
-
-  new_log_fd = fopen(filename , "wb+");
-  if (new_log_fd == NULL) {
-    fprintf(stderr, "Cannot open the log file: %s for write.\n",
-            filename);
-    exit(1);
-  }
-
-  return new_log_fd;
-}
-
 /***************/
 /* ballooning */
 
@@ -618,62 +569,6 @@
     return seconds - time(NULL);
 }
 
-
-#ifdef CONFIG_TRACE
-int tbflush_requested;
-static int exit_requested;
-
-void start_tracing()
-{
-  if (trace_filename == NULL)
-    return;
-  if (!tracing) {
-    fprintf(stderr,"-- start tracing --\n");
-    start_time = Now();
-  }
-  tracing = 1;
-  tbflush_requested = 1;
-  qemu_notify_event();
-}
-
-void stop_tracing()
-{
-  if (trace_filename == NULL)
-    return;
-  if (tracing) {
-    end_time = Now();
-    elapsed_usecs += end_time - start_time;
-    fprintf(stderr,"-- stop tracing --\n");
-  }
-  tracing = 0;
-  tbflush_requested = 1;
-  qemu_notify_event();
-}
-
-#ifndef _WIN32
-/* This is the handler for the SIGUSR1 and SIGUSR2 signals.
- * SIGUSR1 turns tracing on.  SIGUSR2 turns tracing off.
- */
-void sigusr_handler(int sig)
-{
-  if (sig == SIGUSR1)
-    start_tracing();
-  else
-    stop_tracing();
-}
-#endif
-
-/* This is the handler to catch control-C so that we can exit cleanly.
- * This is needed when tracing to flush the buffers to disk.
- */
-void sigint_handler(int sig)
-{
-  exit_requested = 1;
-  qemu_notify_event();
-}
-#endif /* CONFIG_TRACE */
-
-
 /***********************************************************/
 /* Bluetooth support */
 static int nb_hcis;
@@ -1843,14 +1738,14 @@
     return r;
 }
 
-static int qemu_debug_requested(void)
+int qemu_debug_requested(void)
 {
     int r = debug_requested;
     debug_requested = 0;
     return r;
 }
 
-static int qemu_vmstop_requested(void)
+int qemu_vmstop_requested(void)
 {
     int r = vmstop_requested;
     vmstop_requested = 0;
@@ -1912,63 +1807,7 @@
     qemu_notify_event();
 }
 
-#ifdef CONFIG_IOTHREAD
-static void qemu_system_vmstop_request(int reason)
-{
-    vmstop_requested = reason;
-    qemu_notify_event();
-}
-#endif
-
-void main_loop_wait(int timeout)
-{
-    fd_set rfds, wfds, xfds;
-    int ret, nfds;
-    struct timeval tv;
-
-    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;
-    FD_ZERO(&rfds);
-    FD_ZERO(&wfds);
-    FD_ZERO(&xfds);
-    qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
-    if (slirp_is_inited()) {
-        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
-    }
-
-    qemu_mutex_unlock_iothread();
-    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
-    qemu_mutex_lock_iothread();
-    qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
-    if (slirp_is_inited()) {
-        if (ret < 0) {
-            FD_ZERO(&rfds);
-            FD_ZERO(&wfds);
-            FD_ZERO(&xfds);
-        }
-        slirp_select_poll(&rfds, &wfds, &xfds);
-    }
-    charpipe_poll();
-
-    qemu_run_all_timers();
-
-    /* Check bottom-halves last in case any of the earlier events triggered
-       them.  */
-    qemu_bh_poll();
-
-}
-
-static int vm_can_run(void)
+int vm_can_run(void)
 {
     if (powerdown_requested)
         return 0;
@@ -1981,78 +1820,6 @@
     return 1;
 }
 
-static void main_loop(void)
-{
-    int r;
-
-#ifdef CONFIG_IOTHREAD
-    qemu_system_ready = 1;
-    qemu_cond_broadcast(&qemu_system_cond);
-#endif
-
-#ifdef CONFIG_HAX
-    if (hax_enabled())
-        hax_sync_vcpus();
-#endif
-
-    for (;;) {
-        do {
-#ifdef CONFIG_PROFILER
-            int64_t ti;
-#endif
-#ifndef CONFIG_IOTHREAD
-            tcg_cpu_exec();
-#endif
-#ifdef CONFIG_PROFILER
-            ti = profile_getclock();
-#endif
-            main_loop_wait(qemu_calculate_timeout());
-#ifdef CONFIG_PROFILER
-            dev_time += profile_getclock() - ti;
-#endif
-
-            if (rotate_logs_requested) {
-                FILE* new_dns_log_fd = rotate_qemu_log(get_slirp_dns_log_fd(),
-                                                        dns_log_filename);
-                FILE* new_drop_log_fd = rotate_qemu_log(get_slirp_drop_log_fd(),
-                                                         drop_log_filename);
-                slirp_dns_log_fd(new_dns_log_fd);
-                slirp_drop_log_fd(new_drop_log_fd);
-                reset_rotate_qemu_logs_request();
-            }
-
-        } while (vm_can_run());
-
-        if (qemu_debug_requested())
-            vm_stop(EXCP_DEBUG);
-        if (qemu_shutdown_requested()) {
-            if (no_shutdown) {
-                vm_stop(0);
-                no_shutdown = 0;
-            } else {
-                if (savevm_on_exit != NULL) {
-                  /* Prior to saving VM to the snapshot file, save HW config
-                   * settings for that VM, so we can match them when VM gets
-                   * loaded from the snapshot. */
-                  snaphost_save_config(savevm_on_exit);
-                  do_savevm(cur_mon, savevm_on_exit);
-                }
-                break;
-            }
-        }
-        if (qemu_reset_requested()) {
-            pause_all_vcpus();
-            qemu_system_reset();
-            resume_all_vcpus();
-        }
-        if (qemu_powerdown_requested())
-            qemu_system_powerdown();
-        if ((r = qemu_vmstop_requested()))
-            vm_stop(r);
-    }
-    pause_all_vcpus();
-}
-
 void version(void)
 {
     printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
@@ -2314,24 +2081,6 @@
     return 0;
 }
 
-#ifndef _WIN32
-/*
- * Initializes the SIGUSR1 signal handler to clear Qemu logs.
- */
-void init_qemu_clear_logs_sig() {
-  struct sigaction act;
-  sigfillset(&act.sa_mask);
-  act.sa_flags = 0;
-  act.sa_handler = rotate_qemu_logs_handler;
-  if (sigaction(SIGUSR1, &act, NULL) == -1) {
-    fprintf(stderr, "Failed to setup SIGUSR1 handler to clear Qemu logs\n");
-    exit(-1);
-  }
-}
-#endif
-
-
-
 /* parses a null-terminated string specifying a network port (e.g., "80") or
  * port range (e.g., "[6666-7000]"). In case of a single port, lport and hport
  * are the same. Returns 0 on success, -1 on error. */
@@ -2556,7 +2305,9 @@
     int tb_size;
     const char *pid_file = NULL;
     const char *incoming = NULL;
-    CPUState *env;
+    const char* log_mask = NULL;
+    const char* log_file = NULL;
+    CPUOldState *env;
     int show_vnc_port = 0;
     IniFile*  hw_ini = NULL;
     STRALLOC_DEFINE(kernel_params);
@@ -2571,7 +2322,7 @@
 
     init_clocks();
 
-    qemu_cache_utils_init(envp);
+    qemu_cache_utils_init();
 
     QLIST_INIT (&vm_change_state_head);
     os_setup_early_signal_handling();
@@ -2907,11 +2658,7 @@
                 }
 
                 /* On 32-bit hosts, QEMU is limited by virtual address space */
-                if (value > (2047 << 20)
-#ifndef CONFIG_KQEMU
-                    && HOST_LONG_BITS == 32
-#endif
-                    ) {
+                if (value > (2047 << 20) && HOST_LONG_BITS == 32) {
                     PANIC("qemu: at most 2047 MB RAM can be simulated");
                 }
                 if (value != (uint64_t)(ram_addr_t)value) {
@@ -2921,20 +2668,7 @@
                 break;
             }
             case QEMU_OPTION_d:
-                {
-                    int mask;
-                    const CPULogItem *item;
-
-                    mask = cpu_str_to_log_mask(optarg);
-                    if (!mask) {
-                        printf("Log items (comma separated):\n");
-                        for(item = cpu_log_items; item->mask != 0; item++) {
-                            printf("%-10s %s\n", item->name, item->help);
-                        }
-                        PANIC("Invalid parameter -d=%s", optarg);
-                    }
-                    cpu_set_log(mask);
-                }
+                log_mask = optarg;
                 break;
             case QEMU_OPTION_s:
                 gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
@@ -3327,38 +3061,6 @@
             case QEMU_OPTION_mic:
                 audio_input_source = (char*)optarg;
                 break;
-#ifdef CONFIG_TRACE
-            case QEMU_OPTION_trace:
-                trace_filename = optarg;
-                tracing = 1;
-                break;
-#if 0
-            case QEMU_OPTION_trace_miss:
-                trace_cache_miss = 1;
-                break;
-            case QEMU_OPTION_trace_addr:
-                trace_all_addr = 1;
-                break;
-#endif
-            case QEMU_OPTION_tracing:
-                if (strcmp(optarg, "off") == 0)
-                    tracing = 0;
-                else if (strcmp(optarg, "on") == 0 && trace_filename)
-                    tracing = 1;
-                else {
-                    PANIC("Unexpected option to -tracing ('%s')",
-                            optarg);
-                }
-                break;
-#if 0
-            case QEMU_OPTION_dcache_load_miss:
-                dcache_load_miss_penalty = atoi(optarg);
-                break;
-            case QEMU_OPTION_dcache_store_miss:
-                dcache_store_miss_penalty = atoi(optarg);
-                break;
-#endif
-#endif
 #ifdef CONFIG_NAND
             case QEMU_OPTION_nand:
                 nand_add_dev(optarg);
@@ -3944,19 +3646,31 @@
         exit(1);
     }
 
+    /* Open the logfile at this point, if necessary. We can't open the logfile
+     * when encountering either of the logging options (-d or -D) because the
+     * other one may be encountered later on the command line, changing the
+     * location or level of logging.
+     */
+    if (log_mask) {
+        int mask;
+        if (log_file) {
+            qemu_set_log_filename(log_file);
+        }
+
+        mask = qemu_str_to_log_mask(log_mask);
+        if (!mask) {
+            qemu_print_log_usage(stdout);
+            exit(1);
+        }
+        qemu_set_log(mask);
+    }
+  
 #if defined(CONFIG_KVM)
     if (kvm_allowed < 0) {
         kvm_allowed = kvm_check_allowed();
     }
 #endif
 
-#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
-    if (kvm_allowed && kqemu_allowed) {
-        PANIC(
-                "You can not enable both KVM and kqemu at the same time");
-    }
-#endif
-
     machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
     if (smp_cpus > machine->max_cpus) {
         PANIC("Number of SMP cpus requested (%d), exceeds max cpus "
@@ -3973,10 +3687,6 @@
            monitor_device = "stdio";
     }
 
-#ifdef CONFIG_KQEMU
-    if (smp_cpus > 1)
-        kqemu_allowed = 0;
-#endif
     if (qemu_init_main_loop()) {
         PANIC("qemu_init_main_loop failed");
     }
@@ -4098,20 +3808,8 @@
         }
     }
 
-#ifdef CONFIG_KQEMU
-    /* FIXME: This is a nasty hack because kqemu can't cope with dynamic
-       guest ram allocation.  It needs to go away.  */
-    if (kqemu_allowed) {
-        kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
-        kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
-        if (!kqemu_phys_ram_base) {
-            PANIC("Could not allocate physical memory");
-        }
-    }
-#endif
-
 #ifndef _WIN32
-    init_qemu_clear_logs_sig();
+    qemu_log_rotation_init();
 #endif
 
     /* init the dynamic translator */
@@ -4266,13 +3964,6 @@
     module_call_init(MODULE_INIT_DEVICE);
 
 
-#ifdef CONFIG_TRACE
-    if (trace_filename) {
-        trace_init(trace_filename);
-        fprintf(stderr, "-- When done tracing, exit the emulator. --\n");
-    }
-#endif
-
     /* Check the CPU Architecture value */
 #if defined(TARGET_ARM)
     if (strcmp(android_hw->hw_cpu_arch,"arm") != 0) {
@@ -4352,7 +4043,7 @@
 
     current_machine = machine;
 
-    /* Set KVM's vcpu state to qemu's initial CPUState. */
+    /* Set KVM's vcpu state to qemu's initial CPUOldState. */
     if (kvm_enabled()) {
         int ret;
 
diff --git a/vl.c b/vl.c
index 4284222..6d09b9a 100644
--- a/vl.c
+++ b/vl.c
@@ -1711,14 +1711,6 @@
     qemu_notify_event();
 }
 
-#ifdef CONFIG_IOTHREAD
-static void qemu_system_vmstop_request(int reason)
-{
-    vmstop_requested = reason;
-    qemu_notify_event();
-}
-#endif
-
 void main_loop_wait(int timeout)
 {
     fd_set rfds, wfds, xfds;
@@ -1783,19 +1775,12 @@
 {
     int r;
 
-#ifdef CONFIG_IOTHREAD
-    qemu_system_ready = 1;
-    qemu_cond_broadcast(&qemu_system_cond);
-#endif
-
     for (;;) {
         do {
 #ifdef CONFIG_PROFILER
             int64_t ti;
 #endif
-#ifndef CONFIG_IOTHREAD
             tcg_cpu_exec();
-#endif
 #ifdef CONFIG_PROFILER
             ti = profile_getclock();
 #endif
@@ -2093,7 +2078,7 @@
     int tb_size;
     const char *pid_file = NULL;
     const char *incoming = NULL;
-    CPUState *env;
+    CPUOldState *env;
     int show_vnc_port = 0;
 
     init_clocks();
@@ -2600,20 +2585,9 @@
                 }
                 break;
 #endif
-#ifdef CONFIG_KQEMU
-            case QEMU_OPTION_no_kqemu:
-                kqemu_allowed = 0;
-                break;
-            case QEMU_OPTION_kernel_kqemu:
-                kqemu_allowed = 2;
-                break;
-#endif
 #ifdef CONFIG_KVM
             case QEMU_OPTION_enable_kvm:
                 kvm_allowed = 1;
-#ifdef CONFIG_KQEMU
-                kqemu_allowed = 0;
-#endif
                 break;
 #endif
             case QEMU_OPTION_usb:
@@ -2779,14 +2753,6 @@
         exit(1);
     }
 
-#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
-    if (kvm_allowed && kqemu_allowed) {
-        fprintf(stderr,
-                "You can not enable both KVM and kqemu at the same time\n");
-        exit(1);
-    }
-#endif
-
     machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
     if (smp_cpus > machine->max_cpus) {
         fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
@@ -2804,10 +2770,6 @@
            monitor_device = "stdio";
     }
 
-#ifdef CONFIG_KQEMU
-    if (smp_cpus > 1)
-        kqemu_allowed = 0;
-#endif
     if (qemu_init_main_loop()) {
         fprintf(stderr, "qemu_init_main_loop failed\n");
         exit(1);
@@ -2899,19 +2861,6 @@
     if (ram_size == 0)
         ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
 
-#ifdef CONFIG_KQEMU
-    /* FIXME: This is a nasty hack because kqemu can't cope with dynamic
-       guest ram allocation.  It needs to go away.  */
-    if (kqemu_allowed) {
-        kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
-        kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
-        if (!kqemu_phys_ram_base) {
-            fprintf(stderr, "Could not allocate physical memory\n");
-            exit(1);
-        }
-    }
-#endif
-
     /* init the dynamic translator */
     cpu_exec_init_all(tb_size * 1024 * 1024);
 
@@ -3078,7 +3027,7 @@
 
     current_machine = machine;
 
-    /* Set KVM's vcpu state to qemu's initial CPUState. */
+    /* Set KVM's vcpu state to qemu's initial CPUOldState. */
     if (kvm_enabled()) {
         int ret;