summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS6
-rw-r--r--Makefile9
-rw-r--r--accel/tcg/user-exec-stub.c2
-rw-r--r--arch_init.c11
-rw-r--r--chardev/char-socket.c16
-rwxr-xr-xconfigure10
-rw-r--r--cpus-common.c2
-rw-r--r--docs/interop/firmware.json2
-rw-r--r--exec.c2
-rw-r--r--hw/acpi/cpu_hotplug.c2
-rw-r--r--hw/acpi/ich9.c2
-rw-r--r--hw/acpi/piix4.c2
-rw-r--r--hw/arm/smmu-common.c2
-rw-r--r--hw/arm/virt-acpi-build.c2
-rw-r--r--hw/core/Makefile.objs1
-rw-r--r--hw/core/cpu.c (renamed from qom/cpu.c)2
-rw-r--r--hw/core/generic-loader.c2
-rw-r--r--hw/core/machine-qmp-cmds.c10
-rw-r--r--hw/core/null-machine.c2
-rw-r--r--hw/core/numa.c2
-rw-r--r--hw/cpu/a9mpcore.c2
-rw-r--r--hw/cpu/cluster.c2
-rw-r--r--hw/display/ati.c112
-rw-r--r--hw/display/ati_dbg.c10
-rw-r--r--hw/display/ati_int.h5
-rw-r--r--hw/display/ati_regs.h17
-rw-r--r--hw/i386/acpi-build.c2
-rw-r--r--hw/i386/pc.c2
-rw-r--r--hw/intc/arm_gic.c2
-rw-r--r--hw/intc/arm_gicv3_common.c2
-rw-r--r--hw/isa/lpc_ich9.c2
-rw-r--r--hw/misc/imx6_src.c2
-rw-r--r--hw/ppc/spapr.c2
-rw-r--r--hw/timer/a9gtimer.c2
-rw-r--r--hw/timer/arm_mptimer.c2
-rw-r--r--hw/usb/hcd-ehci.c3
-rw-r--r--hw/usb/hcd-xhci.c3
-rw-r--r--hw/usb/redirect.c74
-rw-r--r--include/exec/cpu-all.h2
-rw-r--r--include/exec/cpu-defs.h2
-rw-r--r--include/exec/log.h2
-rw-r--r--include/hw/boards.h2
-rw-r--r--include/hw/core/cpu.h (renamed from include/qom/cpu.h)0
-rw-r--r--include/hw/ppc/openpic.h2
-rw-r--r--include/qemu/module.h2
-rw-r--r--include/sysemu/hw_accel.h2
-rw-r--r--include/sysemu/kvm.h2
-rw-r--r--io/task.c1
-rw-r--r--memory.c99
-rw-r--r--monitor/hmp-cmds.c19
-rw-r--r--monitor/qmp.c2
-rw-r--r--qapi/common.json25
-rw-r--r--qapi/machine.json48
-rw-r--r--qapi/misc.json23
-rw-r--r--qapi/ui.json3
-rw-r--r--qdev-monitor.c18
-rw-r--r--qemu-options.hx7
-rw-r--r--qom/Makefile.objs1
-rw-r--r--qtest.c9
-rw-r--r--scripts/minikconf.py4
-rw-r--r--target/alpha/cpu-qom.h2
-rw-r--r--target/arm/cpu-qom.h2
-rw-r--r--target/cris/cpu-qom.h2
-rw-r--r--target/hppa/cpu-qom.h2
-rw-r--r--target/hppa/int_helper.c2
-rw-r--r--target/hppa/mem_helper.c2
-rw-r--r--target/i386/cpu-qom.h2
-rw-r--r--target/lm32/cpu-qom.h2
-rw-r--r--target/m68k/cpu-qom.h2
-rw-r--r--target/microblaze/cpu-qom.h2
-rw-r--r--target/mips/cpu-qom.h2
-rw-r--r--target/moxie/cpu.h2
-rw-r--r--target/nios2/cpu.h2
-rw-r--r--target/openrisc/cpu.h2
-rw-r--r--target/ppc/cpu-qom.h2
-rw-r--r--target/riscv/cpu.h2
-rw-r--r--target/s390x/cpu-qom.h2
-rw-r--r--target/s390x/cpu_models.h2
-rw-r--r--target/sh4/cpu-qom.h2
-rw-r--r--target/sparc/cpu-qom.h2
-rw-r--r--target/tilegx/cpu.h2
-rw-r--r--target/tricore/cpu-qom.h2
-rw-r--r--target/tricore/helper.h1
-rw-r--r--target/tricore/op_helper.c7
-rw-r--r--target/tricore/translate.c577
-rw-r--r--target/unicore32/cpu-qom.h2
-rw-r--r--target/xtensa/cpu-qom.h2
-rw-r--r--tests/Makefile.include1
-rw-r--r--tests/libqtest.c6
-rw-r--r--tests/libqtest.h2
-rw-r--r--tests/modules-test.c71
-rw-r--r--trace-events2
-rw-r--r--trace/control-vcpu.h2
-rw-r--r--ui/cocoa.m2
-rw-r--r--ui/curses.c2
-rw-r--r--ui/input-linux.c4
-rw-r--r--util/module.c17
97 files changed, 837 insertions, 515 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 743a92666a..ef6c01084b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1274,6 +1274,7 @@ Machine core
 M: Eduardo Habkost <ehabkost@redhat.com>
 M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
 S: Supported
+F: hw/core/cpu.c
 F: hw/core/machine-qmp-cmds.c
 F: hw/core/machine.c
 F: hw/core/null-machine.c
@@ -1281,10 +1282,9 @@ F: hw/core/numa.c
 F: hw/cpu/cluster.c
 F: qapi/machine.json
 F: qapi/machine-target.json
-F: qom/cpu.c
 F: include/hw/boards.h
+F: include/hw/core/cpu.h
 F: include/hw/cpu/cluster.h
-F: include/qom/cpu.h
 F: include/sysemu/numa.h
 T: git https://github.com/ehabkost/qemu.git machine-next
 
@@ -2048,12 +2048,10 @@ F: hw/core/qdev*
 F: include/hw/qdev*
 F: include/monitor/qdev.h
 F: include/qom/
-X: include/qom/cpu.h
 F: qapi/qom.json
 F: qapi/qdev.json
 F: qdev-monitor.c
 F: qom/
-X: qom/cpu.c
 F: tests/check-qom-interface.c
 F: tests/check-qom-proplist.c
 F: tests/test-qdev-global-props.c
diff --git a/Makefile b/Makefile
index 85862fb81a..574fedea6b 100644
--- a/Makefile
+++ b/Makefile
@@ -84,8 +84,7 @@ endif
 
 include $(SRC_PATH)/rules.mak
 
-# notempy and lor are defined in rules.mak
-CONFIG_TOOLS := $(call notempty,$(TOOLS))
+# lor is defined in rules.mak
 CONFIG_BLOCK := $(call lor,$(CONFIG_SOFTMMU),$(CONFIG_TOOLS))
 
 # Create QEMU_PKGVERSION and FULL_VERSION strings
@@ -681,7 +680,7 @@ clean: recurse-clean
 		! -path ./roms/edk2/BaseTools/Source/Python/UPT/Dll/sqlite3.dll \
 		-exec rm {} +
 	rm -f $(edk2-decompressed)
-	rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga$(EXESUF) TAGS cscope.* *.pod *~ */*~
+	rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) TAGS cscope.* *.pod *~ */*~
 	rm -f fsdev/*.pod scsi/*.pod
 	rm -f qemu-img-cmds.h
 	rm -f ui/shader/*-vert.h ui/shader/*-frag.h
@@ -809,7 +808,7 @@ ifdef CONFIG_POSIX
 	$(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7"
 	$(INSTALL_DATA) docs/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7"
 	$(INSTALL_DATA) docs/qemu-cpu-models.7 "$(DESTDIR)$(mandir)/man7"
-ifneq ($(TOOLS),)
+ifeq ($(CONFIG_TOOLS),y)
 	$(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
 	$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
 	$(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
@@ -845,7 +844,7 @@ install: all $(if $(BUILD_DOCS),install-doc) install-datadir install-localstated
 	$(if $(INSTALL_BLOBS),$(edk2-decompressed)) \
 	recurse-install
 ifneq ($(TOOLS),)
-	$(call install-prog,$(subst qemu-ga,qemu-ga$(EXESUF),$(TOOLS)),$(DESTDIR)$(bindir))
+	$(call install-prog,$(TOOLS),$(DESTDIR)$(bindir))
 endif
 ifneq ($(CONFIG_MODULES),)
 	$(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)"
diff --git a/accel/tcg/user-exec-stub.c b/accel/tcg/user-exec-stub.c
index 4bf00b8496..f6d8c8fb6f 100644
--- a/accel/tcg/user-exec-stub.c
+++ b/accel/tcg/user-exec-stub.c
@@ -1,5 +1,5 @@
 #include "qemu/osdep.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "sysemu/replay.h"
 #include "sysemu/sysemu.h"
 
diff --git a/arch_init.c b/arch_init.c
index 74b0708634..0a1531124c 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -106,14 +106,3 @@ int xen_available(void)
     return 0;
 #endif
 }
-
-
-TargetInfo *qmp_query_target(Error **errp)
-{
-    TargetInfo *info = g_malloc0(sizeof(*info));
-
-    info->arch = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME, -1,
-                                 &error_abort);
-
-    return info;
-}
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 7ca5d97af3..03f03407b0 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -150,7 +150,7 @@ static void tcp_chr_accept(QIONetListener *listener,
                            void *opaque);
 
 static int tcp_chr_read_poll(void *opaque);
-static void tcp_chr_disconnect(Chardev *chr);
+static void tcp_chr_disconnect_locked(Chardev *chr);
 
 /* Called with chr_write_lock held.  */
 static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
@@ -174,7 +174,7 @@ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
 
         if (ret < 0 && errno != EAGAIN) {
             if (tcp_chr_read_poll(chr) <= 0) {
-                tcp_chr_disconnect(chr);
+                tcp_chr_disconnect_locked(chr);
                 return len;
             } /* else let the read handler finish it properly */
         }
@@ -469,8 +469,9 @@ static void update_disconnected_filename(SocketChardev *s)
 /* NB may be called even if tcp_chr_connect has not been
  * reached, due to TLS or telnet initialization failure,
  * so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED
+ * This must be called with chr->chr_write_lock held.
  */
-static void tcp_chr_disconnect(Chardev *chr)
+static void tcp_chr_disconnect_locked(Chardev *chr)
 {
     SocketChardev *s = SOCKET_CHARDEV(chr);
     bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED;
@@ -490,6 +491,13 @@ static void tcp_chr_disconnect(Chardev *chr)
     }
 }
 
+static void tcp_chr_disconnect(Chardev *chr)
+{
+    qemu_mutex_lock(&chr->chr_write_lock);
+    tcp_chr_disconnect_locked(chr);
+    qemu_mutex_unlock(&chr->chr_write_lock);
+}
+
 static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
 {
     Chardev *chr = CHARDEV(opaque);
@@ -1131,8 +1139,10 @@ static gboolean socket_reconnect_timeout(gpointer opaque)
     Chardev *chr = CHARDEV(opaque);
     SocketChardev *s = SOCKET_CHARDEV(opaque);
 
+    qemu_mutex_lock(&chr->chr_write_lock);
     g_source_unref(s->reconnect_timer);
     s->reconnect_timer = NULL;
+    qemu_mutex_unlock(&chr->chr_write_lock);
 
     if (chr->be_open) {
         return false;
diff --git a/configure b/configure
index 3a020aefd8..e44e454c43 100755
--- a/configure
+++ b/configure
@@ -6129,7 +6129,7 @@ if [ "$guest_agent" != "no" ]; then
   if [ "$softmmu" = no -a "$want_tools" = no ] ; then
       guest_agent=no
   elif [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" -o "$mingw32" = "yes" ] ; then
-      tools="qemu-ga $tools"
+      tools="qemu-ga\$(EXESUF) $tools"
       guest_agent=yes
   elif [ "$guest_agent" != yes ]; then
       guest_agent=no
@@ -6614,6 +6614,9 @@ fi
 if test "$profiler" = "yes" ; then
   echo "CONFIG_PROFILER=y" >> $config_host_mak
 fi
+if test "$want_tools" = "yes" ; then
+  echo "CONFIG_TOOLS=y" >> $config_host_mak
+fi
 if test "$slirp" != "no"; then
   echo "CONFIG_SLIRP=y" >> $config_host_mak
   echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
@@ -7360,11 +7363,6 @@ if test "$sparse" = "yes" ; then
   echo "HOST_CC      := REAL_CC=\"\$(HOST_CC)\" cgcc"  >> $config_host_mak
   echo "QEMU_CFLAGS  += -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-non-pointer-null" >> $config_host_mak
 fi
-if test "$cross_prefix" != ""; then
-  echo "AUTOCONF_HOST := --host=${cross_prefix%-}"     >> $config_host_mak
-else
-  echo "AUTOCONF_HOST := "                             >> $config_host_mak
-fi
 echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
 echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
 echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
diff --git a/cpus-common.c b/cpus-common.c
index 023cfebfa3..af3385a296 100644
--- a/cpus-common.c
+++ b/cpus-common.c
@@ -20,7 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu/main-loop.h"
 #include "exec/cpu-common.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "sysemu/cpus.h"
 
 static QemuMutex qemu_cpu_list_lock;
diff --git a/docs/interop/firmware.json b/docs/interop/firmware.json
index ff8c2ce5f2..8ffb7856d2 100644
--- a/docs/interop/firmware.json
+++ b/docs/interop/firmware.json
@@ -13,7 +13,7 @@
 # = Firmware
 ##
 
-{ 'include' : 'common.json' }
+{ 'include' : 'machine.json' }
 { 'include' : 'block-core.json' }
 
 ##
diff --git a/exec.c b/exec.c
index 731b79d2e4..1df966d17a 100644
--- a/exec.c
+++ b/exec.c
@@ -939,7 +939,7 @@ void cpu_exec_unrealizefn(CPUState *cpu)
 Property cpu_common_props[] = {
 #ifndef CONFIG_USER_ONLY
     /* Create a memory property for softmmu CPU object,
-     * so users can wire up its memory. (This can't go in qom/cpu.c
+     * so users can wire up its memory. (This can't go in hw/core/cpu.c
      * because that file is compiled only once for both user-mode
      * and system builds.) The default if no link is set up is to use
      * the system address space.
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index a83567e6aa..6e8293aac9 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -12,7 +12,7 @@
 #include "qemu/osdep.h"
 #include "hw/acpi/cpu_hotplug.h"
 #include "qapi/error.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "hw/i386/pc.h"
 #include "qemu/error-report.h"
 
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 2ca52bf045..2034dd749e 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -31,7 +31,7 @@
 #include "hw/pci/pci.h"
 #include "migration/vmstate.h"
 #include "qemu/timer.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "sysemu/reset.h"
 #include "sysemu/runstate.h"
 #include "hw/acpi/acpi.h"
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 1c907d2a7d..5742c3df87 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -44,7 +44,7 @@
 #include "hw/xen/xen.h"
 #include "migration/qemu-file-types.h"
 #include "migration/vmstate.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "trace.h"
 
 #define GPE_BASE 0xafe0
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index 956ebe32c8..245817d23e 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -20,7 +20,7 @@
 #include "exec/address-spaces.h"
 #include "trace.h"
 #include "exec/target_page.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
 #include "qemu/jhash.h"
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index fa9afd2b7e..a8b2d97fe9 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -30,7 +30,7 @@
 #include "qapi/error.h"
 #include "qemu/bitmap.h"
 #include "trace.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "target/arm/cpu.h"
 #include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index b49f880a0c..fd0550d1d9 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -8,6 +8,7 @@ common-obj-y += irq.o
 common-obj-y += hotplug.o
 common-obj-$(CONFIG_SOFTMMU) += nmi.o
 common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o
+common-obj-y += cpu.o
 
 common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
 common-obj-$(CONFIG_XILINX_AXI) += stream.o
diff --git a/qom/cpu.c b/hw/core/cpu.c
index aeb34f8c67..0035845511 100644
--- a/qom/cpu.c
+++ b/hw/core/cpu.c
@@ -20,7 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "sysemu/hw_accel.h"
 #include "qemu/notify.h"
 #include "qemu/log.h"
diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
index 06d8d6466e..4b1fc86a06 100644
--- a/hw/core/generic-loader.c
+++ b/hw/core/generic-loader.c
@@ -31,7 +31,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "hw/sysbus.h"
 #include "sysemu/dma.h"
 #include "sysemu/reset.h"
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 526fbd5ced..15cf7c62e3 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -249,6 +249,16 @@ CurrentMachineParams *qmp_query_current_machine(Error **errp)
     return params;
 }
 
+TargetInfo *qmp_query_target(Error **errp)
+{
+    TargetInfo *info = g_malloc0(sizeof(*info));
+
+    info->arch = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME, -1,
+                                 &error_abort);
+
+    return info;
+}
+
 HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
 {
     MachineState *ms = MACHINE(qdev_get_machine());
diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index 30b1991b52..1aa0a9a01a 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -16,7 +16,7 @@
 #include "hw/boards.h"
 #include "sysemu/sysemu.h"
 #include "exec/address-spaces.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 static void machine_none_init(MachineState *mch)
 {
diff --git a/hw/core/numa.c b/hw/core/numa.c
index 7a63ddc4c6..4f7e4628a0 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -34,7 +34,7 @@
 #include "qapi/opts-visitor.h"
 #include "qapi/qapi-visit-machine.h"
 #include "sysemu/qtest.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "hw/mem/pc-dimm.h"
 #include "migration/vmstate.h"
 #include "hw/boards.h"
diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index cd1e165faf..6872a3a00a 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -14,7 +14,7 @@
 #include "hw/cpu/a9mpcore.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 static void a9mp_priv_set_irq(void *opaque, int irq, int level)
 {
diff --git a/hw/cpu/cluster.c b/hw/cpu/cluster.c
index 74d8d43c00..349a883261 100644
--- a/hw/cpu/cluster.c
+++ b/hw/cpu/cluster.c
@@ -21,7 +21,7 @@
 #include "qemu/osdep.h"
 #include "hw/cpu/cluster.h"
 #include "hw/qdev-properties.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "qemu/cutils.h"
diff --git a/hw/display/ati.c b/hw/display/ati.c
index 35f49a591b..8f940eee22 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -50,6 +50,7 @@ static void ati_vga_switch_mode(ATIVGAState *s)
         s->mode = EXT_MODE;
         if (s->regs.crtc_gen_cntl & CRTC2_EN) {
             /* CRT controller enabled, use CRTC values */
+            /* FIXME Should these be the same as VGA CRTC regs? */
             uint32_t offs = s->regs.crtc_offset & 0x07ffffff;
             int stride = (s->regs.crtc_pitch & 0x7ff) * 8;
             int bpp = 0;
@@ -89,7 +90,9 @@ static void ati_vga_switch_mode(ATIVGAState *s)
             DPRINTF("Switching to %dx%d %d %d @ %x\n", h, v, stride, bpp, offs);
             vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
             vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED);
-            s->vga.big_endian_fb = false;
+            s->vga.big_endian_fb = (s->regs.config_cntl & APER_0_ENDIAN ||
+                                    s->regs.config_cntl & APER_1_ENDIAN ?
+                                    true : false);
             /* reset VBE regs then set up mode */
             s->vga.vbe_regs[VBE_DISPI_INDEX_XRES] = h;
             s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] = v;
@@ -101,16 +104,23 @@ static void ati_vga_switch_mode(ATIVGAState *s)
                 (s->regs.dac_cntl & DAC_8BIT_EN ? VBE_DISPI_8BIT_DAC : 0));
             /* now set offset and stride after enable as that resets these */
             if (stride) {
+                int bypp = DIV_ROUND_UP(bpp, BITS_PER_BYTE);
+
                 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_VIRT_WIDTH);
                 vbe_ioport_write_data(&s->vga, 0, stride);
-                if (offs % stride == 0) {
-                    vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET);
-                    vbe_ioport_write_data(&s->vga, 0, offs / stride);
-                } else {
-                    /* FIXME what to do with this? */
-                    error_report("VGA offset is not multiple of pitch, "
-                                 "expect bad picture");
+                stride *= bypp;
+                if (offs % stride) {
+                    DPRINTF("CRTC offset is not multiple of pitch\n");
+                    vbe_ioport_write_index(&s->vga, 0,
+                                           VBE_DISPI_INDEX_X_OFFSET);
+                    vbe_ioport_write_data(&s->vga, 0, offs % stride / bypp);
                 }
+                vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET);
+                vbe_ioport_write_data(&s->vga, 0, offs / stride);
+                DPRINTF("VBE offset (%d,%d), vbe_start_addr=%x\n",
+                        s->vga.vbe_regs[VBE_DISPI_INDEX_X_OFFSET],
+                        s->vga.vbe_regs[VBE_DISPI_INDEX_Y_OFFSET],
+                        s->vga.vbe_start_addr);
             }
         }
     } else {
@@ -132,9 +142,8 @@ static void ati_cursor_define(ATIVGAState *s)
         return; /* Do not update cursor if locked or rendered by guest */
     }
     /* FIXME handle cur_hv_offs correctly */
-    src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) +
-          s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) -
-          (s->regs.cur_hv_offs & 0xffff) * 16;
+    src = s->vga.vram_ptr + s->regs.cur_offset -
+          (s->regs.cur_hv_offs >> 16) - (s->regs.cur_hv_offs & 0xffff) * 16;
     for (i = 0; i < 64; i++) {
         for (j = 0; j < 8; j++, idx++) {
             data[idx] = src[i * 16 + j];
@@ -190,8 +199,7 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
         return;
     }
     /* FIXME handle cur_hv_offs correctly */
-    src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) +
-          s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16;
+    src = s->vga.vram_ptr + s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16;
     dp = &dp[vga->hw_cursor_x];
     h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8;
     for (i = 0; i < 8; i++) {
@@ -207,7 +215,7 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
                 }
             } else {
                 color = (xbits & BIT(7) ? s->regs.cur_color1 :
-                                          s->regs.cur_color0) << 8 | 0xff;
+                                          s->regs.cur_color0) | 0xff000000;
             }
             if (vga->hw_cursor_x + i * 8 + j >= h) {
                 return; /* end of screen, don't span to next line */
@@ -235,6 +243,21 @@ static uint64_t ati_i2c(bitbang_i2c_interface *i2c, uint64_t data, int base)
     return data;
 }
 
+static void ati_vga_update_irq(ATIVGAState *s)
+{
+    pci_set_irq(&s->dev, !!(s->regs.gen_int_status & s->regs.gen_int_cntl));
+}
+
+static void ati_vga_vblank_irq(void *opaque)
+{
+    ATIVGAState *s = opaque;
+
+    timer_mod(&s->vblank_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+              NANOSECONDS_PER_SECOND / 60);
+    s->regs.gen_int_status |= CRTC_VBLANK_INT;
+    ati_vga_update_irq(s);
+}
+
 static inline uint64_t ati_reg_read_offs(uint32_t reg, int offs,
                                          unsigned int size)
 {
@@ -275,6 +298,12 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
                                 addr - (BIOS_0_SCRATCH + i * 4), size);
         break;
     }
+    case GEN_INT_CNTL:
+        val = s->regs.gen_int_cntl;
+        break;
+    case GEN_INT_STATUS:
+        val = s->regs.gen_int_status;
+        break;
     case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3:
         val = ati_reg_read_offs(s->regs.crtc_gen_cntl,
                                 addr - CRTC_GEN_CNTL, size);
@@ -304,9 +333,27 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
     case PALETTE_DATA:
         val = vga_ioport_read(&s->vga, VGA_PEL_D);
         break;
+    case CNFG_CNTL:
+        val = s->regs.config_cntl;
+        break;
     case CNFG_MEMSIZE:
         val = s->vga.vram_size;
         break;
+    case CONFIG_APER_0_BASE:
+    case CONFIG_APER_1_BASE:
+        val = pci_default_read_config(&s->dev,
+                                      PCI_BASE_ADDRESS_0, size) & 0xfffffff0;
+        break;
+    case CONFIG_APER_SIZE:
+        val = s->vga.vram_size;
+        break;
+    case CONFIG_REG_1_BASE:
+        val = pci_default_read_config(&s->dev,
+                                      PCI_BASE_ADDRESS_2, size) & 0xfffffff0;
+        break;
+    case CONFIG_REG_APER_SIZE:
+        val = memory_region_size(&s->mm);
+        break;
     case MC_STATUS:
         val = 5;
         break;
@@ -486,6 +533,21 @@ static void ati_mm_write(void *opaque, hwaddr addr,
                            addr - (BIOS_0_SCRATCH + i * 4), data, size);
         break;
     }
+    case GEN_INT_CNTL:
+        s->regs.gen_int_cntl = data;
+        if (data & CRTC_VBLANK_INT) {
+            ati_vga_vblank_irq(s);
+        } else {
+            timer_del(&s->vblank_timer);
+            ati_vga_update_irq(s);
+        }
+        break;
+    case GEN_INT_STATUS:
+        data &= (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF ?
+                 0x000f040fUL : 0xfc080effUL);
+        s->regs.gen_int_status &= ~data;
+        ati_vga_update_irq(s);
+        break;
     case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3:
     {
         uint32_t val = s->regs.crtc_gen_cntl;
@@ -549,12 +611,15 @@ static void ati_mm_write(void *opaque, hwaddr addr,
                                addr - GPIO_MONID, data, size);
             /*
              * Rage128p accesses DDC used to get EDID via these bits.
-             * Only touch i2c when write overlaps 3rd byte because some
-             * drivers access this reg via multiple partial writes and
-             * without this spurious bits would be sent.
+             * Because some drivers access this via multiple byte writes
+             * we have to be careful when we send bits to avoid spurious
+             * changes in bitbang_i2c state. So only do it when mask is set
+             * and either the enable bits are changed or output bits changed
+             * while enabled.
              */
             if ((s->regs.gpio_monid & BIT(25)) &&
-                addr <= GPIO_MONID + 2 && addr + size > GPIO_MONID + 2) {
+                ((addr <= GPIO_MONID + 2 && addr + size > GPIO_MONID + 2) ||
+                 (addr == GPIO_MONID && (s->regs.gpio_monid & 0x60000)))) {
                 s->regs.gpio_monid = ati_i2c(&s->bbi2c, s->regs.gpio_monid, 1);
             }
         }
@@ -580,6 +645,9 @@ static void ati_mm_write(void *opaque, hwaddr addr,
         data >>= 8;
         vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff);
         break;
+    case CNFG_CNTL:
+        s->regs.config_cntl = data;
+        break;
     case CRTC_H_TOTAL_DISP:
         s->regs.crtc_h_total_disp = data & 0x07ff07ff;
         break;
@@ -870,12 +938,19 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp)
     pci_register_bar(dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram);
     pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
     pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mm);
+
+    /* most interrupts are not yet emulated but MacOS needs at least VBlank */
+    dev->config[PCI_INTERRUPT_PIN] = 1;
+    timer_init_ns(&s->vblank_timer, QEMU_CLOCK_VIRTUAL, ati_vga_vblank_irq, s);
 }
 
 static void ati_vga_reset(DeviceState *dev)
 {
     ATIVGAState *s = ATI_VGA(dev);
 
+    timer_del(&s->vblank_timer);
+    ati_vga_update_irq(s);
+
     /* reset vga */
     vga_common_reset(&s->vga);
     s->mode = VGA_MODE;
@@ -885,6 +960,7 @@ static void ati_vga_exit(PCIDevice *dev)
 {
     ATIVGAState *s = ATI_VGA(dev);
 
+    timer_del(&s->vblank_timer);
     graphic_console_close(s->vga.con);
 }
 
diff --git a/hw/display/ati_dbg.c b/hw/display/ati_dbg.c
index 88b3a11315..0ebbd36f14 100644
--- a/hw/display/ati_dbg.c
+++ b/hw/display/ati_dbg.c
@@ -16,6 +16,7 @@ static struct ati_regdesc ati_reg_names[] = {
     {"BUS_CNTL", 0x0030},
     {"BUS_CNTL1", 0x0034},
     {"GEN_INT_CNTL", 0x0040},
+    {"GEN_INT_STATUS", 0x0044},
     {"CRTC_GEN_CNTL", 0x0050},
     {"CRTC_EXT_CNTL", 0x0054},
     {"DAC_CNTL", 0x0058},
@@ -23,11 +24,20 @@ static struct ati_regdesc ati_reg_names[] = {
     {"GPIO_DVI_DDC", 0x0064},
     {"GPIO_MONID", 0x0068},
     {"I2C_CNTL_1", 0x0094},
+    {"AMCGPIO_MASK_MIR", 0x009c},
+    {"AMCGPIO_A_MIR", 0x00a0},
+    {"AMCGPIO_Y_MIR", 0x00a4},
+    {"AMCGPIO_EN_MIR", 0x00a8},
     {"PALETTE_INDEX", 0x00b0},
     {"PALETTE_DATA", 0x00b4},
     {"CNFG_CNTL", 0x00e0},
     {"GEN_RESET_CNTL", 0x00f0},
     {"CNFG_MEMSIZE", 0x00f8},
+    {"CONFIG_APER_0_BASE", 0x0100},
+    {"CONFIG_APER_1_BASE", 0x0104},
+    {"CONFIG_APER_SIZE", 0x0108},
+    {"CONFIG_REG_1_BASE", 0x010c},
+    {"CONFIG_REG_APER_SIZE", 0x0110},
     {"MEM_CNTL", 0x0140},
     {"MC_FB_LOCATION", 0x0148},
     {"MC_AGP_LOCATION", 0x014C},
diff --git a/hw/display/ati_int.h b/hw/display/ati_int.h
index 31a1927b3e..2a16708e4f 100644
--- a/hw/display/ati_int.h
+++ b/hw/display/ati_int.h
@@ -9,6 +9,7 @@
 #ifndef ATI_INT_H
 #define ATI_INT_H
 
+#include "qemu/timer.h"
 #include "hw/pci/pci.h"
 #include "hw/i2c/bitbang_i2c.h"
 #include "vga_int.h"
@@ -33,12 +34,15 @@
 typedef struct ATIVGARegs {
     uint32_t mm_index;
     uint32_t bios_scratch[8];
+    uint32_t gen_int_cntl;
+    uint32_t gen_int_status;
     uint32_t crtc_gen_cntl;
     uint32_t crtc_ext_cntl;
     uint32_t dac_cntl;
     uint32_t gpio_vga_ddc;
     uint32_t gpio_dvi_ddc;
     uint32_t gpio_monid;
+    uint32_t config_cntl;
     uint32_t crtc_h_total_disp;
     uint32_t crtc_h_sync_strt_wid;
     uint32_t crtc_v_total_disp;
@@ -88,6 +92,7 @@ typedef struct ATIVGAState {
     uint16_t cursor_size;
     uint32_t cursor_offset;
     QEMUCursor *cursor;
+    QEMUTimer vblank_timer;
     bitbang_i2c_interface bbi2c;
     MemoryRegion io;
     MemoryRegion mm;
diff --git a/hw/display/ati_regs.h b/hw/display/ati_regs.h
index d7155c93d5..ebd37ee30d 100644
--- a/hw/display/ati_regs.h
+++ b/hw/display/ati_regs.h
@@ -34,6 +34,7 @@
 #define BUS_CNTL                                0x0030
 #define BUS_CNTL1                               0x0034
 #define GEN_INT_CNTL                            0x0040
+#define GEN_INT_STATUS                          0x0044
 #define CRTC_GEN_CNTL                           0x0050
 #define CRTC_EXT_CNTL                           0x0054
 #define DAC_CNTL                                0x0058
@@ -41,11 +42,20 @@
 #define GPIO_DVI_DDC                            0x0064
 #define GPIO_MONID                              0x0068
 #define I2C_CNTL_1                              0x0094
+#define AMCGPIO_MASK_MIR                        0x009c
+#define AMCGPIO_A_MIR                           0x00a0
+#define AMCGPIO_Y_MIR                           0x00a4
+#define AMCGPIO_EN_MIR                          0x00a8
 #define PALETTE_INDEX                           0x00b0
 #define PALETTE_DATA                            0x00b4
 #define CNFG_CNTL                               0x00e0
 #define GEN_RESET_CNTL                          0x00f0
 #define CNFG_MEMSIZE                            0x00f8
+#define CONFIG_APER_0_BASE                      0x0100
+#define CONFIG_APER_1_BASE                      0x0104
+#define CONFIG_APER_SIZE                        0x0108
+#define CONFIG_REG_1_BASE                       0x010c
+#define CONFIG_REG_APER_SIZE                    0x0110
 #define MEM_CNTL                                0x0140
 #define MC_FB_LOCATION                          0x0148
 #define MC_AGP_LOCATION                         0x014C
@@ -307,7 +317,14 @@
 #define XPLL_FB_DIV_MASK                        0x0000FF00
 #define X_MPLL_REF_DIV_MASK                     0x000000FF
 
+/* GEN_INT_CNTL) */
+#define CRTC_VBLANK_INT                         0x00000001
+#define CRTC_VLINE_INT                          0x00000002
+#define CRTC_VSYNC_INT                          0x00000004
+
 /* Config control values (CONFIG_CNTL) */
+#define APER_0_ENDIAN                           0x00000003
+#define APER_1_ENDIAN                           0x0000000c
 #define CFG_VGA_IO_DIS                          0x00000400
 
 /* CRTC control values (CRTC_GEN_CNTL) */
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 5b0ec1b89e..034e413fd0 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -27,7 +27,7 @@
 #include "qemu/bitmap.h"
 #include "qemu/error-report.h"
 #include "hw/pci/pci.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "target/i386/cpu.h"
 #include "hw/misc/pvpanic.h"
 #include "hw/timer/hpet.h"
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 697c33606a..c14ed86439 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -76,7 +76,7 @@
 #include "qapi/error.h"
 #include "qapi/qapi-visit-common.h"
 #include "qapi/visitor.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "hw/nmi.h"
 #include "hw/usb.h"
 #include "hw/i386/intel_iommu.h"
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 7af591daac..1d7da7baa2 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -23,7 +23,7 @@
 #include "hw/sysbus.h"
 #include "gic_internal.h"
 #include "qapi/error.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "trace.h"
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
index 8f5f4c8e94..f0c551d43f 100644
--- a/hw/intc/arm_gicv3_common.c
+++ b/hw/intc/arm_gicv3_common.c
@@ -24,7 +24,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "hw/intc/arm_gicv3_common.h"
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index eec9eb31c1..17c292e306 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -49,7 +49,7 @@
 #include "exec/address-spaces.h"
 #include "sysemu/runstate.h"
 #include "sysemu/sysemu.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "hw/nvram/fw_cfg.h"
 #include "qemu/cutils.h"
 
diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c
index 8ab18967b5..dd99cc7acf 100644
--- a/hw/misc/imx6_src.c
+++ b/hw/misc/imx6_src.c
@@ -16,7 +16,7 @@
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
 #include "arm-powerctl.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #ifndef DEBUG_IMX6_SRC
 #define DEBUG_IMX6_SRC 0
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 64fc2255cc..baedadf20b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -49,7 +49,7 @@
 #include "mmu-hash64.h"
 #include "mmu-book3s-v3.h"
 #include "cpu-models.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #include "hw/boards.h"
 #include "hw/ppc/ppc.h"
diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c
index 75f1867174..4c634c83b1 100644
--- a/hw/timer/a9gtimer.c
+++ b/hw/timer/a9gtimer.c
@@ -31,7 +31,7 @@
 #include "qemu/bitops.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #ifndef A9_GTIMER_ERR_DEBUG
 #define A9_GTIMER_ERR_DEBUG 0
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 983e61847e..9f63abef10 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -29,7 +29,7 @@
 #include "qapi/error.h"
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define PTIMER_POLICY                       \
     (PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |  \
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 9ca7b87a80..56ab2f457f 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1838,6 +1838,9 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
             ehci_set_state(q->ehci, q->async, EST_EXECUTING);
             break;
         }
+    } else if (q->dev == NULL) {
+        ehci_trace_guest_bug(q->ehci, "no device attached to queue");
+        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
     } else {
         p = ehci_alloc_packet(q);
         p->qtdaddr = q->qtdaddr;
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index f698224c8a..f578264948 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2543,6 +2543,9 @@ static void xhci_process_commands(XHCIState *xhci)
         case CR_GET_PORT_BANDWIDTH:
             event.ccode = xhci_get_port_bandwidth(xhci, trb.parameter);
             break;
+        case CR_NOOP:
+            event.ccode = CC_SUCCESS;
+            break;
         case CR_VENDOR_NEC_FIRMWARE_REVISION:
             if (xhci->nec_quirks) {
                 event.type = 48; /* NEC reply */
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index fc9fe0c00f..e0f5ca6f81 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -819,8 +819,8 @@ static void usbredir_handle_interrupt_in_data(USBRedirDevice *dev,
                                               USBPacket *p, uint8_t ep)
 {
     /* Input interrupt endpoint, buffered packet input */
-    struct buf_packet *intp;
-    int status, len;
+    struct buf_packet *intp, *intp_to_free;
+    int status, len, sum;
 
     if (!dev->endpoint[EP2I(ep)].interrupt_started &&
             !dev->endpoint[EP2I(ep)].interrupt_error) {
@@ -839,9 +839,17 @@ static void usbredir_handle_interrupt_in_data(USBRedirDevice *dev,
         dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
     }
 
-    intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
+    /* check for completed interrupt message (with all fragments) */
+    sum = 0;
+    QTAILQ_FOREACH(intp, &dev->endpoint[EP2I(ep)].bufpq, next) {
+        sum += intp->len;
+        if (intp->len < dev->endpoint[EP2I(ep)].max_packet_size ||
+            sum >= p->iov.size)
+            break;
+    }
+
     if (intp == NULL) {
-        DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
+        DPRINTF2("interrupt-token-in ep %02X, no intp, buffered %d\n", ep, sum);
         /* Check interrupt_error for stream errors */
         status = dev->endpoint[EP2I(ep)].interrupt_error;
         dev->endpoint[EP2I(ep)].interrupt_error = 0;
@@ -852,18 +860,42 @@ static void usbredir_handle_interrupt_in_data(USBRedirDevice *dev,
         }
         return;
     }
-    DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
-            intp->status, intp->len);
 
-    status = intp->status;
-    len = intp->len;
-    if (len > p->iov.size) {
-        ERROR("received int data is larger then packet ep %02X\n", ep);
-        len = p->iov.size;
-        status = usb_redir_babble;
+    /* copy of completed interrupt message */
+    sum = 0;
+    status = usb_redir_success;
+    intp_to_free = NULL;
+    QTAILQ_FOREACH(intp, &dev->endpoint[EP2I(ep)].bufpq, next) {
+        if (intp_to_free) {
+            bufp_free(dev, intp_to_free, ep);
+        }
+        DPRINTF("interrupt-token-in ep %02X fragment status %d len %d\n", ep,
+                intp->status, intp->len);
+
+        sum += intp->len;
+        len = intp->len;
+        if (status == usb_redir_success) {
+            status = intp->status;
+        }
+        if (sum > p->iov.size) {
+            ERROR("received int data is larger then packet ep %02X\n", ep);
+            len -= (sum - p->iov.size);
+            sum = p->iov.size;
+            status = usb_redir_babble;
+        }
+
+        usb_packet_copy(p, intp->data, len);
+
+        intp_to_free = intp;
+        if (intp->len < dev->endpoint[EP2I(ep)].max_packet_size ||
+            sum >= p->iov.size)
+            break;
+    }
+    if (intp_to_free) {
+        bufp_free(dev, intp_to_free, ep);
     }
-    usb_packet_copy(p, intp->data, len);
-    bufp_free(dev, intp, ep);
+    DPRINTF("interrupt-token-in ep %02X summary status %d len %d\n", ep,
+            status, sum);
     usbredir_handle_status(dev, p, status);
 }
 
@@ -1499,6 +1531,11 @@ static void usbredir_check_bulk_receiving(USBRedirDevice *dev)
     for (i = EP2I(USB_DIR_IN); i < MAX_ENDPOINTS; i++) {
         dev->endpoint[i].bulk_receiving_enabled = 0;
     }
+
+    if (dev->interface_info.interface_count == NO_INTERFACE_INFO) {
+        return;
+    }
+
     for (i = 0; i < dev->interface_info.interface_count; i++) {
         quirks = usb_get_quirks(dev->device_info.vendor_id,
                                 dev->device_info.product_id,
@@ -2036,22 +2073,17 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
     }
 
     if (ep & USB_DIR_IN) {
-        bool q_was_empty;
-
         if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
             DPRINTF("received int packet while not started ep %02X\n", ep);
             free(data);
             return;
         }
 
-        q_was_empty = QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq);
-
         /* bufp_alloc also adds the packet to the ep queue */
         bufp_alloc(dev, data, data_len, interrupt_packet->status, ep, data);
 
-        if (q_was_empty) {
-            usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0);
-        }
+        /* insufficient data solved with USB_RET_NAK */
+        usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0);
     } else {
         /*
          * We report output interrupt packets as completed directly upon
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 536ea58f81..8323094648 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -22,7 +22,7 @@
 #include "exec/cpu-common.h"
 #include "exec/memory.h"
 #include "qemu/thread.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "qemu/rcu.h"
 
 #define EXCP_INTERRUPT 	0x10000 /* async interruption */
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 57a9a4ffd9..189709b6de 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -32,7 +32,7 @@
 #include "exec/hwaddr.h"
 #endif
 #include "exec/memattrs.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #include "cpu-param.h"
 
diff --git a/include/exec/log.h b/include/exec/log.h
index de067f173b..e2cfd436e6 100644
--- a/include/exec/log.h
+++ b/include/exec/log.h
@@ -2,7 +2,7 @@
 #define QEMU_EXEC_LOG_H
 
 #include "qemu/log.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "disas/disas.h"
 
 /* cpu_dump_state() logging functions: */
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 60d69217b4..ced86109ec 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -9,7 +9,7 @@
 #include "qapi/qapi-types-machine.h"
 #include "qemu/module.h"
 #include "qom/object.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 /**
  * memory_region_allocate_system_memory - Allocate a board's main memory
diff --git a/include/qom/cpu.h b/include/hw/core/cpu.h
index 77fca95a40..77fca95a40 100644
--- a/include/qom/cpu.h
+++ b/include/hw/core/cpu.h
diff --git a/include/hw/ppc/openpic.h b/include/hw/ppc/openpic.h
index ec16897bfb..db0d29e6c2 100644
--- a/include/hw/ppc/openpic.h
+++ b/include/hw/ppc/openpic.h
@@ -2,7 +2,7 @@
 #define OPENPIC_H
 
 #include "hw/sysbus.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define MAX_CPU     32
 #define MAX_MSI     8
diff --git a/include/qemu/module.h b/include/qemu/module.h
index db3065381d..65ba596e46 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -65,6 +65,6 @@ void register_module_init(void (*fn)(void), module_init_type type);
 void register_dso_module_init(void (*fn)(void), module_init_type type);
 
 void module_call_init(module_init_type type);
-void module_load_one(const char *prefix, const char *lib_name);
+bool module_load_one(const char *prefix, const char *lib_name);
 
 #endif
diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h
index d2ddfb5ad0..0ec2372477 100644
--- a/include/sysemu/hw_accel.h
+++ b/include/sysemu/hw_accel.h
@@ -11,7 +11,7 @@
 #ifndef QEMU_HW_ACCEL_H
 #define QEMU_HW_ACCEL_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "sysemu/hax.h"
 #include "sysemu/kvm.h"
 #include "sysemu/whpx.h"
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index c8ea412f62..909bcd77cf 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -15,7 +15,7 @@
 #define QEMU_KVM_H
 
 #include "qemu/queue.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "exec/memattrs.h"
 
 #ifdef NEED_CPU_H
diff --git a/io/task.c b/io/task.c
index 64c4c7126a..1ae7b86488 100644
--- a/io/task.c
+++ b/io/task.c
@@ -136,6 +136,7 @@ static gpointer qio_task_thread_worker(gpointer opaque)
                           qio_task_thread_result, task, NULL);
     g_source_attach(task->thread->completion,
                     task->thread->context);
+    g_source_unref(task->thread->completion);
     trace_qio_task_thread_source_attach(task, task->thread->completion);
 
     qemu_cond_signal(&task->thread_cond);
diff --git a/memory.c b/memory.c
index 4aa38eb5b1..7fd93b1d42 100644
--- a/memory.c
+++ b/memory.c
@@ -217,7 +217,6 @@ struct FlatRange {
     bool romd_mode;
     bool readonly;
     bool nonvolatile;
-    int has_coalesced_range;
 };
 
 #define FOR_EACH_FLAT_RANGE(var, view)          \
@@ -654,7 +653,6 @@ static void render_memory_region(FlatView *view,
     fr.romd_mode = mr->romd_mode;
     fr.readonly = readonly;
     fr.nonvolatile = nonvolatile;
-    fr.has_coalesced_range = 0;
 
     /* Render the region itself into any gaps left by the current view. */
     for (i = 0; i < view->nr && int128_nz(remain); ++i) {
@@ -855,46 +853,55 @@ static void address_space_update_ioeventfds(AddressSpace *as)
     flatview_unref(view);
 }
 
-static void flat_range_coalesced_io_del(FlatRange *fr, AddressSpace *as)
+/*
+ * Notify the memory listeners about the coalesced IO change events of
+ * range `cmr'.  Only the part that has intersection of the specified
+ * FlatRange will be sent.
+ */
+static void flat_range_coalesced_io_notify(FlatRange *fr, AddressSpace *as,
+                                           CoalescedMemoryRange *cmr, bool add)
 {
-    if (!fr->has_coalesced_range) {
+    AddrRange tmp;
+
+    tmp = addrrange_shift(cmr->addr,
+                          int128_sub(fr->addr.start,
+                                     int128_make64(fr->offset_in_region)));
+    if (!addrrange_intersects(tmp, fr->addr)) {
         return;
     }
+    tmp = addrrange_intersection(tmp, fr->addr);
 
-    if (--fr->has_coalesced_range > 0) {
-        return;
+    if (add) {
+        MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, coalesced_io_add,
+                                      int128_get64(tmp.start),
+                                      int128_get64(tmp.size));
+    } else {
+        MEMORY_LISTENER_UPDATE_REGION(fr, as, Reverse, coalesced_io_del,
+                                      int128_get64(tmp.start),
+                                      int128_get64(tmp.size));
     }
+}
 
-    MEMORY_LISTENER_UPDATE_REGION(fr, as, Reverse, coalesced_io_del,
-                                  int128_get64(fr->addr.start),
-                                  int128_get64(fr->addr.size));
+static void flat_range_coalesced_io_del(FlatRange *fr, AddressSpace *as)
+{
+    CoalescedMemoryRange *cmr;
+
+    QTAILQ_FOREACH(cmr, &fr->mr->coalesced, link) {
+        flat_range_coalesced_io_notify(fr, as, cmr, false);
+    }
 }
 
 static void flat_range_coalesced_io_add(FlatRange *fr, AddressSpace *as)
 {
     MemoryRegion *mr = fr->mr;
     CoalescedMemoryRange *cmr;
-    AddrRange tmp;
 
     if (QTAILQ_EMPTY(&mr->coalesced)) {
         return;
     }
 
-    if (fr->has_coalesced_range++) {
-        return;
-    }
-
     QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
-        tmp = addrrange_shift(cmr->addr,
-                              int128_sub(fr->addr.start,
-                                         int128_make64(fr->offset_in_region)));
-        if (!addrrange_intersects(tmp, fr->addr)) {
-            continue;
-        }
-        tmp = addrrange_intersection(tmp, fr->addr);
-        MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, coalesced_io_add,
-                                      int128_get64(tmp.start),
-                                      int128_get64(tmp.size));
+        flat_range_coalesced_io_notify(fr, as, cmr, true);
     }
 }
 
@@ -2236,27 +2243,26 @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
     qemu_ram_resize(mr->ram_block, newsize, errp);
 }
 
-static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
+/*
+ * Call proper memory listeners about the change on the newly
+ * added/removed CoalescedMemoryRange.
+ */
+static void memory_region_update_coalesced_range(MemoryRegion *mr,
+                                                 CoalescedMemoryRange *cmr,
+                                                 bool add)
 {
+    AddressSpace *as;
     FlatView *view;
     FlatRange *fr;
 
-    view = address_space_get_flatview(as);
-    FOR_EACH_FLAT_RANGE(fr, view) {
-        if (fr->mr == mr) {
-            flat_range_coalesced_io_del(fr, as);
-            flat_range_coalesced_io_add(fr, as);
-        }
-    }
-    flatview_unref(view);
-}
-
-static void memory_region_update_coalesced_range(MemoryRegion *mr)
-{
-    AddressSpace *as;
-
     QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
-        memory_region_update_coalesced_range_as(mr, as);
+        view = address_space_get_flatview(as);
+        FOR_EACH_FLAT_RANGE(fr, view) {
+            if (fr->mr == mr) {
+                flat_range_coalesced_io_notify(fr, as, cmr, add);
+            }
+        }
+        flatview_unref(view);
     }
 }
 
@@ -2274,14 +2280,17 @@ void memory_region_add_coalescing(MemoryRegion *mr,
 
     cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size));
     QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
-    memory_region_update_coalesced_range(mr);
+    memory_region_update_coalesced_range(mr, cmr, true);
     memory_region_set_flush_coalesced(mr);
 }
 
 void memory_region_clear_coalescing(MemoryRegion *mr)
 {
     CoalescedMemoryRange *cmr;
-    bool updated = false;
+
+    if (QTAILQ_EMPTY(&mr->coalesced)) {
+        return;
+    }
 
     qemu_flush_coalesced_mmio_buffer();
     mr->flush_coalesced_mmio = false;
@@ -2289,12 +2298,8 @@ void memory_region_clear_coalescing(MemoryRegion *mr)
     while (!QTAILQ_EMPTY(&mr->coalesced)) {
         cmr = QTAILQ_FIRST(&mr->coalesced);
         QTAILQ_REMOVE(&mr->coalesced, cmr, link);
+        memory_region_update_coalesced_range(mr, cmr, false);
         g_free(cmr);
-        updated = true;
-    }
-
-    if (updated) {
-        memory_region_update_coalesced_range(mr);
     }
 }
 
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index e4d4043a3b..b2551c16d1 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -25,7 +25,6 @@
 #include "qemu/timer.h"
 #include "qemu/sockets.h"
 #include "monitor/monitor-internal.h"
-#include "monitor/qdev.h"
 #include "qapi/error.h"
 #include "qapi/clone-visitor.h"
 #include "qapi/opts-visitor.h"
@@ -35,7 +34,6 @@
 #include "qapi/qapi-commands-migration.h"
 #include "qapi/qapi-commands-misc.h"
 #include "qapi/qapi-commands-net.h"
-#include "qapi/qapi-commands-qdev.h"
 #include "qapi/qapi-commands-rocker.h"
 #include "qapi/qapi-commands-run-state.h"
 #include "qapi/qapi-commands-tpm.h"
@@ -2167,23 +2165,6 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_device_add(Monitor *mon, const QDict *qdict)
-{
-    Error *err = NULL;
-
-    qmp_device_add((QDict *)qdict, NULL, &err);
-    hmp_handle_error(mon, &err);
-}
-
-void hmp_device_del(Monitor *mon, const QDict *qdict)
-{
-    const char *id = qdict_get_str(qdict, "id");
-    Error *err = NULL;
-
-    qmp_device_del(id, &err);
-    hmp_handle_error(mon, &err);
-}
-
 void hmp_netdev_add(Monitor *mon, const QDict *qdict)
 {
     Error *err = NULL;
diff --git a/monitor/qmp.c b/monitor/qmp.c
index e1b196217d..9d9e5d8b27 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -97,7 +97,7 @@ void qmp_send_response(MonitorQMP *mon, const QDict *rsp)
 }
 
 /*
- * Emit QMP response @rsp with ID @id to @mon.
+ * Emit QMP response @rsp to @mon.
  * Null @rsp can only happen for commands with QCO_NO_SUCCESS_RESP.
  * Nothing is emitted then.
  */
diff --git a/qapi/common.json b/qapi/common.json
index 3d4e8de1e0..7b9cbcd97b 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -144,28 +144,3 @@
 ##
 { 'enum': 'PCIELinkWidth',
   'data': [ '1', '2', '4', '8', '12', '16', '32' ] }
-
-##
-# @SysEmuTarget:
-#
-# The comprehensive enumeration of QEMU system emulation ("softmmu")
-# targets. Run "./configure --help" in the project root directory, and
-# look for the *-softmmu targets near the "--target-list" option. The
-# individual target constants are not documented here, for the time
-# being.
-#
-# Notes: The resulting QMP strings can be appended to the "qemu-system-"
-#        prefix to produce the corresponding QEMU executable name. This
-#        is true even for "qemu-system-x86_64".
-#
-# ppcemb: dropped in 3.1
-#
-# Since: 3.0
-##
-{ 'enum' : 'SysEmuTarget',
-  'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32',
-             'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
-             'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc',
-             'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4',
-             'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32',
-             'x86_64', 'xtensa', 'xtensaeb' ] }
diff --git a/qapi/machine.json b/qapi/machine.json
index 6db8a7e2ec..de5c742d72 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -7,7 +7,30 @@
 # = Machines
 ##
 
-{ 'include': 'common.json' }
+##
+# @SysEmuTarget:
+#
+# The comprehensive enumeration of QEMU system emulation ("softmmu")
+# targets. Run "./configure --help" in the project root directory, and
+# look for the *-softmmu targets near the "--target-list" option. The
+# individual target constants are not documented here, for the time
+# being.
+#
+# Notes: The resulting QMP strings can be appended to the "qemu-system-"
+#        prefix to produce the corresponding QEMU executable name. This
+#        is true even for "qemu-system-x86_64".
+#
+# ppcemb: dropped in 3.1
+#
+# Since: 3.0
+##
+{ 'enum' : 'SysEmuTarget',
+  'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32',
+             'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
+             'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc',
+             'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4',
+             'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32',
+             'x86_64', 'xtensa', 'xtensaeb' ] }
 
 ##
 # @CpuInfoArch:
@@ -369,6 +392,29 @@
 { 'command': 'query-current-machine', 'returns': 'CurrentMachineParams' }
 
 ##
+# @TargetInfo:
+#
+# Information describing the QEMU target.
+#
+# @arch: the target architecture
+#
+# Since: 1.2.0
+##
+{ 'struct': 'TargetInfo',
+  'data': { 'arch': 'SysEmuTarget' } }
+
+##
+# @query-target:
+#
+# Return information about the target for this QEMU
+#
+# Returns: TargetInfo
+#
+# Since: 1.2.0
+##
+{ 'command': 'query-target', 'returns': 'TargetInfo' }
+
+##
 # @NumaOptionsType:
 #
 # @node: NUMA nodes configuration
diff --git a/qapi/misc.json b/qapi/misc.json
index a7fba7230c..6bd11f50e6 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -1342,29 +1342,6 @@
 { 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
 
 ##
-# @TargetInfo:
-#
-# Information describing the QEMU target.
-#
-# @arch: the target architecture
-#
-# Since: 1.2.0
-##
-{ 'struct': 'TargetInfo',
-  'data': { 'arch': 'SysEmuTarget' } }
-
-##
-# @query-target:
-#
-# Return information about the target for this QEMU
-#
-# Returns: TargetInfo
-#
-# Since: 1.2.0
-##
-{ 'command': 'query-target', 'returns': 'TargetInfo' }
-
-##
 # @AcpiTableOptions:
 #
 # Specify an ACPI table on the command line to load.
diff --git a/qapi/ui.json b/qapi/ui.json
index 59e412139a..e04525d8b4 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -1025,7 +1025,8 @@
 #
 ##
 { 'enum': 'GrabToggleKeys',
-  'data': [ 'ctrl-ctrl', 'alt-alt', 'meta-meta', 'scrolllock', 'ctrl-scrolllock' ] }
+  'data': [ 'ctrl-ctrl', 'alt-alt', 'shift-shift','meta-meta', 'scrolllock',
+            'ctrl-scrolllock' ] }
 
 ##
 # @DisplayGTK:
diff --git a/qdev-monitor.c b/qdev-monitor.c
index a0003bf2a9..8fe5c2cad2 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -19,6 +19,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
+#include "monitor/hmp.h"
 #include "monitor/monitor.h"
 #include "monitor/qdev.h"
 #include "sysemu/arch_init.h"
@@ -844,6 +845,23 @@ void qmp_device_del(const char *id, Error **errp)
     }
 }
 
+void hmp_device_add(Monitor *mon, const QDict *qdict)
+{
+    Error *err = NULL;
+
+    qmp_device_add((QDict *)qdict, NULL, &err);
+    hmp_handle_error(mon, &err);
+}
+
+void hmp_device_del(Monitor *mon, const QDict *qdict)
+{
+    const char *id = qdict_get_str(qdict, "id");
+    Error *err = NULL;
+
+    qmp_device_del(id, &err);
+    hmp_handle_error(mon, &err);
+}
+
 BlockBackend *blk_by_qdev_id(const char *id, Error **errp)
 {
     DeviceState *dev;
diff --git a/qemu-options.hx b/qemu-options.hx
index a308e5f5aa..ea0638e92d 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1436,12 +1436,15 @@ STEXI
 ETEXI
 
 DEF("usb", 0, QEMU_OPTION_usb,
-    "-usb            enable the USB driver (if it is not used by default yet)\n",
+    "-usb            enable on-board USB host controller (if not enabled by default)\n",
     QEMU_ARCH_ALL)
 STEXI
 @item -usb
 @findex -usb
-Enable the USB driver (if it is not used by default yet).
+Enable USB emulation on machine types with an on-board USB host controller (if
+not enabled by default).  Note that on-board USB host controllers may not
+support USB 3.0.  In this case @option{-device qemu-xhci} can be used instead
+on machines with PCI.
 ETEXI
 
 DEF("usbdevice", HAS_ARG, QEMU_OPTION_usbdevice,
diff --git a/qom/Makefile.objs b/qom/Makefile.objs
index aae478fc21..f9d77350ac 100644
--- a/qom/Makefile.objs
+++ b/qom/Makefile.objs
@@ -1,5 +1,4 @@
 qom-obj-y = object.o container.o qom-qobject.o
 qom-obj-y += object_interfaces.o
 
-common-obj-y = cpu.o
 common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o
diff --git a/qtest.c b/qtest.c
index d8b4857c74..8b50e2783e 100644
--- a/qtest.c
+++ b/qtest.c
@@ -661,6 +661,15 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
         qtest_send_prefix(chr);
         qtest_sendf(chr, "OK %"PRIi64"\n",
                     (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+    } else if (strcmp(words[0], "module_load") == 0) {
+        g_assert(words[1] && words[2]);
+
+        qtest_send_prefix(chr);
+        if (module_load_one(words[1], words[2])) {
+            qtest_sendf(chr, "OK\n");
+        } else {
+            qtest_sendf(chr, "FAIL\n");
+        }
     } else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) {
         int64_t ns;
         int ret;
diff --git a/scripts/minikconf.py b/scripts/minikconf.py
index 3109a81db7..40ae1989e1 100644
--- a/scripts/minikconf.py
+++ b/scripts/minikconf.py
@@ -702,8 +702,8 @@ if __name__ == '__main__':
 
     config = data.compute_config()
     for key in sorted(config.keys()):
-        if key not in external_vars:
-            print ('CONFIG_%s=%s' % (key, ('y' if config[key] else 'n')))
+        if key not in external_vars and config[key]:
+            print ('CONFIG_%s=y' % key)
 
     deps = open(argv[2], 'w')
     for fname in data.previously_included:
diff --git a/target/alpha/cpu-qom.h b/target/alpha/cpu-qom.h
index bae4945344..6f0a0adb9e 100644
--- a/target/alpha/cpu-qom.h
+++ b/target/alpha/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_ALPHA_CPU_QOM_H
 #define QEMU_ALPHA_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_ALPHA_CPU "alpha-cpu"
 
diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h
index 2049fa9612..7f5b244bde 100644
--- a/target/arm/cpu-qom.h
+++ b/target/arm/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_ARM_CPU_QOM_H
 #define QEMU_ARM_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 struct arm_boot_info;
 
diff --git a/target/cris/cpu-qom.h b/target/cris/cpu-qom.h
index 7556e9f97e..308c1f95bd 100644
--- a/target/cris/cpu-qom.h
+++ b/target/cris/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_CRIS_CPU_QOM_H
 #define QEMU_CRIS_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_CRIS_CPU "cris-cpu"
 
diff --git a/target/hppa/cpu-qom.h b/target/hppa/cpu-qom.h
index 9084e4701d..6367dc4793 100644
--- a/target/hppa/cpu-qom.h
+++ b/target/hppa/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_HPPA_CPU_QOM_H
 #define QEMU_HPPA_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_HPPA_CPU "hppa-cpu"
 
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 89241c31e7..462747baf8 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -22,7 +22,7 @@
 #include "qemu/log.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #ifndef CONFIG_USER_ONLY
 static void eval_interrupt(HPPACPU *cpu)
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index b12c5b5054..5a465db0dd 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -21,7 +21,7 @@
 #include "cpu.h"
 #include "exec/exec-all.h"
 #include "exec/helper-proto.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "trace.h"
 
 #ifdef CONFIG_USER_ONLY
diff --git a/target/i386/cpu-qom.h b/target/i386/cpu-qom.h
index 1a52f02a4c..0efab2fc67 100644
--- a/target/i386/cpu-qom.h
+++ b/target/i386/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_I386_CPU_QOM_H
 #define QEMU_I386_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "qemu/notify.h"
 
 #ifdef TARGET_X86_64
diff --git a/target/lm32/cpu-qom.h b/target/lm32/cpu-qom.h
index b423d2564b..dc9ac9ac9f 100644
--- a/target/lm32/cpu-qom.h
+++ b/target/lm32/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_LM32_CPU_QOM_H
 #define QEMU_LM32_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_LM32_CPU "lm32-cpu"
 
diff --git a/target/m68k/cpu-qom.h b/target/m68k/cpu-qom.h
index 0c157251a2..b56da8a213 100644
--- a/target/m68k/cpu-qom.h
+++ b/target/m68k/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_M68K_CPU_QOM_H
 #define QEMU_M68K_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_M68K_CPU "m68k-cpu"
 
diff --git a/target/microblaze/cpu-qom.h b/target/microblaze/cpu-qom.h
index 1a61db77d0..49b07cc697 100644
--- a/target/microblaze/cpu-qom.h
+++ b/target/microblaze/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_MICROBLAZE_CPU_QOM_H
 #define QEMU_MICROBLAZE_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_MICROBLAZE_CPU "microblaze-cpu"
 
diff --git a/target/mips/cpu-qom.h b/target/mips/cpu-qom.h
index ee58606afe..a430c0fe4b 100644
--- a/target/mips/cpu-qom.h
+++ b/target/mips/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_MIPS_CPU_QOM_H
 #define QEMU_MIPS_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #ifdef TARGET_MIPS64
 #define TYPE_MIPS_CPU "mips64-cpu"
diff --git a/target/moxie/cpu.h b/target/moxie/cpu.h
index 91ef2dc25e..01dca548e5 100644
--- a/target/moxie/cpu.h
+++ b/target/moxie/cpu.h
@@ -46,7 +46,7 @@ typedef struct CPUMoxieState {
     struct {} end_reset_fields;
 } CPUMoxieState;
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_MOXIE_CPU "moxie-cpu"
 
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index 5d44b76389..361b06ffeb 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -22,7 +22,7 @@
 #define NIOS2_CPU_H
 
 #include "exec/cpu-defs.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 typedef struct CPUNios2State CPUNios2State;
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 61ade1d4f0..561f0f7fad 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -21,7 +21,7 @@
 #define OPENRISC_CPU_H
 
 #include "exec/cpu-defs.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 /* cpu_openrisc_map_address_* in CPUOpenRISCTLBContext need this decl.  */
 struct OpenRISCCPU;
diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index 5769fb78a9..7ffdb0a706 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_PPC_CPU_QOM_H
 #define QEMU_PPC_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #ifdef TARGET_PPC64
 #define TYPE_POWERPC_CPU "powerpc64-cpu"
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 240b31e2eb..18d91d0920 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -20,7 +20,7 @@
 #ifndef RISCV_CPU_H
 #define RISCV_CPU_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat-types.h"
 
diff --git a/target/s390x/cpu-qom.h b/target/s390x/cpu-qom.h
index b46217dc31..b809ec8418 100644
--- a/target/s390x/cpu-qom.h
+++ b/target/s390x/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_S390_CPU_QOM_H
 #define QEMU_S390_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_S390_CPU "s390x-cpu"
 
diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h
index 174a99e561..88bd01a616 100644
--- a/target/s390x/cpu_models.h
+++ b/target/s390x/cpu_models.h
@@ -15,7 +15,7 @@
 
 #include "cpu_features.h"
 #include "gen-features.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 /* static CPU definition */
 struct S390CPUDef {
diff --git a/target/sh4/cpu-qom.h b/target/sh4/cpu-qom.h
index 0f9fb4dd31..0c56d055ba 100644
--- a/target/sh4/cpu-qom.h
+++ b/target/sh4/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_SUPERH_CPU_QOM_H
 #define QEMU_SUPERH_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_SUPERH_CPU "superh-cpu"
 
diff --git a/target/sparc/cpu-qom.h b/target/sparc/cpu-qom.h
index af6d57a9e0..7442e2768e 100644
--- a/target/sparc/cpu-qom.h
+++ b/target/sparc/cpu-qom.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_SPARC_CPU_QOM_H
 #define QEMU_SPARC_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #ifdef TARGET_SPARC64
 #define TYPE_SPARC_CPU "sparc64-cpu"
diff --git a/target/tilegx/cpu.h b/target/tilegx/cpu.h
index 6fcec06a9b..9cbec247d2 100644
--- a/target/tilegx/cpu.h
+++ b/target/tilegx/cpu.h
@@ -94,7 +94,7 @@ typedef struct CPUTLGState {
     struct {} end_reset_fields;
 } CPUTLGState;
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_TILEGX_CPU "tilegx-cpu"
 
diff --git a/target/tricore/cpu-qom.h b/target/tricore/cpu-qom.h
index 93c9d77fe3..7c1e130b4e 100644
--- a/target/tricore/cpu-qom.h
+++ b/target/tricore/cpu-qom.h
@@ -18,7 +18,7 @@
 #ifndef QEMU_TRICORE_CPU_QOM_H
 #define QEMU_TRICORE_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 
 #define TYPE_TRICORE_CPU "tricore-cpu"
diff --git a/target/tricore/helper.h b/target/tricore/helper.h
index b64780c37d..78176aa17a 100644
--- a/target/tricore/helper.h
+++ b/target/tricore/helper.h
@@ -153,3 +153,4 @@ DEF_HELPER_2(psw_write, void, env, i32)
 DEF_HELPER_1(psw_read, i32, env)
 /* Exceptions */
 DEF_HELPER_3(raise_exception_sync, noreturn, env, i32, i32)
+DEF_HELPER_2(qemu_excp, noreturn, env, i32)
diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c
index 9476d10d00..32c2bc1699 100644
--- a/target/tricore/op_helper.c
+++ b/target/tricore/op_helper.c
@@ -107,6 +107,13 @@ static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class,
     raise_exception_sync_internal(env, class, tin, pc, 0);
 }
 
+void helper_qemu_excp(CPUTriCoreState *env, uint32_t excp)
+{
+    CPUState *cs = env_cpu(env);
+    cs->exception_index = excp;
+    cpu_loop_exit(cs);
+}
+
 /* Addressing mode helper */
 
 static uint16_t reverse16(uint16_t val)
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
index dc2a65f3f9..4f10407477 100644
--- a/target/tricore/translate.c
+++ b/target/tricore/translate.c
@@ -30,6 +30,7 @@
 #include "exec/helper-gen.h"
 
 #include "tricore-opcodes.h"
+#include "exec/translator.h"
 #include "exec/log.h"
 
 /*
@@ -64,25 +65,16 @@ static const char *regnames_d[] = {
     };
 
 typedef struct DisasContext {
-    struct TranslationBlock *tb;
-    target_ulong pc, saved_pc, next_pc;
+    DisasContextBase base;
+    CPUTriCoreState *env;
+    target_ulong pc_succ_insn;
     uint32_t opcode;
-    int singlestep_enabled;
     /* Routine used to access memory */
     int mem_idx;
     uint32_t hflags, saved_hflags;
-    int bstate;
 } DisasContext;
 
 enum {
-
-    BS_NONE   = 0,
-    BS_STOP   = 1,
-    BS_BRANCH = 2,
-    BS_EXCP   = 3,
-};
-
-enum {
     MODE_LL = 0,
     MODE_LU = 1,
     MODE_UL = 2,
@@ -378,13 +370,13 @@ static void gen_swapmsk(DisasContext *ctx, int reg, TCGv ea)
    These makros also specify in which ISA version the csfr was introduced. */
 #define R(ADDRESS, REG, FEATURE)                                         \
     case ADDRESS:                                                        \
-        if (tricore_feature(env, FEATURE)) {                             \
+        if (tricore_feature(ctx->env, FEATURE)) {                        \
             tcg_gen_ld_tl(ret, cpu_env, offsetof(CPUTriCoreState, REG)); \
         }                                                                \
         break;
 #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
 #define E(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
-static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset)
+static inline void gen_mfcr(DisasContext *ctx, TCGv ret, int32_t offset)
 {
     /* since we're caching PSW make this a special case */
     if (offset == 0xfe04) {
@@ -403,7 +395,7 @@ static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset)
                                     since no execption occurs */
 #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)                \
     case ADDRESS:                                                        \
-        if (tricore_feature(env, FEATURE)) {                             \
+        if (tricore_feature(ctx->env, FEATURE)) {                        \
             tcg_gen_st_tl(r1, cpu_env, offsetof(CPUTriCoreState, REG));  \
         }                                                                \
         break;
@@ -412,7 +404,7 @@ static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset)
          watchdog device, we handle endinit protected registers like
          all-access registers for now. */
 #define E(ADDRESS, REG, FEATURE) A(ADDRESS, REG, FEATURE)
-static inline void gen_mtcr(CPUTriCoreState *env, DisasContext *ctx, TCGv r1,
+static inline void gen_mtcr(DisasContext *ctx, TCGv r1,
                             int32_t offset)
 {
     if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) {
@@ -1102,7 +1094,7 @@ gen_maddrs_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n)
 
 static inline void
 gen_madd32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n,
-             uint32_t up_shift, CPUTriCoreState *env)
+             uint32_t up_shift)
 {
     TCGv temp = tcg_temp_new();
     TCGv temp2 = tcg_temp_new();
@@ -1263,7 +1255,7 @@ gen_m16adds64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
 
 static inline void
 gen_madd64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
-             TCGv arg3, uint32_t n, CPUTriCoreState *env)
+             TCGv arg3, uint32_t n)
 {
     TCGv_i64 t1 = tcg_temp_new_i64();
     TCGv_i64 t2 = tcg_temp_new_i64();
@@ -1961,7 +1953,7 @@ gen_msubrs_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n)
 
 static inline void
 gen_msub32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n,
-             uint32_t up_shift, CPUTriCoreState *env)
+             uint32_t up_shift)
 {
     TCGv temp = tcg_temp_new();
     TCGv temp2 = tcg_temp_new();
@@ -2116,7 +2108,7 @@ gen_m16subs64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
 
 static inline void
 gen_msub64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
-             TCGv arg3, uint32_t n, CPUTriCoreState *env)
+             TCGv arg3, uint32_t n)
 {
     TCGv_i64 t1 = tcg_temp_new_i64();
     TCGv_i64 t2 = tcg_temp_new_i64();
@@ -3162,11 +3154,11 @@ static inline void gen_unpack(TCGv rl, TCGv rh, TCGv r1)
 }
 
 static inline void
-gen_dvinit_b(CPUTriCoreState *env, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
+gen_dvinit_b(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
 {
     TCGv_i64 ret = tcg_temp_new_i64();
 
-    if (!tricore_feature(env, TRICORE_FEATURE_131)) {
+    if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
         gen_helper_dvinit_b_13(ret, cpu_env, r1, r2);
     } else {
         gen_helper_dvinit_b_131(ret, cpu_env, r1, r2);
@@ -3177,11 +3169,11 @@ gen_dvinit_b(CPUTriCoreState *env, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
 }
 
 static inline void
-gen_dvinit_h(CPUTriCoreState *env, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
+gen_dvinit_h(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
 {
     TCGv_i64 ret = tcg_temp_new_i64();
 
-    if (!tricore_feature(env, TRICORE_FEATURE_131)) {
+    if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
         gen_helper_dvinit_h_13(ret, cpu_env, r1, r2);
     } else {
         gen_helper_dvinit_h_131(ret, cpu_env, r1, r2);
@@ -3230,12 +3222,12 @@ static inline void gen_save_pc(target_ulong pc)
 
 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
 {
-    if (unlikely(ctx->singlestep_enabled)) {
+    if (unlikely(ctx->base.singlestep_enabled)) {
         return false;
     }
 
 #ifndef CONFIG_USER_ONLY
-    return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
+    return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
 #else
     return true;
 #endif
@@ -3246,10 +3238,10 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
     if (use_goto_tb(ctx, dest)) {
         tcg_gen_goto_tb(n);
         gen_save_pc(dest);
-        tcg_gen_exit_tb(ctx->tb, n);
+        tcg_gen_exit_tb(ctx->base.tb, n);
     } else {
         gen_save_pc(dest);
-        if (ctx->singlestep_enabled) {
+        if (ctx->base.singlestep_enabled) {
             /* raise exception debug */
         }
         tcg_gen_exit_tb(NULL, 0);
@@ -3261,24 +3253,33 @@ static void generate_trap(DisasContext *ctx, int class, int tin)
     TCGv_i32 classtemp = tcg_const_i32(class);
     TCGv_i32 tintemp = tcg_const_i32(tin);
 
-    gen_save_pc(ctx->pc);
+    gen_save_pc(ctx->base.pc_next);
     gen_helper_raise_exception_sync(cpu_env, classtemp, tintemp);
-    ctx->bstate = BS_EXCP;
+    ctx->base.is_jmp = DISAS_NORETURN;
 
     tcg_temp_free(classtemp);
     tcg_temp_free(tintemp);
 }
 
+static void generate_qemu_excp(DisasContext *ctx, int excp)
+{
+    TCGv_i32 tmp = tcg_const_i32(excp);
+    gen_save_pc(ctx->base.pc_next);
+    gen_helper_qemu_excp(cpu_env, tmp);
+    ctx->base.is_jmp = DISAS_NORETURN;
+    tcg_temp_free(tmp);
+}
+
 static inline void gen_branch_cond(DisasContext *ctx, TCGCond cond, TCGv r1,
                                    TCGv r2, int16_t address)
 {
     TCGLabel *jumpLabel = gen_new_label();
     tcg_gen_brcond_tl(cond, r1, r2, jumpLabel);
 
-    gen_goto_tb(ctx, 1, ctx->next_pc);
+    gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
 
     gen_set_label(jumpLabel);
-    gen_goto_tb(ctx, 0, ctx->pc + address * 2);
+    gen_goto_tb(ctx, 0, ctx->base.pc_next + address * 2);
 }
 
 static inline void gen_branch_condi(DisasContext *ctx, TCGCond cond, TCGv r1,
@@ -3295,9 +3296,9 @@ static void gen_loop(DisasContext *ctx, int r1, int32_t offset)
 
     tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1);
-    gen_goto_tb(ctx, 1, ctx->pc + offset);
+    gen_goto_tb(ctx, 1, ctx->base.pc_next + offset);
     gen_set_label(l1);
-    gen_goto_tb(ctx, 0, ctx->next_pc);
+    gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
 }
 
 static void gen_fcall_save_ctx(DisasContext *ctx)
@@ -3306,7 +3307,7 @@ static void gen_fcall_save_ctx(DisasContext *ctx)
 
     tcg_gen_addi_tl(temp, cpu_gpr_a[10], -4);
     tcg_gen_qemu_st_tl(cpu_gpr_a[11], temp, ctx->mem_idx, MO_LESL);
-    tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+    tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
     tcg_gen_mov_tl(cpu_gpr_a[10], temp);
 
     tcg_temp_free(temp);
@@ -3321,7 +3322,7 @@ static void gen_fret(DisasContext *ctx)
     tcg_gen_addi_tl(cpu_gpr_a[10], cpu_gpr_a[10], 4);
     tcg_gen_mov_tl(cpu_PC, temp);
     tcg_gen_exit_tb(NULL, 0);
-    ctx->bstate = BS_BRANCH;
+    ctx->base.is_jmp = DISAS_NORETURN;
 
     tcg_temp_free(temp);
 }
@@ -3336,12 +3337,12 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
 /* SB-format jumps */
     case OPC1_16_SB_J:
     case OPC1_32_B_J:
-        gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+        gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
         break;
     case OPC1_32_B_CALL:
     case OPC1_16_SB_CALL:
-        gen_helper_1arg(call, ctx->next_pc);
-        gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+        gen_helper_1arg(call, ctx->pc_succ_insn);
+        gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
         break;
     case OPC1_16_SB_JZ:
         gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], 0, offset);
@@ -3433,26 +3434,26 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
         break;
 /* B-format */
     case OPC1_32_B_CALLA:
-        gen_helper_1arg(call, ctx->next_pc);
+        gen_helper_1arg(call, ctx->pc_succ_insn);
         gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
         break;
     case OPC1_32_B_FCALL:
         gen_fcall_save_ctx(ctx);
-        gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+        gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
         break;
     case OPC1_32_B_FCALLA:
         gen_fcall_save_ctx(ctx);
         gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
         break;
     case OPC1_32_B_JLA:
-        tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+        tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
         /* fall through */
     case OPC1_32_B_JA:
         gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
         break;
     case OPC1_32_B_JL:
-        tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
-        gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+        tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
+        gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
         break;
 /* BOL format */
     case OPCM_32_BRC_EQ_NEQ:
@@ -3551,7 +3552,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
             gen_loop(ctx, r2, offset * 2);
         } else {
             /* OPC2_32_BRR_LOOPU */
-            gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+            gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
         }
         break;
     case OPCM_32_BRR_JNE:
@@ -3585,7 +3586,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
     default:
         generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
     }
-    ctx->bstate = BS_BRANCH;
+    ctx->base.is_jmp = DISAS_NORETURN;
 }
 
 
@@ -3593,7 +3594,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
  * Functions for decoding instructions
  */
 
-static void decode_src_opc(CPUTriCoreState *env, DisasContext *ctx, int op1)
+static void decode_src_opc(DisasContext *ctx, int op1)
 {
     int r1;
     int32_t const4;
@@ -3655,7 +3656,7 @@ static void decode_src_opc(CPUTriCoreState *env, DisasContext *ctx, int op1)
         tcg_gen_movi_tl(cpu_gpr_a[r1], const4);
         break;
     case OPC1_16_SRC_MOV_E:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
             tcg_gen_sari_tl(cpu_gpr_d[r1+1], cpu_gpr_d[r1], 31);
         } else {
@@ -3919,7 +3920,7 @@ static void decode_sro_opc(DisasContext *ctx, int op1)
     }
 }
 
-static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_sr_system(DisasContext *ctx)
 {
     uint32_t op2;
     op2 = MASK_OP_SR_OP2(ctx->opcode);
@@ -3933,7 +3934,7 @@ static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx)
     case OPC2_16_SR_RFE:
         gen_helper_rfe(cpu_env);
         tcg_gen_exit_tb(NULL, 0);
-        ctx->bstate = BS_BRANCH;
+        ctx->base.is_jmp = DISAS_NORETURN;
         break;
     case OPC2_16_SR_DEBUG:
         /* raise EXCP_DEBUG */
@@ -3946,7 +3947,7 @@ static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_sr_accu(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_sr_accu(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t r1;
@@ -3990,7 +3991,7 @@ static void decode_sr_accu(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_16Bit_opc(DisasContext *ctx)
 {
     int op1;
     int r1, r2;
@@ -4021,7 +4022,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
     case OPC1_16_SRC_MOV_E:
     case OPC1_16_SRC_SH:
     case OPC1_16_SRC_SHA:
-        decode_src_opc(env, ctx, op1);
+        decode_src_opc(ctx, op1);
         break;
 /* SRR-format */
     case OPC1_16_SRR_ADD:
@@ -4106,7 +4107,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
         break;
     case OPC1_16_SBC_JEQ2:
     case OPC1_16_SBC_JNE2:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             address = MASK_OP_SBC_DISP4(ctx->opcode);
             const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
             gen_compute_branch(ctx, op1, 0, 0, const16, address);
@@ -4124,7 +4125,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
 /* SBR-format */
     case OPC1_16_SBR_JEQ2:
     case OPC1_16_SBR_JNE2:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             r1 = MASK_OP_SBR_S2(ctx->opcode);
             address = MASK_OP_SBR_DISP4(ctx->opcode);
             gen_compute_branch(ctx, op1, r1, 0, 0, address);
@@ -4204,10 +4205,10 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
         break;
 /* SR-format */
     case OPCM_16_SR_SYSTEM:
-        decode_sr_system(env, ctx);
+        decode_sr_system(ctx);
         break;
     case OPCM_16_SR_ACCU:
-        decode_sr_accu(env, ctx);
+        decode_sr_accu(ctx);
         break;
     case OPC1_16_SR_JI:
         r1 = MASK_OP_SR_S1D(ctx->opcode);
@@ -4227,7 +4228,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
  */
 
 /* ABS-format */
-static void decode_abs_ldw(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_abs_ldw(DisasContext *ctx)
 {
     int32_t op2;
     int32_t r1;
@@ -4262,7 +4263,7 @@ static void decode_abs_ldw(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp);
 }
 
-static void decode_abs_ldb(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_abs_ldb(DisasContext *ctx)
 {
     int32_t op2;
     int32_t r1;
@@ -4295,7 +4296,7 @@ static void decode_abs_ldb(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp);
 }
 
-static void decode_abs_ldst_swap(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_abs_ldst_swap(DisasContext *ctx)
 {
     int32_t op2;
     int32_t r1;
@@ -4322,7 +4323,7 @@ static void decode_abs_ldst_swap(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp);
 }
 
-static void decode_abs_ldst_context(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_abs_ldst_context(DisasContext *ctx)
 {
     uint32_t op2;
     int32_t off18;
@@ -4348,7 +4349,7 @@ static void decode_abs_ldst_context(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_abs_store(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_abs_store(DisasContext *ctx)
 {
     int32_t op2;
     int32_t r1;
@@ -4382,7 +4383,7 @@ static void decode_abs_store(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp);
 }
 
-static void decode_abs_storeb_h(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_abs_storeb_h(DisasContext *ctx)
 {
     int32_t op2;
     int32_t r1;
@@ -4410,7 +4411,7 @@ static void decode_abs_storeb_h(CPUTriCoreState *env, DisasContext *ctx)
 
 /* Bit-format */
 
-static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_bit_andacc(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3;
@@ -4451,7 +4452,7 @@ static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_bit_logical_t(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3;
@@ -4485,7 +4486,7 @@ static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_bit_insert(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_bit_insert(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3;
@@ -4508,7 +4509,7 @@ static void decode_bit_insert(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp);
 }
 
-static void decode_bit_logical_t2(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_bit_logical_t2(DisasContext *ctx)
 {
     uint32_t op2;
 
@@ -4544,7 +4545,7 @@ static void decode_bit_logical_t2(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_bit_orand(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_bit_orand(DisasContext *ctx)
 {
     uint32_t op2;
 
@@ -4585,7 +4586,7 @@ static void decode_bit_orand(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_bit_sh_logic1(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_bit_sh_logic1(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3;
@@ -4626,7 +4627,7 @@ static void decode_bit_sh_logic1(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp);
 }
 
-static void decode_bit_sh_logic2(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_bit_sh_logic2(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3;
@@ -4670,8 +4671,7 @@ static void decode_bit_sh_logic2(CPUTriCoreState *env, DisasContext *ctx)
 /* BO-format */
 
 
-static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
-                                             DisasContext *ctx)
+static void decode_bo_addrmode_post_pre_base(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t off10;
@@ -4705,13 +4705,13 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
         break;
     case OPC2_32_BO_CACHEI_WI_SHORTOFF:
     case OPC2_32_BO_CACHEI_W_SHORTOFF:
-        if (!tricore_feature(env, TRICORE_FEATURE_131)) {
+        if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
             generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
         }
         break;
     case OPC2_32_BO_CACHEI_W_POSTINC:
     case OPC2_32_BO_CACHEI_WI_POSTINC:
-        if (tricore_feature(env, TRICORE_FEATURE_131)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
             tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
         } else {
             generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
@@ -4719,7 +4719,7 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
         break;
     case OPC2_32_BO_CACHEI_W_PREINC:
     case OPC2_32_BO_CACHEI_WI_PREINC:
-        if (tricore_feature(env, TRICORE_FEATURE_131)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
             tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
         } else {
             generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
@@ -4830,8 +4830,7 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
     }
 }
 
-static void decode_bo_addrmode_bitreverse_circular(CPUTriCoreState *env,
-                                                   DisasContext *ctx)
+static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t off10;
@@ -4941,8 +4940,7 @@ static void decode_bo_addrmode_bitreverse_circular(CPUTriCoreState *env,
     tcg_temp_free(temp3);
 }
 
-static void decode_bo_addrmode_ld_post_pre_base(CPUTriCoreState *env,
-                                                DisasContext *ctx)
+static void decode_bo_addrmode_ld_post_pre_base(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t off10;
@@ -5076,8 +5074,7 @@ static void decode_bo_addrmode_ld_post_pre_base(CPUTriCoreState *env,
     }
 }
 
-static void decode_bo_addrmode_ld_bitreverse_circular(CPUTriCoreState *env,
-                                                DisasContext *ctx)
+static void decode_bo_addrmode_ld_bitreverse_circular(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t off10;
@@ -5195,8 +5192,7 @@ static void decode_bo_addrmode_ld_bitreverse_circular(CPUTriCoreState *env,
     tcg_temp_free(temp3);
 }
 
-static void decode_bo_addrmode_stctx_post_pre_base(CPUTriCoreState *env,
-                                                   DisasContext *ctx)
+static void decode_bo_addrmode_stctx_post_pre_base(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t off10;
@@ -5288,8 +5284,7 @@ static void decode_bo_addrmode_stctx_post_pre_base(CPUTriCoreState *env,
     tcg_temp_free(temp2);
 }
 
-static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env,
-                                                         DisasContext *ctx)
+static void decode_bo_addrmode_ldmst_bitreverse_circular(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t off10;
@@ -5351,7 +5346,7 @@ static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env,
     tcg_temp_free(temp3);
 }
 
-static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
+static void decode_bol_opc(DisasContext *ctx, int32_t op1)
 {
     int r1, r2;
     int32_t address;
@@ -5378,7 +5373,7 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
         tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], address);
         break;
     case OPC1_32_BOL_ST_A_LONGOFF:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], address, MO_LEUL);
         } else {
             generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
@@ -5388,42 +5383,42 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
         gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUL);
         break;
     case OPC1_32_BOL_LD_B_LONGOFF:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);
         } else {
             generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
         }
         break;
     case OPC1_32_BOL_LD_BU_LONGOFF:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_UB);
         } else {
             generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
         }
         break;
     case OPC1_32_BOL_LD_H_LONGOFF:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
         } else {
             generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
         }
         break;
     case OPC1_32_BOL_LD_HU_LONGOFF:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUW);
         } else {
             generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
         }
         break;
     case OPC1_32_BOL_ST_B_LONGOFF:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);
         } else {
             generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
         }
         break;
     case OPC1_32_BOL_ST_H_LONGOFF:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
         } else {
             generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
@@ -5435,7 +5430,7 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
 }
 
 /* RC format */
-static void decode_rc_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rc_logical_shift(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2;
@@ -5502,7 +5497,7 @@ static void decode_rc_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp);
 }
 
-static void decode_rc_accumulator(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rc_accumulator(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2;
@@ -5702,7 +5697,7 @@ static void decode_rc_accumulator(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp);
 }
 
-static void decode_rc_serviceroutine(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rc_serviceroutine(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t const9;
@@ -5722,7 +5717,7 @@ static void decode_rc_serviceroutine(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rc_mul(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2;
@@ -5760,7 +5755,7 @@ static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx)
 }
 
 /* RCPW format */
-static void decode_rcpw_insert(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rcpw_insert(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2;
@@ -5799,7 +5794,7 @@ static void decode_rcpw_insert(CPUTriCoreState *env, DisasContext *ctx)
 
 /* RCRW format */
 
-static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rcrw_insert(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r3, r4;
@@ -5844,7 +5839,7 @@ static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx)
 
 /* RCR format */
 
-static void decode_rcr_cond_select(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rcr_cond_select(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r3, r4;
@@ -5888,7 +5883,7 @@ static void decode_rcr_cond_select(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rcr_madd(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r3, r4;
@@ -5943,7 +5938,7 @@ static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rcr_msub(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r3, r4;
@@ -6000,7 +5995,7 @@ static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx)
 
 /* RLC format */
 
-static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
+static void decode_rlc_opc(DisasContext *ctx,
                            uint32_t op1)
 {
     int32_t const16;
@@ -6022,13 +6017,13 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
         break;
     case OPC1_32_RLC_MFCR:
         const16 = MASK_OP_RLC_CONST16(ctx->opcode);
-        gen_mfcr(env, cpu_gpr_d[r2], const16);
+        gen_mfcr(ctx, cpu_gpr_d[r2], const16);
         break;
     case OPC1_32_RLC_MOV:
         tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
         break;
     case OPC1_32_RLC_MOV_64:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             CHECK_REG_PAIR(r2);
             tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
             tcg_gen_movi_tl(cpu_gpr_d[r2+1], const16 >> 15);
@@ -6048,7 +6043,7 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
         break;
     case OPC1_32_RLC_MTCR:
         const16 = MASK_OP_RLC_CONST16(ctx->opcode);
-        gen_mtcr(env, ctx, cpu_gpr_d[r1], const16);
+        gen_mtcr(ctx, cpu_gpr_d[r1], const16);
         break;
     default:
         generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
@@ -6056,7 +6051,7 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
 }
 
 /* RR format */
-static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rr_accumulator(DisasContext *ctx)
 {
     uint32_t op2;
     int r3, r2, r1;
@@ -6254,7 +6249,7 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx)
         tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
         break;
     case OPC2_32_RR_MOV_64:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             temp = tcg_temp_new();
 
             CHECK_REG_PAIR(r3);
@@ -6268,7 +6263,7 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx)
         }
         break;
     case OPC2_32_RR_MOVS_64:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             CHECK_REG_PAIR(r3);
             tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
             tcg_gen_sari_tl(cpu_gpr_d[r3 + 1], cpu_gpr_d[r2], 31);
@@ -6398,7 +6393,7 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_rr_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rr_logical_shift(DisasContext *ctx)
 {
     uint32_t op2;
     int r3, r2, r1;
@@ -6476,7 +6471,7 @@ static void decode_rr_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp);
 }
 
-static void decode_rr_address(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rr_address(DisasContext *ctx)
 {
     uint32_t op2, n;
     int r1, r2, r3;
@@ -6544,7 +6539,7 @@ static void decode_rr_address(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rr_idirect(DisasContext *ctx)
 {
     uint32_t op2;
     int r1;
@@ -6557,11 +6552,11 @@ static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx)
         tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
         break;
     case OPC2_32_RR_JLI:
-        tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+        tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
         tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
         break;
     case OPC2_32_RR_CALLI:
-        gen_helper_1arg(call, ctx->next_pc);
+        gen_helper_1arg(call, ctx->pc_succ_insn);
         tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
         break;
     case OPC2_32_RR_FCALLI:
@@ -6572,10 +6567,10 @@ static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx)
         generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
     }
     tcg_gen_exit_tb(NULL, 0);
-    ctx->bstate = BS_BRANCH;
+    ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rr_divide(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3;
@@ -6597,7 +6592,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
         break;
     case OPC2_32_RR_DVINIT_B:
         CHECK_REG_PAIR(r3);
-        gen_dvinit_b(env, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
+        gen_dvinit_b(ctx, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
                      cpu_gpr_d[r2]);
         break;
     case OPC2_32_RR_DVINIT_BU:
@@ -6608,7 +6603,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
         tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 8);
         /* reset av */
         tcg_gen_movi_tl(cpu_PSW_AV, 0);
-        if (!tricore_feature(env, TRICORE_FEATURE_131)) {
+        if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
             /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
             tcg_gen_abs_tl(temp, temp3);
             tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
@@ -6630,7 +6625,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
         break;
     case OPC2_32_RR_DVINIT_H:
         CHECK_REG_PAIR(r3);
-        gen_dvinit_h(env, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
+        gen_dvinit_h(ctx, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
                      cpu_gpr_d[r2]);
         break;
     case OPC2_32_RR_DVINIT_HU:
@@ -6641,7 +6636,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
         tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 16);
         /* reset av */
         tcg_gen_movi_tl(cpu_PSW_AV, 0);
-        if (!tricore_feature(env, TRICORE_FEATURE_131)) {
+        if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
             /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
             tcg_gen_abs_tl(temp, temp3);
             tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
@@ -6704,14 +6699,14 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
         gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
         break;
     case OPC2_32_RR_CRC32:
-        if (tricore_feature(env, TRICORE_FEATURE_161)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_161)) {
             gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
         } else {
             generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
         }
         break;
     case OPC2_32_RR_DIV:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
                           cpu_gpr_d[r2]);
         } else {
@@ -6719,7 +6714,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
         }
         break;
     case OPC2_32_RR_DIV_U:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1],
                           cpu_gpr_d[r1], cpu_gpr_d[r2]);
         } else {
@@ -6762,7 +6757,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
 }
 
 /* RR1 Format */
-static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rr1_mul(DisasContext *ctx)
 {
     uint32_t op2;
 
@@ -6876,7 +6871,7 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(n);
 }
 
-static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rr1_mulq(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3;
@@ -6948,7 +6943,7 @@ static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx)
 }
 
 /* RR2 format */
-static void decode_rr2_mul(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rr2_mul(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3;
@@ -6985,7 +6980,7 @@ static void decode_rr2_mul(CPUTriCoreState *env, DisasContext *ctx)
 }
 
 /* RRPW format */
-static void decode_rrpw_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrpw_extract_insert(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3;
@@ -7039,7 +7034,7 @@ static void decode_rrpw_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
 }
 
 /* RRR format */
-static void decode_rrr_cond_select(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrr_cond_select(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3, r4;
@@ -7085,7 +7080,7 @@ static void decode_rrr_cond_select(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrr_divide(DisasContext *ctx)
 {
     uint32_t op2;
 
@@ -7165,7 +7160,7 @@ static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx)
 }
 
 /* RRR2 format */
-static void decode_rrr2_madd(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrr2_madd(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t r1, r2, r3, r4;
@@ -7217,7 +7212,7 @@ static void decode_rrr2_madd(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_rrr2_msub(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrr2_msub(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t r1, r2, r3, r4;
@@ -7269,7 +7264,7 @@ static void decode_rrr2_msub(CPUTriCoreState *env, DisasContext *ctx)
 }
 
 /* RRR1 format */
-static void decode_rrr1_madd(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrr1_madd(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t r1, r2, r3, r4, n;
@@ -7415,7 +7410,7 @@ static void decode_rrr1_madd(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrr1_maddq_h(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t r1, r2, r3, r4, n;
@@ -7434,19 +7429,19 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
     switch (op2) {
     case OPC2_32_RRR1_MADD_Q_32:
         gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
-                     cpu_gpr_d[r2], n, 32, env);
+                     cpu_gpr_d[r2], n, 32);
         break;
     case OPC2_32_RRR1_MADD_Q_64:
         CHECK_REG_PAIR(r4);
         CHECK_REG_PAIR(r3);
         gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
                      cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
-                     n, env);
+                     n);
         break;
     case OPC2_32_RRR1_MADD_Q_32_L:
         tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
         gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
-                     temp, n, 16, env);
+                     temp, n, 16);
         break;
     case OPC2_32_RRR1_MADD_Q_64_L:
         CHECK_REG_PAIR(r4);
@@ -7454,12 +7449,12 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
         tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
         gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
                      cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
-                     n, env);
+                     n);
         break;
     case OPC2_32_RRR1_MADD_Q_32_U:
         tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
         gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
-                     temp, n, 16, env);
+                     temp, n, 16);
         break;
     case OPC2_32_RRR1_MADD_Q_64_U:
         CHECK_REG_PAIR(r4);
@@ -7467,7 +7462,7 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
         tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
         gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
                      cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
-                     n, env);
+                     n);
         break;
     case OPC2_32_RRR1_MADD_Q_32_LL:
         tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
@@ -7595,7 +7590,7 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp2);
 }
 
-static void decode_rrr1_maddsu_h(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrr1_maddsu_h(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t r1, r2, r3, r4, n;
@@ -7753,7 +7748,7 @@ static void decode_rrr1_maddsu_h(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_rrr1_msub(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrr1_msub(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t r1, r2, r3, r4, n;
@@ -7899,7 +7894,7 @@ static void decode_rrr1_msub(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrr1_msubq_h(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t r1, r2, r3, r4, n;
@@ -7918,19 +7913,19 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
     switch (op2) {
     case OPC2_32_RRR1_MSUB_Q_32:
         gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
-                     cpu_gpr_d[r2], n, 32, env);
+                     cpu_gpr_d[r2], n, 32);
         break;
     case OPC2_32_RRR1_MSUB_Q_64:
         CHECK_REG_PAIR(r4);
         CHECK_REG_PAIR(r3);
         gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
                      cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
-                     n, env);
+                     n);
         break;
     case OPC2_32_RRR1_MSUB_Q_32_L:
         tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
         gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
-                     temp, n, 16, env);
+                     temp, n, 16);
         break;
     case OPC2_32_RRR1_MSUB_Q_64_L:
         CHECK_REG_PAIR(r4);
@@ -7938,12 +7933,12 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
         tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
         gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
                      cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
-                     n, env);
+                     n);
         break;
     case OPC2_32_RRR1_MSUB_Q_32_U:
         tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
         gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
-                     temp, n, 16, env);
+                     temp, n, 16);
         break;
     case OPC2_32_RRR1_MSUB_Q_64_U:
         CHECK_REG_PAIR(r4);
@@ -7951,7 +7946,7 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
         tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
         gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
                      cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
-                     n, env);
+                     n);
         break;
     case OPC2_32_RRR1_MSUB_Q_32_LL:
         tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
@@ -8079,7 +8074,7 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp2);
 }
 
-static void decode_rrr1_msubad_h(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrr1_msubad_h(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t r1, r2, r3, r4, n;
@@ -8238,7 +8233,7 @@ static void decode_rrr1_msubad_h(CPUTriCoreState *env, DisasContext *ctx)
 }
 
 /* RRRR format */
-static void decode_rrrr_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrrr_extract_insert(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3, r4;
@@ -8295,7 +8290,7 @@ static void decode_rrrr_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
 }
 
 /* RRRW format */
-static void decode_rrrw_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_rrrw_extract_insert(DisasContext *ctx)
 {
     uint32_t op2;
     int r1, r2, r3, r4;
@@ -8356,7 +8351,7 @@ static void decode_rrrw_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
 }
 
 /* SYS Format*/
-static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_sys_interrupts(DisasContext *ctx)
 {
     uint32_t op2;
     uint32_t r1;
@@ -8391,7 +8386,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx)
     case OPC2_32_SYS_RFE:
         gen_helper_rfe(cpu_env);
         tcg_gen_exit_tb(NULL, 0);
-        ctx->bstate = BS_BRANCH;
+        ctx->base.is_jmp = DISAS_NORETURN;
         break;
     case OPC2_32_SYS_RFM:
         if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) {
@@ -8404,7 +8399,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx)
             gen_helper_rfm(cpu_env);
             gen_set_label(l1);
             tcg_gen_exit_tb(NULL, 0);
-            ctx->bstate = BS_BRANCH;
+            ctx->base.is_jmp = DISAS_NORETURN;
             tcg_temp_free(tmp);
         } else {
             /* generate privilege trap */
@@ -8417,7 +8412,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx)
         gen_helper_svlcx(cpu_env);
         break;
     case OPC2_32_SYS_RESTORE:
-        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
             if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM ||
                 (ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_UM1) {
                 tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1);
@@ -8443,7 +8438,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
+static void decode_32Bit_opc(DisasContext *ctx)
 {
     int op1;
     int32_t r1, r2, r3;
@@ -8462,22 +8457,22 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
     switch (op1) {
 /* ABS-format */
     case OPCM_32_ABS_LDW:
-        decode_abs_ldw(env, ctx);
+        decode_abs_ldw(ctx);
         break;
     case OPCM_32_ABS_LDB:
-        decode_abs_ldb(env, ctx);
+        decode_abs_ldb(ctx);
         break;
     case OPCM_32_ABS_LDMST_SWAP:
-        decode_abs_ldst_swap(env, ctx);
+        decode_abs_ldst_swap(ctx);
         break;
     case OPCM_32_ABS_LDST_CONTEXT:
-        decode_abs_ldst_context(env, ctx);
+        decode_abs_ldst_context(ctx);
         break;
     case OPCM_32_ABS_STORE:
-        decode_abs_store(env, ctx);
+        decode_abs_store(ctx);
         break;
     case OPCM_32_ABS_STOREB_H:
-        decode_abs_storeb_h(env, ctx);
+        decode_abs_storeb_h(ctx);
         break;
     case OPC1_32_ABS_STOREQ:
         address = MASK_OP_ABS_OFF18(ctx->opcode);
@@ -8537,44 +8532,44 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
         break;
 /* Bit-format */
     case OPCM_32_BIT_ANDACC:
-        decode_bit_andacc(env, ctx);
+        decode_bit_andacc(ctx);
         break;
     case OPCM_32_BIT_LOGICAL_T1:
-        decode_bit_logical_t(env, ctx);
+        decode_bit_logical_t(ctx);
         break;
     case OPCM_32_BIT_INSERT:
-        decode_bit_insert(env, ctx);
+        decode_bit_insert(ctx);
         break;
     case OPCM_32_BIT_LOGICAL_T2:
-        decode_bit_logical_t2(env, ctx);
+        decode_bit_logical_t2(ctx);
         break;
     case OPCM_32_BIT_ORAND:
-        decode_bit_orand(env, ctx);
+        decode_bit_orand(ctx);
         break;
     case OPCM_32_BIT_SH_LOGIC1:
-        decode_bit_sh_logic1(env, ctx);
+        decode_bit_sh_logic1(ctx);
         break;
     case OPCM_32_BIT_SH_LOGIC2:
-        decode_bit_sh_logic2(env, ctx);
+        decode_bit_sh_logic2(ctx);
         break;
     /* BO Format */
     case OPCM_32_BO_ADDRMODE_POST_PRE_BASE:
-        decode_bo_addrmode_post_pre_base(env, ctx);
+        decode_bo_addrmode_post_pre_base(ctx);
         break;
     case OPCM_32_BO_ADDRMODE_BITREVERSE_CIRCULAR:
-        decode_bo_addrmode_bitreverse_circular(env, ctx);
+        decode_bo_addrmode_bitreverse_circular(ctx);
         break;
     case OPCM_32_BO_ADDRMODE_LD_POST_PRE_BASE:
-        decode_bo_addrmode_ld_post_pre_base(env, ctx);
+        decode_bo_addrmode_ld_post_pre_base(ctx);
         break;
     case OPCM_32_BO_ADDRMODE_LD_BITREVERSE_CIRCULAR:
-        decode_bo_addrmode_ld_bitreverse_circular(env, ctx);
+        decode_bo_addrmode_ld_bitreverse_circular(ctx);
         break;
     case OPCM_32_BO_ADDRMODE_STCTX_POST_PRE_BASE:
-        decode_bo_addrmode_stctx_post_pre_base(env, ctx);
+        decode_bo_addrmode_stctx_post_pre_base(ctx);
         break;
     case OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR:
-        decode_bo_addrmode_ldmst_bitreverse_circular(env, ctx);
+        decode_bo_addrmode_ldmst_bitreverse_circular(ctx);
         break;
 /* BOL-format */
     case OPC1_32_BOL_LD_A_LONGOFF:
@@ -8588,7 +8583,7 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
     case OPC1_32_BOL_LD_HU_LONGOFF:
     case OPC1_32_BOL_ST_B_LONGOFF:
     case OPC1_32_BOL_ST_H_LONGOFF:
-        decode_bol_opc(env, ctx, op1);
+        decode_bol_opc(ctx, op1);
         break;
 /* BRC Format */
     case OPCM_32_BRC_EQ_NEQ:
@@ -8621,20 +8616,20 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
         break;
 /* RC Format */
     case OPCM_32_RC_LOGICAL_SHIFT:
-        decode_rc_logical_shift(env, ctx);
+        decode_rc_logical_shift(ctx);
         break;
     case OPCM_32_RC_ACCUMULATOR:
-        decode_rc_accumulator(env, ctx);
+        decode_rc_accumulator(ctx);
         break;
     case OPCM_32_RC_SERVICEROUTINE:
-        decode_rc_serviceroutine(env, ctx);
+        decode_rc_serviceroutine(ctx);
         break;
     case OPCM_32_RC_MUL:
-        decode_rc_mul(env, ctx);
+        decode_rc_mul(ctx);
         break;
 /* RCPW Format */
     case OPCM_32_RCPW_MASK_INSERT:
-        decode_rcpw_insert(env, ctx);
+        decode_rcpw_insert(ctx);
         break;
 /* RCRR Format */
     case OPC1_32_RCRR_INSERT:
@@ -8659,17 +8654,17 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
         break;
 /* RCRW Format */
     case OPCM_32_RCRW_MASK_INSERT:
-        decode_rcrw_insert(env, ctx);
+        decode_rcrw_insert(ctx);
         break;
 /* RCR Format */
     case OPCM_32_RCR_COND_SELECT:
-        decode_rcr_cond_select(env, ctx);
+        decode_rcr_cond_select(ctx);
         break;
     case OPCM_32_RCR_MADD:
-        decode_rcr_madd(env, ctx);
+        decode_rcr_madd(ctx);
         break;
     case OPCM_32_RCR_MSUB:
-        decode_rcr_msub(env, ctx);
+        decode_rcr_msub(ctx);
         break;
 /* RLC Format */
     case OPC1_32_RLC_ADDI:
@@ -8682,38 +8677,38 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
     case OPC1_32_RLC_MOV_H:
     case OPC1_32_RLC_MOVH_A:
     case OPC1_32_RLC_MTCR:
-        decode_rlc_opc(env, ctx, op1);
+        decode_rlc_opc(ctx, op1);
         break;
 /* RR Format */
     case OPCM_32_RR_ACCUMULATOR:
-        decode_rr_accumulator(env, ctx);
+        decode_rr_accumulator(ctx);
         break;
     case OPCM_32_RR_LOGICAL_SHIFT:
-        decode_rr_logical_shift(env, ctx);
+        decode_rr_logical_shift(ctx);
         break;
     case OPCM_32_RR_ADDRESS:
-        decode_rr_address(env, ctx);
+        decode_rr_address(ctx);
         break;
     case OPCM_32_RR_IDIRECT:
-        decode_rr_idirect(env, ctx);
+        decode_rr_idirect(ctx);
         break;
     case OPCM_32_RR_DIVIDE:
-        decode_rr_divide(env, ctx);
+        decode_rr_divide(ctx);
         break;
 /* RR1 Format */
     case OPCM_32_RR1_MUL:
-        decode_rr1_mul(env, ctx);
+        decode_rr1_mul(ctx);
         break;
     case OPCM_32_RR1_MULQ:
-        decode_rr1_mulq(env, ctx);
+        decode_rr1_mulq(ctx);
         break;
 /* RR2 format */
     case OPCM_32_RR2_MUL:
-        decode_rr2_mul(env, ctx);
+        decode_rr2_mul(ctx);
         break;
 /* RRPW format */
     case OPCM_32_RRPW_EXTRACT_INSERT:
-        decode_rrpw_extract_insert(env, ctx);
+        decode_rrpw_extract_insert(ctx);
         break;
     case OPC1_32_RRPW_DEXTR:
         r1 = MASK_OP_RRPW_S1(ctx->opcode);
@@ -8732,48 +8727,48 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
         break;
 /* RRR Format */
     case OPCM_32_RRR_COND_SELECT:
-        decode_rrr_cond_select(env, ctx);
+        decode_rrr_cond_select(ctx);
         break;
     case OPCM_32_RRR_DIVIDE:
-        decode_rrr_divide(env, ctx);
+        decode_rrr_divide(ctx);
         break;
 /* RRR2 Format */
     case OPCM_32_RRR2_MADD:
-        decode_rrr2_madd(env, ctx);
+        decode_rrr2_madd(ctx);
         break;
     case OPCM_32_RRR2_MSUB:
-        decode_rrr2_msub(env, ctx);
+        decode_rrr2_msub(ctx);
         break;
 /* RRR1 format */
     case OPCM_32_RRR1_MADD:
-        decode_rrr1_madd(env, ctx);
+        decode_rrr1_madd(ctx);
         break;
     case OPCM_32_RRR1_MADDQ_H:
-        decode_rrr1_maddq_h(env, ctx);
+        decode_rrr1_maddq_h(ctx);
         break;
     case OPCM_32_RRR1_MADDSU_H:
-        decode_rrr1_maddsu_h(env, ctx);
+        decode_rrr1_maddsu_h(ctx);
         break;
     case OPCM_32_RRR1_MSUB_H:
-        decode_rrr1_msub(env, ctx);
+        decode_rrr1_msub(ctx);
         break;
     case OPCM_32_RRR1_MSUB_Q:
-        decode_rrr1_msubq_h(env, ctx);
+        decode_rrr1_msubq_h(ctx);
         break;
     case OPCM_32_RRR1_MSUBAD_H:
-        decode_rrr1_msubad_h(env, ctx);
+        decode_rrr1_msubad_h(ctx);
         break;
 /* RRRR format */
     case OPCM_32_RRRR_EXTRACT_INSERT:
-        decode_rrrr_extract_insert(env, ctx);
+        decode_rrrr_extract_insert(ctx);
         break;
 /* RRRW format */
     case OPCM_32_RRRW_EXTRACT_INSERT:
-        decode_rrrw_extract_insert(env, ctx);
+        decode_rrrw_extract_insert(ctx);
         break;
 /* SYS format */
     case OPCM_32_SYS_INTERRUPTS:
-        decode_sys_interrupts(env, ctx);
+        decode_sys_interrupts(ctx);
         break;
     case OPC1_32_SYS_RSTV:
         tcg_gen_movi_tl(cpu_PSW_V, 0);
@@ -8786,70 +8781,130 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
-static void decode_opc(CPUTriCoreState *env, DisasContext *ctx, int *is_branch)
+static bool tricore_insn_is_16bit(uint32_t insn)
 {
-    /* 16-Bit Instruction */
-    if ((ctx->opcode & 0x1) == 0) {
-        ctx->next_pc = ctx->pc + 2;
-        decode_16Bit_opc(env, ctx);
-    /* 32-Bit Instruction */
-    } else {
-        ctx->next_pc = ctx->pc + 4;
-        decode_32Bit_opc(env, ctx);
-    }
+    return (insn & 0x1) == 0;
 }
 
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+static void tricore_tr_init_disas_context(DisasContextBase *dcbase,
+                                          CPUState *cs)
 {
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
     CPUTriCoreState *env = cs->env_ptr;
-    DisasContext ctx;
-    target_ulong pc_start;
-    int num_insns = 0;
-
-    pc_start = tb->pc;
-    ctx.pc = pc_start;
-    ctx.saved_pc = -1;
-    ctx.tb = tb;
-    ctx.singlestep_enabled = cs->singlestep_enabled;
-    ctx.bstate = BS_NONE;
-    ctx.mem_idx = cpu_mmu_index(env, false);
-    ctx.hflags = (uint32_t)tb->flags;
-
-    tcg_clear_temp_count();
-    gen_tb_start(tb);
-    while (ctx.bstate == BS_NONE) {
-        tcg_gen_insn_start(ctx.pc);
-        num_insns++;
-
-        ctx.opcode = cpu_ldl_code(env, ctx.pc);
-        decode_opc(env, &ctx, 0);
-
-        if (num_insns >= max_insns || tcg_op_buf_full()) {
-            gen_save_pc(ctx.next_pc);
-            tcg_gen_exit_tb(NULL, 0);
-            break;
-        }
-        ctx.pc = ctx.next_pc;
+    ctx->mem_idx = cpu_mmu_index(env, false);
+    ctx->hflags = (uint32_t)ctx->base.tb->flags;
+}
+
+static void tricore_tr_tb_start(DisasContextBase *db, CPUState *cpu)
+{
+}
+
+static void tricore_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
+{
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+    tcg_gen_insn_start(ctx->base.pc_next);
+}
+
+static bool tricore_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
+                                      const CPUBreakpoint *bp)
+{
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
+    generate_qemu_excp(ctx, EXCP_DEBUG);
+    /*
+     * The address covered by the breakpoint must be included in
+     * [tb->pc, tb->pc + tb->size) in order to for it to be
+     * properly cleared -- thus we increment the PC here so that
+     * the logic setting tb->size below does the right thing.
+     */
+    ctx->base.pc_next += 4;
+    return true;
+}
+
+static bool insn_crosses_page(CPUTriCoreState *env, DisasContext *ctx)
+{
+    /*
+     * Return true if the insn at ctx->base.pc_next might cross a page boundary.
+     * (False positives are OK, false negatives are not.)
+     * Our caller ensures we are only called if dc->base.pc_next is less than
+     * 4 bytes from the page boundary, so we cross the page if the first
+     * 16 bits indicate that this is a 32 bit insn.
+     */
+    uint16_t insn = cpu_lduw_code(env, ctx->base.pc_next);
+
+    return !tricore_insn_is_16bit(insn);
+}
+
+
+static void tricore_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
+{
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
+    CPUTriCoreState *env = cpu->env_ptr;
+    uint16_t insn_lo;
+    bool is_16bit;
+
+    insn_lo = cpu_lduw_code(env, ctx->base.pc_next);
+    is_16bit = tricore_insn_is_16bit(insn_lo);
+    if (is_16bit) {
+        ctx->opcode = insn_lo;
+        ctx->pc_succ_insn = ctx->base.pc_next + 2;
+        decode_16Bit_opc(ctx);
+    } else {
+        uint32_t insn_hi = cpu_lduw_code(env, ctx->base.pc_next + 2);
+        ctx->opcode = insn_hi << 16 | insn_lo;
+        ctx->pc_succ_insn = ctx->base.pc_next + 4;
+        decode_32Bit_opc(ctx);
     }
+    ctx->base.pc_next = ctx->pc_succ_insn;
 
-    gen_tb_end(tb, num_insns);
-    tb->size = ctx.pc - pc_start;
-    tb->icount = num_insns;
+    if (ctx->base.is_jmp == DISAS_NEXT) {
+        target_ulong page_start;
 
-    if (tcg_check_temp_count()) {
-        printf("LEAK at %08x\n", env->PC);
+        page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
+        if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE
+            || (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE - 3
+                && insn_crosses_page(env, ctx))) {
+            ctx->base.is_jmp = DISAS_TOO_MANY;
+        }
     }
+}
 
-#ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
-        qemu_log_lock();
-        qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, ctx.pc - pc_start);
-        qemu_log("\n");
-        qemu_log_unlock();
+static void tricore_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
+{
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+    switch (ctx->base.is_jmp) {
+    case DISAS_TOO_MANY:
+        gen_goto_tb(ctx, 0, ctx->base.pc_next);
+        break;
+    case DISAS_NORETURN:
+        break;
+    default:
+        g_assert_not_reached();
     }
-#endif
+}
+
+static void tricore_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
+{
+    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
+    log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
+}
+
+static const TranslatorOps tricore_tr_ops = {
+    .init_disas_context = tricore_tr_init_disas_context,
+    .tb_start           = tricore_tr_tb_start,
+    .insn_start         = tricore_tr_insn_start,
+    .breakpoint_check   = tricore_tr_breakpoint_check,
+    .translate_insn     = tricore_tr_translate_insn,
+    .tb_stop            = tricore_tr_tb_stop,
+    .disas_log          = tricore_tr_disas_log,
+};
+
+
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+{
+    DisasContext ctx;
+    translator_loop(&tricore_tr_ops, &ctx.base, cs, tb, max_insns);
 }
 
 void
diff --git a/target/unicore32/cpu-qom.h b/target/unicore32/cpu-qom.h
index bc68e78045..7dd04515cb 100644
--- a/target/unicore32/cpu-qom.h
+++ b/target/unicore32/cpu-qom.h
@@ -11,7 +11,7 @@
 #ifndef QEMU_UC32_CPU_QOM_H
 #define QEMU_UC32_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_UNICORE32_CPU "unicore32-cpu"
 
diff --git a/target/xtensa/cpu-qom.h b/target/xtensa/cpu-qom.h
index 403bd95721..9ac54241bd 100644
--- a/target/xtensa/cpu-qom.h
+++ b/target/xtensa/cpu-qom.h
@@ -29,7 +29,7 @@
 #ifndef QEMU_XTENSA_CPU_QOM_H
 #define QEMU_XTENSA_CPU_QOM_H
 
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #define TYPE_XTENSA_CPU "xtensa-cpu"
 
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 6f02dfcc01..39bed753b3 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -149,6 +149,7 @@ check-block-$(call land,$(CONFIG_POSIX),$(CONFIG_SOFTMMU)) += tests/check-block.
 
 check-qtest-generic-y += tests/qmp-test$(EXESUF)
 check-qtest-generic-y += tests/qmp-cmd-test$(EXESUF)
+check-qtest-generic-$(CONFIG_MODULES) += tests/modules-test$(EXESUF)
 
 check-qtest-generic-y += tests/device-introspect-test$(EXESUF)
 check-qtest-generic-y += tests/cdrom-test$(EXESUF)
diff --git a/tests/libqtest.c b/tests/libqtest.c
index eb971d0d11..2713b86cf7 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -811,6 +811,12 @@ bool qtest_get_irq(QTestState *s, int num)
     return s->irq_level[num];
 }
 
+void qtest_module_load(QTestState *s, const char *prefix, const char *libname)
+{
+    qtest_sendf(s, "module_load %s %s\n", prefix, libname);
+    qtest_rsp(s, 0);
+}
+
 static int64_t qtest_clock_rsp(QTestState *s)
 {
     gchar **words;
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 7833148358..07ea35867c 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -262,6 +262,8 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
 char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
     GCC_FMT_ATTR(2, 0);
 
+void qtest_module_load(QTestState *s, const char *prefix, const char *libname);
+
 /**
  * qtest_get_irq:
  * @s: #QTestState instance to operate on.
diff --git a/tests/modules-test.c b/tests/modules-test.c
new file mode 100644
index 0000000000..3aef0e5a19
--- /dev/null
+++ b/tests/modules-test.c
@@ -0,0 +1,71 @@
+#include "qemu/osdep.h"
+#include "libqtest.h"
+
+static void test_modules_load(const void *data)
+{
+    QTestState *qts;
+    const char **args = data;
+
+    qts = qtest_init(NULL);
+    qtest_module_load(qts, args[0], args[1]);
+    qtest_quit(qts);
+}
+
+int main(int argc, char *argv[])
+{
+    const char *modules[] = {
+#ifdef CONFIG_CURL
+        "block-", "curl",
+#endif
+#ifdef CONFIG_GLUSTERFS
+        "block-", "gluster",
+#endif
+#ifdef CONFIG_LIBISCSI
+        "block-", "iscsi",
+#endif
+#ifdef CONFIG_LIBNFS
+        "block-", "nfs",
+#endif
+#ifdef CONFIG_LIBSSH
+        "block-", "ssh",
+#endif
+#ifdef CONFIG_RBD
+        "block-", "rbd",
+#endif
+#ifdef CONFIG_AUDIO_ALSA
+        "audio-", "alsa",
+#endif
+#ifdef CONFIG_AUDIO_OSS
+        "audio-", "oss",
+#endif
+#ifdef CONFIG_AUDIO_PA
+        "audio-", "pa",
+#endif
+#ifdef CONFIG_AUDIO_SDL
+        "audio-", "sdl",
+#endif
+#ifdef CONFIG_CURSES
+        "ui-", "curses",
+#endif
+#if defined(CONFIG_GTK) && defined(CONFIG_VTE)
+        "ui-", "gtk",
+#endif
+#ifdef CONFIG_SDL
+        "ui-", "sdl",
+#endif
+#if defined(CONFIG_SPICE) && defined(CONFIG_GIO)
+        "ui-", "spice-app",
+#endif
+    };
+    int i;
+
+    g_test_init(&argc, &argv, NULL);
+
+    for (i = 0; i < G_N_ELEMENTS(modules); i += 2) {
+        char *testname = g_strdup_printf("/module/load/%s", modules[i + 1]);
+        qtest_add_data_func(testname, modules + i, test_modules_load);
+        g_free(testname);
+    }
+
+    return g_test_run();
+}
diff --git a/trace-events b/trace-events
index aeea3c2bdb..823a4ae64e 100644
--- a/trace-events
+++ b/trace-events
@@ -129,7 +129,7 @@ vcpu guest_cpu_enter(void)
 # Targets: all
 vcpu guest_cpu_exit(void)
 
-# qom/cpu.c
+# hw/core/cpu.c
 
 # Reset the state of a virtual (guest) CPU
 #
diff --git a/trace/control-vcpu.h b/trace/control-vcpu.h
index a8f1035c2e..0f98ebe7b5 100644
--- a/trace/control-vcpu.h
+++ b/trace/control-vcpu.h
@@ -12,7 +12,7 @@
 
 #include "control.h"
 #include "event-internal.h"
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 /**
  * trace_event_get_vcpu_state:
diff --git a/ui/cocoa.m b/ui/cocoa.m
index f023d5166f..f12e21df6e 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -40,7 +40,7 @@
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
 #include <Carbon/Carbon.h>
-#include "qom/cpu.h"
+#include "hw/core/cpu.h"
 
 #ifndef MAC_OS_X_VERSION_10_5
 #define MAC_OS_X_VERSION_10_5 1050
diff --git a/ui/curses.c b/ui/curses.c
index a6e260eb96..ec281125ac 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -225,6 +225,8 @@ static wint_t console_getch(enum maybe_keycode *maybe_keycode)
     case ERR:
         ret = -1;
         break;
+    default:
+        abort();
     }
     return ret;
 }
diff --git a/ui/input-linux.c b/ui/input-linux.c
index 59456fe765..a7b280b25b 100644
--- a/ui/input-linux.c
+++ b/ui/input-linux.c
@@ -113,6 +113,10 @@ static bool input_linux_check_toggle(InputLinux *il)
         return il->keydown[KEY_LEFTALT] &&
             il->keydown[KEY_RIGHTALT];
 
+    case GRAB_TOGGLE_KEYS_SHIFT_SHIFT:
+        return il->keydown[KEY_LEFTSHIFT] &&
+            il->keydown[KEY_RIGHTSHIFT];
+
     case GRAB_TOGGLE_KEYS_META_META:
         return il->keydown[KEY_LEFTMETA] &&
             il->keydown[KEY_RIGHTMETA];
diff --git a/util/module.c b/util/module.c
index 142db7e911..e9fe3e5422 100644
--- a/util/module.c
+++ b/util/module.c
@@ -156,8 +156,10 @@ out:
 }
 #endif
 
-void module_load_one(const char *prefix, const char *lib_name)
+bool module_load_one(const char *prefix, const char *lib_name)
 {
+    bool success = false;
+
 #ifdef CONFIG_MODULES
     char *fname = NULL;
     char *exec_dir;
@@ -170,7 +172,7 @@ void module_load_one(const char *prefix, const char *lib_name)
 
     if (!g_module_supported()) {
         fprintf(stderr, "Module is not supported by system.\n");
-        return;
+        return false;
     }
 
     if (!loaded_modules) {
@@ -179,11 +181,10 @@ void module_load_one(const char *prefix, const char *lib_name)
 
     module_name = g_strdup_printf("%s%s", prefix, lib_name);
 
-    if (g_hash_table_lookup(loaded_modules, module_name)) {
+    if (!g_hash_table_add(loaded_modules, module_name)) {
         g_free(module_name);
-        return;
+        return true;
     }
-    g_hash_table_insert(loaded_modules, module_name, module_name);
 
     exec_dir = qemu_get_exec_dir();
     search_dir = getenv("QEMU_MODULE_DIR");
@@ -206,13 +207,19 @@ void module_load_one(const char *prefix, const char *lib_name)
         fname = NULL;
         /* Try loading until loaded a module file */
         if (!ret) {
+            success = true;
             break;
         }
     }
 
+    if (!success) {
+        g_hash_table_remove(loaded_modules, module_name);
+    }
+
     for (i = 0; i < n_dirs; i++) {
         g_free(dirs[i]);
     }
 
 #endif
+    return success;
 }