summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS494
-rw-r--r--Makefile13
-rw-r--r--Makefile.objs32
-rw-r--r--Makefile.target32
-rw-r--r--audio/audio.c24
-rw-r--r--block-migration.c61
-rw-r--r--block.c54
-rwxr-xr-xconfigure8
-rw-r--r--default-configs/arm-softmmu.mak3
-rw-r--r--default-configs/cris-softmmu.mak1
-rw-r--r--default-configs/i386-softmmu.mak4
-rw-r--r--default-configs/m68k-softmmu.mak2
-rw-r--r--default-configs/microblaze-softmmu.mak1
-rw-r--r--default-configs/mips-softmmu.mak3
-rw-r--r--default-configs/mips64-softmmu.mak3
-rw-r--r--default-configs/mips64el-softmmu.mak3
-rw-r--r--default-configs/mipsel-softmmu.mak3
-rw-r--r--default-configs/pci.mak12
-rw-r--r--default-configs/ppc-softmmu.mak3
-rw-r--r--default-configs/ppc64-softmmu.mak3
-rw-r--r--default-configs/ppcemb-softmmu.mak3
-rw-r--r--default-configs/s390x-softmmu.mak1
-rw-r--r--default-configs/sh4-softmmu.mak3
-rw-r--r--default-configs/sh4eb-softmmu.mak3
-rw-r--r--default-configs/sparc-softmmu.mak2
-rw-r--r--default-configs/sparc64-softmmu.mak2
-rw-r--r--default-configs/x86_64-softmmu.mak4
-rw-r--r--hw/acpi_piix4.c55
-rw-r--r--hw/pc.c4
-rw-r--r--hw/pc_piix.c34
-rw-r--r--hw/pcnet-pci.c345
-rw-r--r--hw/pcnet.c316
-rw-r--r--hw/pcnet.h3
-rw-r--r--hw/vga-pci.c5
-rw-r--r--hw/virtio-blk.c4
-rw-r--r--hw/virtio-net.c41
-rw-r--r--hw/virtio-pci.c9
-rw-r--r--hw/virtio.c35
-rw-r--r--hw/vmware_vga.c5
-rw-r--r--ioport.c64
-rw-r--r--ioport.h2
-rw-r--r--iorange.h30
-rw-r--r--linux-user/signal.c18
-rw-r--r--make_device_config.sh28
-rwxr-xr-xpc-bios/optionrom/signrom.sh7
-rw-r--r--simpletrace.h6
-rw-r--r--slirp/misc.c42
-rw-r--r--slirp/slirp.h14
-rw-r--r--slirp/slirp_config.h6
-rw-r--r--trace-events3
-rwxr-xr-xtracetool128
-rw-r--r--vl.c3
52 files changed, 1298 insertions, 686 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index e5165fbae8..59effc7143 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1,88 +1,428 @@
 QEMU Maintainers
 ================
 
-Project leaders:
-----------------
+The intention of this file is not to establish who owns what portions of the
+code base, but to provide a set of names that developers can consult when they
+have a question about a particular subset and also to provide a set of names
+to be CC'd when submitting a patch to obtain appropriate review.
 
-Fabrice Bellard
-Paul Brook
+In general, if you have a question about inclusion of a patch, you should
+consult qemu-devel and not any specific individual privately.
 
-CPU cores:
-----------
+Descriptions of section entries:
+
+	M: Mail patches to: FullName <address@domain>
+	L: Mailing list that is relevant to this area
+	W: Web-page with status/info
+	Q: Patchwork web based patch tracking system site
+	T: SCM tree type and location.  Type is one of: git, hg, quilt, stgit.
+	S: Status, one of the following:
+	   Supported:	Someone is actually paid to look after this.
+	   Maintained:	Someone actually looks after it.
+	   Odd Fixes:	It has a maintainer but they don't have time to do
+			much other than throw the odd patch in. See below..
+	   Orphan:	No current maintainer [but maybe you could take the
+			role as you write your new code].
+	   Obsolete:	Old code. Something tagged obsolete generally means
+			it has been replaced by a better system and you
+			should be using that.
+	F: Files and directories with wildcard patterns.
+	   A trailing slash includes all files and subdirectory files.
+	   F:	drivers/net/	all files in and below drivers/net
+	   F:	drivers/net/*	all files in drivers/net, but not below
+	   F:	*/net/*		all files in "any top level directory"/net
+	   One pattern per line.  Multiple F: lines acceptable.
+	X: Files and directories that are NOT maintained, same rules as F:
+	   Files exclusions are tested before file matches.
+	   Can be useful for excluding a specific subdirectory, for instance:
+	   F:	net/
+	   X:	net/ipv6/
+	   matches all files in and below net excluding net/ipv6/
+	K: Keyword perl extended regex pattern to match content in a
+	   patch or file.  For instance:
+	   K: of_get_profile
+	      matches patches or files that contain "of_get_profile"
+	   K: \b(printk|pr_(info|err))\b
+	      matches patches or files that contain one or more of the words
+	      printk, pr_info or pr_err
+	   One regex pattern per line.  Multiple K: lines acceptable.
+
+
+General Project Administration
+------------------------------
+M: Anthony Liguori <aliguori@us.ibm.com>
+M: Paul Brook <paul@codesourcery.com>
+
+Guest CPU cores (TCG):
+----------------------
+Alpha
+M: qemu-devel@nongnu.org
+S: Orphan
+F: target-alpha/
 
-x86                Fabrice Bellard
-ARM                Paul Brook
-SPARC              Blue Swirl
-MIPS               ?
-PowerPC            Alexander Graf
-M68K               Paul Brook
-SH4                ?
-CRIS               Edgar E. Iglesias
-Alpha              ?
-MicroBlaze         Edgar E. Iglesias
-S390               ?
-
-Machines (sorted by CPU):
--------------------------
-
-x86
-  pc.c                    Fabrice Bellard (new maintainer needed)
 ARM
-  integratorcp.c          Paul Brook
-  versatilepb.c           Paul Brook
-  Real View               Paul Brook
-  spitz.c                 Andrzej Zaborowski
-  palm.c                  Andrzej Zaborowski
-  nseries.c               Andrzej Zaborowski
-  stellaris.c             Paul Brook
-  gumstix.c               Thorsten Zitterell
-  mainstone.c             Armin Kuster
-  musicpal.c              Jan Kiszka
-SPARC
-  sun4u.c                 Blue Swirl
-  sun4m.c                 Blue Swirl
+M: Paul Brook <paul@codesourcery.com>
+S: Maintained
+F: target-arm/
+
+CRIS
+M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
+S: Maintained
+F: target-cris/
+
+M68K
+M: Paul Brook <paul@codesourcery.com>
+S: Maintained
+F: target-m68k/
+
+MicroBlaze
+M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
+S: Maintained
+F: target-microblaze/
+
 MIPS
-  mips_r4k.c              Aurelien Jarno
-  mips_malta.c            Aurelien Jarno
-  mips_jazz.c             Hervé Poussineau
-  mips_mipssim.c          ?
+M: qemu-devel@nongnu.org
+S: Orphan
+F: target-mips/
+
 PowerPC
-  ppc_prep.c              ?
-  ppc_oldworld.c          Alexander Graf
-  ppc_newworld.c          Alexander Graf
-  ppc405_boards.c         Alexander Graf
-M86K
-  mcf5208.c               Paul Brook
-  an5206.c                Paul Brook
-  dummy_m68k.c            Paul Brook
+M: Alexander Graf <agraf@suse.de>
+S: Maintained
+F: target-ppc/
+
+S390
+M: Alexander Graf <agraf@suse.de>
+S: Maintained
+F: target-s390x/
+
 SH4
-  shix.c                  ?
-  r2d.c                   Magnus Damm
-CRIS
-  etraxfs.c               Edgar E. Iglesias
-  axis_dev88.c            Edgar E. Iglesias
-Alpha
-MicroBlaze
-  petalogix_s3adsp1800.c  Edgar E. Iglesias
+M: qemu-devel@nongnu.org
+S: Orphan
+F: target-sh4/
+
+SPARC
+M: Blue Swirl <blauwirbel@gmail.com>
+S: Maintained
+F: target-sparc/
+
+X86
+M: qemu-devel@nongnu.org
+S: Odd Fixes
+F: target-i386/
+
+Guest CPU Cores (KVM):
+----------------------
+
+Overall
+M: Avi Kivity <avi@redhat.com>
+M: Marcelo Tosatti <mtosatti@redhat.com>
+L: kvm@vger.kernel.org
+S: Supported
+F: kvm-*
+F: */kvm.*
+
+PPC
+M: Alexander Graf <agraf@suse.de>
+S: Maintained
+F: target-ppc/kvm.c
+
 S390
-  s390-*.c                Alexander Graf
-
-Generic Subsystems:
--------------------  
-
-Dynamic translator        Fabrice Bellard
-Main loop                 Fabrice Bellard (new maintainer needed)
-TCG                       Fabrice Bellard
-IDE device                ?
-SCSI device               Paul Brook
-PCI layer                 Michael S. Tsirkin
-USB layer                 ?
-Block layer               ?
-Graphic layer             ?
-Audio device layer        Vassili Karpov (malc)
-Character device layer    ?
-Network device layer      ?
-GDB stub                  ?
-Linux user                ?
-Darwin user               ?
-SLIRP                     ?
+M: Alexander Graf <agraf@suse.de>
+S: Maintained
+F: target-s390x/kvm.c
+
+X86
+M: Avi Kivity <avi@redhat.com>
+M: Marcelo Tosatti <mtosatti@redhat.com>
+L: kvm@vger.kernel.org
+S: Supported
+F: target-i386/kvm.c
+
+ARM Machines
+------------
+Gumstix
+M: qemu-devel@nongnu.org
+S: Orphan
+F: hw/gumstix.c
+
+Integrator CP
+M: Paul Brook <paul@codesourcery.com>
+S: Maintained
+F: hw/integratorcp.c
+
+Mainstone
+M: qemu-devel@nongnu.org
+S: Orphan
+F: hw/mainstone.c
+
+Musicpal
+M: Jan Kiszka <jan.kiszka@web.de>
+S: Maintained
+F: hw/musicpal.c
+
+nSeries
+M: Andrzej Zaborowski <balrogg@gmail.com>
+S: Maintained
+F: hw/nseries.c
+
+Palm
+M: Andrzej Zaborowski <balrogg@gmail.com>
+S: Maintained
+F: hw/palm.c
+
+Real View
+M: Paul Brook <paul@codesourcery.com>
+S: Maintained
+F: hw/realview*
+
+Spitz
+M: Andrzej Zaborowski <balrogg@gmail.com>
+S: Maintained
+F: hw/spitz.c
+
+Stellaris
+M: Paul Brook <paul@codesourcery.com>
+S: Maintained
+F: hw/stellaris.c
+
+Versatile PB
+M: Paul Brook <paul@codesourcery.com>
+S: Maintained
+F: hw/versatilepb.c
+
+CRIS Machines
+-------------
+Axis Dev88
+M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
+S: Maintained
+F: hw/axis_dev88.c
+
+etraxfs
+M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
+S: Maintained
+F: hw/etraxfs.c
+
+M86K Machines
+-------------
+an5206
+M: Paul Brook <paul@codesourcery.com>
+S: Maintained
+F: hw/an5206.c
+
+dummy_m68k
+M: Paul Brook <paul@codesourcery.com>
+S: Maintained
+F: hw/dummy_m68k.c
+
+mcf5208
+M: Paul Brook <paul@codesourcery.com>
+S: Maintained
+F: hw/mcf5208.c
+
+MicroBlaze Machines
+-------------------
+petalogix_s3adsp1800
+M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
+S: Maintained
+F: hw/petalogix_s3adsp1800.c
+
+MIPS Machines
+-------------
+Jazz
+M: Hervé Poussineau <hpoussin@reactos.org>
+S: Maintained
+F: hw/mips_jazz.c
+
+Malta
+M: Aurelien Jarno <aurelien@aurel32.net>
+S: Maintained
+F: hw/mips_malta.c
+
+Mipssim
+M: qemu-devel@nongnu.org
+S: Orphan
+F: hw/mips_mipssim.c
+
+R4000
+M: Aurelien Jarno <aurelien@aurel32.net>
+S: Maintained
+F: hw/mips_r4k.c
+
+PowerPC Machines
+----------------
+405
+M: Alexander Graf <agraf@suse.de>
+S: Maintained
+F: hw/ppc405_boards.c
+
+New World
+M: Alexander Graf <agraf@suse.de>
+S: Maintained
+F: hw/ppc_newworld.c
+
+Old World
+M: Alexander Graf <agraf@suse.de>
+S: Maintained
+F: hw/ppc_oldworld.c
+
+Prep
+M: qemu-devel@nongnu.org
+S: Orphan
+F: hw/ppc_prep.c
+
+SH4 Machines
+------------
+R2D
+M: Magnus Damm <magnus.damm@gmail.com>
+S: Maintained
+F: hw/r2d.c
+
+Shix
+M: Magnus Damm <magnus.damm@gmail.com>
+S: Oprhan
+F: hw/shix.c
+
+SPARC Machines
+--------------
+Sun4m
+M: Blue Swirl <blauwirbel@gmail.com>
+S: Maintained
+F: hw/sun4m.c
+
+Sun4u
+M: Blue Swirl <blauwirbel@gmail.com>
+S: Maintained
+F: hw/sun4u.c
+
+S390 Machines
+-------------
+S390 Virtio
+M: Alexander Graf <agraf@suse.de>
+S: Maintained
+F: hw/s390-*.c
+
+X86 Machines
+------------
+PC
+M: Anthony Liguori <aliguori@us.ibm.com>
+S: Supported
+F: hw/pc.[ch] hw/pc_piix.c
+
+Devices
+-------
+IDE
+M: Kevin Wolf <kwolf@redhat.com>
+S: Odd Fixes
+F: hw/ide/
+
+PCI
+M: Michael S. Tsirkin <mst@redhat.com>
+S: Supported
+F: hw/pci*
+F: hw/piix*
+
+SCSI
+M: Paul Brook <paul@codesourcery.com>
+M: Kevin Wolf <kwolf@redhat.com>
+S: Odd Fixes
+F: hw/lsi53c895a.c
+F: hw/scsi*
+
+USB
+M: qemu-devel@nongnu.org
+S: Odd Fixes
+F: hw/usb*
+
+vhost
+M: Michael S. Tsirkin <mst@redhat.com>
+S: Supported
+F: hw/vhost*
+
+virtio
+M: Anthony Liguori <aliguori@us.ibm.com>
+S: Supported
+F: hw/virtio*
+
+virtio-9p
+M: Venkateswararao Jujjuri (JV) <jvrao@linux.vnet.ibm.com>
+S: Supported
+F: hw/virtio-9p*
+
+virtio-blk
+M: Kevin Wolf <kwolf@redhat.com>
+S: Supported
+F: hw/virtio-blk*
+
+virtio-serial
+M: Amit Shah <amit.shah@redhat.com>
+S: Supported
+F: hw/virtio-serial*
+F: hw/virtio-console*
+
+Subsystems
+----------
+Audio
+M: Vassili Karpov (malc) <av1474@comtv.ru>
+S: Maintained
+F: audio/
+
+Block
+M: Kevin Wolf <kwolf@redhat.com>
+S: Supported
+F: block*
+F: block/
+
+Character Devices
+M: Anthony Liguori <aliguori@us.ibm.com>
+S: Maintained
+F: qemu-char.c
+
+GDB stub
+M: qemu-devel@nongnu.org
+S: Odd Fixes
+F: gdbstub*
+F: gdb-xml/
+
+Graphics
+M: Anthony Liguori <aliguori@us.ibm.com>
+S: Maintained
+F: ui/
+
+Main loop
+M: Anthony Liguori <aliguori@us.ibm.com>
+S: Supported
+F: vl.c
+
+Monitor (QMP/HMP)
+M: Luiz Capitulino <lcapitulino@redhat.com>
+M: Markus Armbruster <armbru@redhat.com>
+S: Supported
+F: monitor.c
+
+Network device layer
+M: Anthony Liguori <aliguori@us.ibm.com>
+M: Mark McLoughlin <markmc@redhat.com>
+S: Maintained
+F: net/
+
+SLIRP
+M: qemu-devel@nongnu.org
+S: Orphan
+F: slirp/
+
+Usermode Emulation
+------------------
+BSD user
+M: Blue Swirl <blauwirbel@gmail.com>
+S: Maintained
+F: bsd-user/
+
+Darwin user
+M: qemu-devel@nongnu.org
+S: Orphan
+F: darwin-user/
+
+Linux user
+M: Riku Voipio <riku.voipio@iki.fi>
+S: Maintained
+F: linux-user/
diff --git a/Makefile b/Makefile
index 4e120a2d3a..d3bc0f2c74 100644
--- a/Makefile
+++ b/Makefile
@@ -39,18 +39,19 @@ endif
 
 SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory)
 SUBDIR_DEVICES_MAK=$(patsubst %, %/config-devices.mak, $(TARGET_DIRS))
+SUBDIR_DEVICES_MAK_DEP=$(patsubst %, %/config-devices.mak.d, $(TARGET_DIRS))
 
 config-all-devices.mak: $(SUBDIR_DEVICES_MAK)
 	$(call quiet-command,cat $(SUBDIR_DEVICES_MAK) | grep =y | sort -u > $@,"  GEN   $@")
 
+-include $(SUBDIR_DEVICES_MAK_DEP)
+
 %/config-devices.mak: default-configs/%.mak
-	$(call quiet-command,cat $< > $@.tmp, "  GEN   $@")
+	$(call quiet-command,$(SHELL) $(SRC_PATH)/make_device_config.sh $@ $<, "  GEN   $@")
 	@if test -f $@; then \
 	  if cmp -s $@.old $@; then \
-	    if ! cmp -s $@ $@.tmp; then \
-	      mv $@.tmp $@; \
-	      cp -p $@ $@.old; \
-	    fi; \
+	    mv $@.tmp $@; \
+	    cp -p $@ $@.old; \
 	  else \
 	    if test -f $@.old; then \
 	      echo "WARNING: $@ (user modified) out of date.";\
@@ -150,7 +151,7 @@ version-obj-$(CONFIG_WIN32) += version.o
 ######################################################################
 
 qemu-img.o: qemu-img-cmds.h
-qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS)
+qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o: $(GENERATED_HEADERS)
 
 qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
 
diff --git a/Makefile.objs b/Makefile.objs
index 23b17cefad..13ba26fdcb 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -42,6 +42,11 @@ net-nested-$(CONFIG_SLIRP) += slirp.o
 net-nested-$(CONFIG_VDE) += vde.o
 net-obj-y += $(addprefix net/, $(net-nested-y))
 
+ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS),yy)
+# Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add.
+# only pull in the actual virtio-9p device if we also enabled virtio.
+CONFIG_REALLY_VIRTFS=y
+endif
 fsdev-nested-$(CONFIG_VIRTFS) = qemu-fsdev.o
 fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y))
 
@@ -159,9 +164,13 @@ user-obj-y += cutils.o cache-utils.o
 
 hw-obj-y =
 hw-obj-y += vl.o loader.o
-hw-obj-y += virtio.o virtio-console.o
-hw-obj-y += fw_cfg.o pci.o pci_host.o pcie_host.o pci_bridge.o
-hw-obj-y += ioh3420.o xio3130_upstream.o xio3130_downstream.o
+hw-obj-$(CONFIG_VIRTIO) += virtio.o virtio-console.o
+hw-obj-y += fw_cfg.o
+# FIXME: Core PCI code and its direct dependencies are required by the
+# QMP query-pci command.
+hw-obj-y += pci.o pci_bridge.o msix.o msi.o
+hw-obj-$(CONFIG_PCI) += pci_host.o pcie_host.o
+hw-obj-$(CONFIG_PCI) += ioh3420.o xio3130_upstream.o xio3130_downstream.o
 hw-obj-y += watchdog.o
 hw-obj-$(CONFIG_ISA_MMIO) += isa_mmio.o
 hw-obj-$(CONFIG_ECC) += ecc.o
@@ -206,15 +215,15 @@ hw-obj-$(CONFIG_PPCE500_PCI) += ppce500_pci.o
 hw-obj-$(CONFIG_PIIX4) += piix4.o
 
 # PCI watchdog devices
-hw-obj-y += wdt_i6300esb.o
+hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o
 
-hw-obj-y += pcie.o pcie_port.o
-hw-obj-y += msix.o msi.o
+hw-obj-$(CONFIG_PCI) += pcie.o pcie_port.o
 
 # PCI network cards
-hw-obj-y += ne2000.o
-hw-obj-y += eepro100.o
-hw-obj-y += pcnet.o
+hw-obj-$(CONFIG_NE2000_PCI) += ne2000.o
+hw-obj-$(CONFIG_EEPRO100_PCI) += eepro100.o
+hw-obj-$(CONFIG_PCNET_PCI) += pcnet-pci.o
+hw-obj-$(CONFIG_PCNET_COMMON) += pcnet.o
 
 hw-obj-$(CONFIG_SMC91C111) += smc91c111.o
 hw-obj-$(CONFIG_LAN9118) += lan9118.o
@@ -231,7 +240,7 @@ hw-obj-$(CONFIG_IDE_MACIO) += ide/macio.o
 hw-obj-$(CONFIG_IDE_VIA) += ide/via.o
 
 # SCSI layer
-hw-obj-y += lsi53c895a.o
+hw-obj-$(CONFIG_LSI_SCSI_PCI) += lsi53c895a.o
 hw-obj-$(CONFIG_ESP) += esp.o
 
 hw-obj-y += dma-helpers.o sysbus.o isa-bus.o
@@ -261,7 +270,8 @@ sound-obj-$(CONFIG_HDA) += intel-hda.o hda-audio.o
 adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
 hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 
-hw-obj-$(CONFIG_VIRTFS) += virtio-9p-debug.o virtio-9p-local.o virtio-9p-xattr.o
+hw-obj-$(CONFIG_REALLY_VIRTFS) += virtio-9p-debug.o
+hw-obj-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o
 hw-obj-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
 
 ######################################################################
diff --git a/Makefile.target b/Makefile.target
index 652c7d2a57..578484452b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -42,17 +42,26 @@ config-target.h: config-target.h-timestamp
 config-target.h-timestamp: config-target.mak
 
 ifdef CONFIG_SYSTEMTAP_TRACE
-STPFILES+=$(QEMU_PROG).stp
+stap: $(QEMU_PROG).stp
+
+ifdef CONFIG_USER_ONLY
+TARGET_TYPE=user
+else
+TARGET_TYPE=system
+endif
 
 $(QEMU_PROG).stp:
 	$(call quiet-command,sh $(SRC_PATH)/tracetool \
 		--$(TRACE_BACKEND) \
-		--bindir $(bindir) \
-		--target $(TARGET_ARCH) \
-		-s < $(SRC_PATH)/trace-events > $@,"  GEN   $@")
+		--binary $(bindir)/$(QEMU_PROG) \
+		--target-arch $(TARGET_ARCH) \
+		--target-type $(TARGET_TYPE) \
+		--stap < $(SRC_PATH)/trace-events > $(QEMU_PROG).stp,"  GEN   $(QEMU_PROG).stp")
+else
+stap:
 endif
 
-all: $(PROGS) $(STPFILES)
+all: $(PROGS) stap
 
 # Dummy command so that make thinks it has done something
 	@true
@@ -179,11 +188,11 @@ ifdef CONFIG_SOFTMMU
 obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
-obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
+obj-$(CONFIG_VIRTIO) += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
 obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 obj-y += vhost_net.o
 obj-$(CONFIG_VHOST_NET) += vhost.o
-obj-$(CONFIG_VIRTFS) += virtio-9p.o
+obj-$(CONFIG_REALLY_VIRTFS) += virtio-9p.o
 obj-y += rwhandler.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
@@ -201,8 +210,8 @@ obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
 obj-$(CONFIG_USB_OHCI) += usb-ohci.o
 
 # PCI network cards
-obj-y += rtl8139.o
-obj-y += e1000.o
+obj-$(CONFIG_RTL8139_PCI) += rtl8139.o
+obj-$(CONFIG_E1000_PCI) += e1000.o
 
 # Inter-VM PCI shared memory
 obj-$(CONFIG_KVM) += ivshmem.o
@@ -352,6 +361,9 @@ clean:
 	rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
 	rm -f *.d */*.d tcg/*.o ide/*.o
 	rm -f hmp-commands.h qmp-commands.h gdbstub-xml.c
+ifdef CONFIG_SYSTEMTAP_TRACE
+	rm -f *.stp
+endif
 
 install: all
 ifneq ($(PROGS),)
@@ -362,7 +374,7 @@ endif
 endif
 ifdef CONFIG_SYSTEMTAP_TRACE
 	$(INSTALL_DIR) "$(DESTDIR)$(datadir)/../systemtap/tapset"
-	$(INSTALL_DATA) $(STPFILES) "$(DESTDIR)$(datadir)/../systemtap/tapset"
+	$(INSTALL_DATA) $(QEMU_PROG).stp "$(DESTDIR)$(datadir)/../systemtap/tapset"
 endif
 
 # Include automatically generated dependency files
diff --git a/audio/audio.c b/audio/audio.c
index ade342e856..17074469b2 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1096,15 +1096,6 @@ static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
 /*
  * Timer
  */
-static void audio_timer (void *opaque)
-{
-    AudioState *s = opaque;
-
-    audio_run ("timer");
-    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
-}
-
-
 static int audio_is_timer_needed (void)
 {
     HWVoiceIn *hwi = NULL;
@@ -1119,10 +1110,8 @@ static int audio_is_timer_needed (void)
     return 0;
 }
 
-static void audio_reset_timer (void)
+static void audio_reset_timer (AudioState *s)
 {
-    AudioState *s = &glob_audio_state;
-
     if (audio_is_timer_needed ()) {
         qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
     }
@@ -1131,6 +1120,12 @@ static void audio_reset_timer (void)
     }
 }
 
+static void audio_timer (void *opaque)
+{
+    audio_run ("timer");
+    audio_reset_timer (opaque);
+}
+
 /*
  * Public API
  */
@@ -1195,7 +1190,7 @@ void AUD_set_active_out (SWVoiceOut *sw, int on)
                 hw->enabled = 1;
                 if (s->vm_running) {
                     hw->pcm_ops->ctl_out (hw, VOICE_ENABLE, conf.try_poll_out);
-                    audio_reset_timer ();
+                    audio_reset_timer (s);
                 }
             }
         }
@@ -1240,6 +1235,7 @@ void AUD_set_active_in (SWVoiceIn *sw, int on)
                 hw->enabled = 1;
                 if (s->vm_running) {
                     hw->pcm_ops->ctl_in (hw, VOICE_ENABLE, conf.try_poll_in);
+                    audio_reset_timer (s);
                 }
             }
             sw->total_hw_samples_acquired = hw->total_samples_captured;
@@ -1761,7 +1757,7 @@ static void audio_vm_change_state_handler (void *opaque, int running,
     while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
         hwi->pcm_ops->ctl_in (hwi, op, conf.try_poll_in);
     }
-    audio_reset_timer ();
+    audio_reset_timer (s);
 }
 
 static void audio_atexit (void)
diff --git a/block-migration.c b/block-migration.c
index 0bfdb73c8b..3e66f49350 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -49,12 +49,14 @@ typedef struct BlkMigDevState {
     int64_t total_sectors;
     int64_t dirty;
     QSIMPLEQ_ENTRY(BlkMigDevState) entry;
+    unsigned long *aio_bitmap;
 } BlkMigDevState;
 
 typedef struct BlkMigBlock {
     uint8_t *buf;
     BlkMigDevState *bmds;
     int64_t sector;
+    int nr_sectors;
     struct iovec iov;
     QEMUIOVector qiov;
     BlockDriverAIOCB *aiocb;
@@ -140,6 +142,57 @@ static inline long double compute_read_bwidth(void)
     return  (block_mig_state.reads * BLOCK_SIZE)/ block_mig_state.total_time;
 }
 
+static int bmds_aio_inflight(BlkMigDevState *bmds, int64_t sector)
+{
+    int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
+
+    if (bmds->aio_bitmap &&
+        (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bmds->bs)) {
+        return !!(bmds->aio_bitmap[chunk / (sizeof(unsigned long) * 8)] &
+            (1UL << (chunk % (sizeof(unsigned long) * 8))));
+    } else {
+        return 0;
+    }
+}
+
+static void bmds_set_aio_inflight(BlkMigDevState *bmds, int64_t sector_num,
+                             int nb_sectors, int set)
+{
+    int64_t start, end;
+    unsigned long val, idx, bit;
+
+    start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
+    end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
+
+    for (; start <= end; start++) {
+        idx = start / (sizeof(unsigned long) * 8);
+        bit = start % (sizeof(unsigned long) * 8);
+        val = bmds->aio_bitmap[idx];
+        if (set) {
+            if (!(val & (1UL << bit))) {
+                val |= 1UL << bit;
+            }
+        } else {
+            if (val & (1UL << bit)) {
+                val &= ~(1UL << bit);
+            }
+        }
+        bmds->aio_bitmap[idx] = val;
+    }
+}
+
+static void alloc_aio_bitmap(BlkMigDevState *bmds)
+{
+    BlockDriverState *bs = bmds->bs;
+    int64_t bitmap_size;
+
+    bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
+            BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
+    bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
+
+    bmds->aio_bitmap = qemu_mallocz(bitmap_size);
+}
+
 static void blk_mig_read_cb(void *opaque, int ret)
 {
     BlkMigBlock *blk = opaque;
@@ -151,6 +204,7 @@ static void blk_mig_read_cb(void *opaque, int ret)
     add_avg_read_time(blk->time);
 
     QSIMPLEQ_INSERT_TAIL(&block_mig_state.blk_list, blk, entry);
+    bmds_set_aio_inflight(blk->bmds, blk->sector, blk->nr_sectors, 0);
 
     block_mig_state.submitted--;
     block_mig_state.read_done++;
@@ -194,6 +248,7 @@ static int mig_save_device_bulk(Monitor *mon, QEMUFile *f,
     blk->buf = qemu_malloc(BLOCK_SIZE);
     blk->bmds = bmds;
     blk->sector = cur_sector;
+    blk->nr_sectors = nr_sectors;
 
     blk->iov.iov_base = blk->buf;
     blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
@@ -248,6 +303,7 @@ static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
         bmds->total_sectors = sectors;
         bmds->completed_sectors = 0;
         bmds->shared_base = block_mig_state.shared_base;
+        alloc_aio_bitmap(bmds);
 
         block_mig_state.total_sector_sum += sectors;
 
@@ -329,6 +385,8 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f,
     int nr_sectors;
 
     for (sector = bmds->cur_dirty; sector < bmds->total_sectors;) {
+        if (bmds_aio_inflight(bmds, sector))
+            qemu_aio_flush();
         if (bdrv_get_dirty(bmds->bs, sector)) {
 
             if (total_sectors - sector < BDRV_SECTORS_PER_DIRTY_CHUNK) {
@@ -340,6 +398,7 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f,
             blk->buf = qemu_malloc(BLOCK_SIZE);
             blk->bmds = bmds;
             blk->sector = sector;
+            blk->nr_sectors = nr_sectors;
 
             if (is_async) {
                 blk->iov.iov_base = blk->buf;
@@ -354,6 +413,7 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f,
                     goto error;
                 }
                 block_mig_state.submitted++;
+                bmds_set_aio_inflight(bmds, sector, nr_sectors, 1);
             } else {
                 if (bdrv_read(bmds->bs, sector, blk->buf,
                               nr_sectors) < 0) {
@@ -474,6 +534,7 @@ static void blk_mig_cleanup(Monitor *mon)
 
     while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) {
         QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry);
+        qemu_free(bmds->aio_bitmap);
         qemu_free(bmds);
     }
 
diff --git a/block.c b/block.c
index 6b505fba1b..63effd8769 100644
--- a/block.c
+++ b/block.c
@@ -930,14 +930,14 @@ static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
         bit = start % (sizeof(unsigned long) * 8);
         val = bs->dirty_bitmap[idx];
         if (dirty) {
-            if (!(val & (1 << bit))) {
+            if (!(val & (1UL << bit))) {
                 bs->dirty_count++;
-                val |= 1 << bit;
+                val |= 1UL << bit;
             }
         } else {
-            if (val & (1 << bit)) {
+            if (val & (1UL << bit)) {
                 bs->dirty_count--;
-                val &= ~(1 << bit);
+                val &= ~(1UL << bit);
             }
         }
         bs->dirty_bitmap[idx] = val;
@@ -2031,12 +2031,49 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
     return ret;
 }
 
+typedef struct BlockCompleteData {
+    BlockDriverCompletionFunc *cb;
+    void *opaque;
+    BlockDriverState *bs;
+    int64_t sector_num;
+    int nb_sectors;
+} BlockCompleteData;
+
+static void block_complete_cb(void *opaque, int ret)
+{
+    BlockCompleteData *b = opaque;
+
+    if (b->bs->dirty_bitmap) {
+        set_dirty_bitmap(b->bs, b->sector_num, b->nb_sectors, 1);
+    }
+    b->cb(b->opaque, ret);
+    qemu_free(b);
+}
+
+static BlockCompleteData *blk_dirty_cb_alloc(BlockDriverState *bs,
+                                             int64_t sector_num,
+                                             int nb_sectors,
+                                             BlockDriverCompletionFunc *cb,
+                                             void *opaque)
+{
+    BlockCompleteData *blkdata = qemu_mallocz(sizeof(BlockCompleteData));
+
+    blkdata->bs = bs;
+    blkdata->cb = cb;
+    blkdata->opaque = opaque;
+    blkdata->sector_num = sector_num;
+    blkdata->nb_sectors = nb_sectors;
+
+    return blkdata;
+}
+
 BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
                                   QEMUIOVector *qiov, int nb_sectors,
                                   BlockDriverCompletionFunc *cb, void *opaque)
 {
     BlockDriver *drv = bs->drv;
     BlockDriverAIOCB *ret;
+    BlockCompleteData *blk_cb_data;
 
     trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
 
@@ -2048,7 +2085,10 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
         return NULL;
 
     if (bs->dirty_bitmap) {
-        set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
+        blk_cb_data = blk_dirty_cb_alloc(bs, sector_num, nb_sectors, cb,
+                                         opaque);
+        cb = &block_complete_cb;
+        opaque = blk_cb_data;
     }
 
     ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
@@ -2685,8 +2725,8 @@ int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
 
     if (bs->dirty_bitmap &&
         (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
-        return bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
-            (1 << (chunk % (sizeof(unsigned long) * 8)));
+        return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
+            (1UL << (chunk % (sizeof(unsigned long) * 8))));
     } else {
         return 0;
     }
diff --git a/configure b/configure
index e560f878a3..2917874f96 100755
--- a/configure
+++ b/configure
@@ -2192,10 +2192,6 @@ EOF
     echo
     exit 1
   fi
-  trace_backend_stap="no"
-  if has 'stap' ; then
-    trace_backend_stap="yes"
-  fi
 fi
 
 ##########################################
@@ -2207,6 +2203,10 @@ if test "$trace_backend" = "dtrace"; then
     echo
     exit 1
   fi
+  trace_backend_stap="no"
+  if has 'stap' ; then
+    trace_backend_stap="yes"
+  fi
 fi
 
 ##########################################
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index e7a4e84481..ac48dc1565 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -1,7 +1,7 @@
 # Default configuration for arm-softmmu
 
+include pci.mak
 CONFIG_GDBSTUB_XML=y
-CONFIG_USB_OHCI=y
 CONFIG_ISA_MMIO=y
 CONFIG_NAND=y
 CONFIG_ECC=y
@@ -25,6 +25,5 @@ CONFIG_SSI_SD=y
 CONFIG_LAN9118=y
 CONFIG_SMC91C111=y
 CONFIG_DS1338=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
diff --git a/default-configs/cris-softmmu.mak b/default-configs/cris-softmmu.mak
index e0d2cabb2d..1a479cd8d3 100644
--- a/default-configs/cris-softmmu.mak
+++ b/default-configs/cris-softmmu.mak
@@ -2,5 +2,4 @@
 
 CONFIG_NAND=y
 CONFIG_PTIMER=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_PFLASH_CFI02=y
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index ed00471da2..ce905d23d1 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -1,6 +1,6 @@
 # Default configuration for i386-softmmu
 
-CONFIG_USB_OHCI=y
+include pci.mak
 CONFIG_VGA_PCI=y
 CONFIG_VGA_ISA=y
 CONFIG_VMWARE_VGA=y
@@ -9,7 +9,6 @@ CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
 CONFIG_PCKBD=y
-CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_APM=y
@@ -22,4 +21,3 @@ CONFIG_IDE_PIIX=y
 CONFIG_NE2000_ISA=y
 CONFIG_PIIX_PCI=y
 CONFIG_SOUND=y
-CONFIG_VIRTIO_PCI=y
diff --git a/default-configs/m68k-softmmu.mak b/default-configs/m68k-softmmu.mak
index 69ca3ed08e..3e2ec3716c 100644
--- a/default-configs/m68k-softmmu.mak
+++ b/default-configs/m68k-softmmu.mak
@@ -1,5 +1,5 @@
 # Default configuration for m68k-softmmu
 
+include pci.mak
 CONFIG_GDBSTUB_XML=y
 CONFIG_PTIMER=y
-CONFIG_VIRTIO_PCI=y
diff --git a/default-configs/microblaze-softmmu.mak b/default-configs/microblaze-softmmu.mak
index 6c4f4f2f22..4399b8b361 100644
--- a/default-configs/microblaze-softmmu.mak
+++ b/default-configs/microblaze-softmmu.mak
@@ -1,5 +1,4 @@
 # Default configuration for microblaze-softmmu
 
 CONFIG_PTIMER=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_PFLASH_CFI01=y
diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak
index 3d0af83165..565e611c53 100644
--- a/default-configs/mips-softmmu.mak
+++ b/default-configs/mips-softmmu.mak
@@ -1,5 +1,6 @@
 # Default configuration for mips-softmmu
 
+include pci.mak
 CONFIG_ISA_MMIO=y
 CONFIG_ESP=y
 CONFIG_VGA_PCI=y
@@ -11,7 +12,6 @@ CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
 CONFIG_PCKBD=y
-CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_APM=y
@@ -24,7 +24,6 @@ CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_RC4030=y
 CONFIG_DP8393X=y
 CONFIG_DS1225Y=y
diff --git a/default-configs/mips64-softmmu.mak b/default-configs/mips64-softmmu.mak
index 0030de45dc..03bd8ebf8d 100644
--- a/default-configs/mips64-softmmu.mak
+++ b/default-configs/mips64-softmmu.mak
@@ -1,5 +1,6 @@
 # Default configuration for mips64-softmmu
 
+include pci.mak
 CONFIG_ISA_MMIO=y
 CONFIG_ESP=y
 CONFIG_VGA_PCI=y
@@ -11,7 +12,6 @@ CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
 CONFIG_PCKBD=y
-CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_APM=y
@@ -24,7 +24,6 @@ CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_RC4030=y
 CONFIG_DP8393X=y
 CONFIG_DS1225Y=y
diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak
index fa2a3ffa45..4661617700 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -1,5 +1,6 @@
 # Default configuration for mips64el-softmmu
 
+include pci.mak
 CONFIG_ISA_MMIO=y
 CONFIG_ESP=y
 CONFIG_VGA_PCI=y
@@ -11,7 +12,6 @@ CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
 CONFIG_PCKBD=y
-CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_APM=y
@@ -25,7 +25,6 @@ CONFIG_IDE_PIIX=y
 CONFIG_IDE_VIA=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_RC4030=y
 CONFIG_DP8393X=y
 CONFIG_DS1225Y=y
diff --git a/default-configs/mipsel-softmmu.mak b/default-configs/mipsel-softmmu.mak
index 238b73ace1..92fc473318 100644
--- a/default-configs/mipsel-softmmu.mak
+++ b/default-configs/mipsel-softmmu.mak
@@ -1,5 +1,6 @@
 # Default configuration for mipsel-softmmu
 
+include pci.mak
 CONFIG_ISA_MMIO=y
 CONFIG_ESP=y
 CONFIG_VGA_PCI=y
@@ -11,7 +12,6 @@ CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
 CONFIG_PCKBD=y
-CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_APM=y
@@ -24,7 +24,6 @@ CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_RC4030=y
 CONFIG_DP8393X=y
 CONFIG_DS1225Y=y
diff --git a/default-configs/pci.mak b/default-configs/pci.mak
new file mode 100644
index 0000000000..c74a99f5c9
--- /dev/null
+++ b/default-configs/pci.mak
@@ -0,0 +1,12 @@
+CONFIG_PCI=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO=y
+CONFIG_USB_UHCI=y
+CONFIG_USB_OHCI=y
+CONFIG_NE2000_PCI=y
+CONFIG_EEPRO100_PCI=y
+CONFIG_PCNET_PCI=y
+CONFIG_PCNET_COMMON=y
+CONFIG_LSI_SCSI_PCI=y
+CONFIG_RTL8139_PCI=y
+CONFIG_E1000_PCI=y
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 940f4bf375..f1cb99e408 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -1,7 +1,7 @@
 # Default configuration for ppc-softmmu
 
+include pci.mak
 CONFIG_GDBSTUB_XML=y
-CONFIG_USB_OHCI=y
 CONFIG_ISA_MMIO=y
 CONFIG_ESCC=y
 CONFIG_M48T59=y
@@ -31,7 +31,6 @@ CONFIG_IDE_CMD646=y
 CONFIG_IDE_MACIO=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
 CONFIG_PTIMER=y
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index e1bc6b8f80..83cbe97f1e 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -1,7 +1,7 @@
 # Default configuration for ppc64-softmmu
 
+include pci.mak
 CONFIG_GDBSTUB_XML=y
-CONFIG_USB_OHCI=y
 CONFIG_ISA_MMIO=y
 CONFIG_ESCC=y
 CONFIG_M48T59=y
@@ -31,7 +31,6 @@ CONFIG_IDE_CMD646=y
 CONFIG_IDE_MACIO=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
 CONFIG_PTIMER=y
diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak
index 8f1cc09add..2b52d4a3f3 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ -1,7 +1,7 @@
 # Default configuration for ppcemb-softmmu
 
+include pci.mak
 CONFIG_GDBSTUB_XML=y
-CONFIG_USB_OHCI=y
 CONFIG_ISA_MMIO=y
 CONFIG_ESCC=y
 CONFIG_M48T59=y
@@ -31,7 +31,6 @@ CONFIG_IDE_CMD646=y
 CONFIG_IDE_MACIO=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
 CONFIG_PTIMER=y
diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
index e69de29bb2..3005729204 100644
--- a/default-configs/s390x-softmmu.mak
+++ b/default-configs/s390x-softmmu.mak
@@ -0,0 +1 @@
+CONFIG_VIRTIO=y
diff --git a/default-configs/sh4-softmmu.mak b/default-configs/sh4-softmmu.mak
index 866ed7de34..87247a4e53 100644
--- a/default-configs/sh4-softmmu.mak
+++ b/default-configs/sh4-softmmu.mak
@@ -1,9 +1,8 @@
 # Default configuration for sh4-softmmu
 
-CONFIG_USB_OHCI=y
+include pci.mak
 CONFIG_SERIAL=y
 CONFIG_PTIMER=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_IDE_CORE=y
 CONFIG_PFLASH_CFI02=y
 CONFIG_ISA_MMIO=y
diff --git a/default-configs/sh4eb-softmmu.mak b/default-configs/sh4eb-softmmu.mak
index e3e08b7f1a..5b8a16eea2 100644
--- a/default-configs/sh4eb-softmmu.mak
+++ b/default-configs/sh4eb-softmmu.mak
@@ -1,9 +1,8 @@
 # Default configuration for sh4eb-softmmu
 
-CONFIG_USB_OHCI=y
+include pci.mak
 CONFIG_SERIAL=y
 CONFIG_PTIMER=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_IDE_CORE=y
 CONFIG_PFLASH_CFI02=y
 CONFIG_ISA_MMIO=y
diff --git a/default-configs/sparc-softmmu.mak b/default-configs/sparc-softmmu.mak
index becf88096c..b0310c51e2 100644
--- a/default-configs/sparc-softmmu.mak
+++ b/default-configs/sparc-softmmu.mak
@@ -6,5 +6,5 @@ CONFIG_ESCC=y
 CONFIG_M48T59=y
 CONFIG_PTIMER=y
 CONFIG_FDC=y
-CONFIG_VIRTIO_PCI=y
 CONFIG_EMPTY_SLOT=y
+CONFIG_PCNET_COMMON=y
diff --git a/default-configs/sparc64-softmmu.mak b/default-configs/sparc64-softmmu.mak
index 1cc3f13079..ecc31228ba 100644
--- a/default-configs/sparc64-softmmu.mak
+++ b/default-configs/sparc64-softmmu.mak
@@ -1,5 +1,6 @@
 # Default configuration for sparc64-softmmu
 
+include pci.mak
 CONFIG_ISA_MMIO=y
 CONFIG_M48T59=y
 CONFIG_PTIMER=y
@@ -13,4 +14,3 @@ CONFIG_IDE_QDEV=y
 CONFIG_IDE_PCI=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_CMD646=y
-CONFIG_VIRTIO_PCI=y
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index 518320377f..7f22599fc8 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -1,6 +1,6 @@
 # Default configuration for x86_64-softmmu
 
-CONFIG_USB_OHCI=y
+include pci.mak
 CONFIG_VGA_PCI=y
 CONFIG_VGA_ISA=y
 CONFIG_VMWARE_VGA=y
@@ -9,7 +9,6 @@ CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
 CONFIG_PCKBD=y
-CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_APM=y
@@ -22,4 +21,3 @@ CONFIG_IDE_PIIX=y
 CONFIG_NE2000_ISA=y
 CONFIG_PIIX_PCI=y
 CONFIG_SOUND=y
-CONFIG_VIRTIO_PCI=y
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index f549089a55..173d78148d 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -52,6 +52,7 @@ struct pci_status {
 
 typedef struct PIIX4PMState {
     PCIDevice dev;
+    IORange ioport;
     uint16_t pmsts;
     uint16_t pmen;
     uint16_t pmcntrl;
@@ -128,10 +129,16 @@ static void pm_tmr_timer(void *opaque)
     pm_update_sci(s);
 }
 
-static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
+static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
+                            uint64_t val)
 {
-    PIIX4PMState *s = opaque;
-    addr &= 0x3f;
+    PIIX4PMState *s = container_of(ioport, PIIX4PMState, ioport);
+
+    if (width != 2) {
+        PIIX4_DPRINTF("PM write port=0x%04x width=%d val=0x%08x\n",
+                      (unsigned)addr, width, (unsigned)val);
+    }
+
     switch(addr) {
     case 0x00:
         {
@@ -184,12 +191,12 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
     PIIX4_DPRINTF("PM writew port=0x%04x val=0x%04x\n", addr, val);
 }
 
-static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
+static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
+                            uint64_t *data)
 {
-    PIIX4PMState *s = opaque;
+    PIIX4PMState *s = container_of(ioport, PIIX4PMState, ioport);
     uint32_t val;
 
-    addr &= 0x3f;
     switch(addr) {
     case 0x00:
         val = get_pmsts(s);
@@ -200,27 +207,6 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
     case 0x04:
         val = s->pmcntrl;
         break;
-    default:
-        val = 0;
-        break;
-    }
-    PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", addr, val);
-    return val;
-}
-
-static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    //    PIIX4PMState *s = opaque;
-    PIIX4_DPRINTF("PM writel port=0x%04x val=0x%08x\n", addr & 0x3f, val);
-}
-
-static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
-{
-    PIIX4PMState *s = opaque;
-    uint32_t val;
-
-    addr &= 0x3f;
-    switch(addr) {
     case 0x08:
         val = get_pmtmr(s);
         break;
@@ -228,10 +214,15 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
         val = 0;
         break;
     }
-    PIIX4_DPRINTF("PM readl port=0x%04x val=0x%08x\n", addr, val);
-    return val;
+    PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", addr, val);
+    *data = val;
 }
 
+static const IORangeOps pm_iorange_ops = {
+    .read = pm_ioport_read,
+    .write = pm_ioport_write,
+};
+
 static void apm_ctrl_changed(uint32_t val, void *arg)
 {
     PIIX4PMState *s = arg;
@@ -265,10 +256,8 @@ static void pm_io_space_update(PIIX4PMState *s)
 
         /* XXX: need to improve memory and ioport allocation */
         PIIX4_DPRINTF("PM: mapping to 0x%x\n", pm_io_base);
-        register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s);
-        register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s);
-        register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s);
-        register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s);
+        iorange_init(&s->ioport, &pm_iorange_ops, pm_io_base, 64);
+        ioport_register(&s->ioport);
     }
 }
 
diff --git a/hw/pc.c b/hw/pc.c
index c34d194c25..119c1106c2 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -430,8 +430,8 @@ static void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val)
         /* Bochs BIOS messages */
     case 0x400:
     case 0x401:
-        fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val);
-        exit(1);
+        /* used to be panic, now unused */
+        break;
     case 0x402:
     case 0x403:
 #ifdef DEBUG_BIOS
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 12359a75c9..7d29d43190 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -212,7 +212,7 @@ static void pc_init_isa(ram_addr_t ram_size,
 }
 
 static QEMUMachine pc_machine = {
-    .name = "pc-0.13",
+    .name = "pc-0.14",
     .alias = "pc",
     .desc = "Standard PC",
     .init = pc_init_pci,
@@ -220,6 +220,29 @@ static QEMUMachine pc_machine = {
     .is_default = 1,
 };
 
+static QEMUMachine pc_machine_v0_13 = {
+    .name = "pc-0.13",
+    .desc = "Standard PC",
+    .init = pc_init_pci,
+    .max_cpus = 255,
+    .compat_props = (GlobalProperty[]) {
+        {
+            .driver   = "virtio-9p-pci",
+            .property = "vectors",
+            .value    = stringify(0),
+        },{
+            .driver   = "VGA",
+            .property = "rombar",
+            .value    = stringify(0),
+        },{
+            .driver   = "vmware-svga",
+            .property = "rombar",
+            .value    = stringify(0),
+        },
+        { /* end of list */ }
+    },
+};
+
 static QEMUMachine pc_machine_v0_12 = {
     .name = "pc-0.12",
     .desc = "Standard PC",
@@ -234,6 +257,14 @@ static QEMUMachine pc_machine_v0_12 = {
             .driver   = "virtio-serial-pci",
             .property = "vectors",
             .value    = stringify(0),
+        },{
+            .driver   = "VGA",
+            .property = "rombar",
+            .value    = stringify(0),
+        },{
+            .driver   = "vmware-svga",
+            .property = "rombar",
+            .value    = stringify(0),
         },
         { /* end of list */ }
     }
@@ -331,6 +362,7 @@ static QEMUMachine isapc_machine = {
 static void pc_machine_init(void)
 {
     qemu_register_machine(&pc_machine);
+    qemu_register_machine(&pc_machine_v0_13);
     qemu_register_machine(&pc_machine_v0_12);
     qemu_register_machine(&pc_machine_v0_11);
     qemu_register_machine(&pc_machine_v0_10);
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
new file mode 100644
index 0000000000..3dfbe46472
--- /dev/null
+++ b/hw/pcnet-pci.c
@@ -0,0 +1,345 @@
+/*
+ * QEMU AMD PC-Net II (Am79C970A) PCI emulation
+ *
+ * Copyright (c) 2004 Antony T Curtis
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* This software was written to be compatible with the specification:
+ * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
+ * AMD Publication# 19436  Rev:E  Amendment/0  Issue Date: June 2000
+ */
+
+#include "pci.h"
+#include "net.h"
+#include "loader.h"
+#include "qemu-timer.h"
+
+#include "pcnet.h"
+
+//#define PCNET_DEBUG
+//#define PCNET_DEBUG_IO
+//#define PCNET_DEBUG_BCR
+//#define PCNET_DEBUG_CSR
+//#define PCNET_DEBUG_RMD
+//#define PCNET_DEBUG_TMD
+//#define PCNET_DEBUG_MATCH
+
+
+typedef struct {
+    PCIDevice pci_dev;
+    PCNetState state;
+} PCIPCNetState;
+
+static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCNetState *s = opaque;
+#ifdef PCNET_DEBUG
+    printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
+#endif
+    /* Check APROMWE bit to enable write access */
+    if (pcnet_bcr_readw(s,2) & 0x100)
+        s->prom[addr & 15] = val;
+}
+
+static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
+{
+    PCNetState *s = opaque;
+    uint32_t val = s->prom[addr & 15];
+#ifdef PCNET_DEBUG
+    printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
+#endif
+    return val;
+}
+
+static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
+                             pcibus_t addr, pcibus_t size, int type)
+{
+    PCNetState *d = &DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state;
+
+#ifdef PCNET_DEBUG_IO
+    printf("pcnet_ioport_map addr=0x%04"FMT_PCIBUS" size=0x%04"FMT_PCIBUS"\n",
+           addr, size);
+#endif
+
+    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
+    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
+
+    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
+    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
+    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
+    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
+}
+
+static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    PCNetState *d = opaque;
+#ifdef PCNET_DEBUG_IO
+    printf("pcnet_mmio_writeb addr=0x" TARGET_FMT_plx" val=0x%02x\n", addr,
+           val);
+#endif
+    if (!(addr & 0x10))
+        pcnet_aprom_writeb(d, addr & 0x0f, val);
+}
+
+static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
+{
+    PCNetState *d = opaque;
+    uint32_t val = -1;
+    if (!(addr & 0x10))
+        val = pcnet_aprom_readb(d, addr & 0x0f);
+#ifdef PCNET_DEBUG_IO
+    printf("pcnet_mmio_readb addr=0x" TARGET_FMT_plx " val=0x%02x\n", addr,
+           val & 0xff);
+#endif
+    return val;
+}
+
+static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    PCNetState *d = opaque;
+#ifdef PCNET_DEBUG_IO
+    printf("pcnet_mmio_writew addr=0x" TARGET_FMT_plx " val=0x%04x\n", addr,
+           val);
+#endif
+    if (addr & 0x10)
+        pcnet_ioport_writew(d, addr & 0x0f, val);
+    else {
+        addr &= 0x0f;
+        pcnet_aprom_writeb(d, addr, val & 0xff);
+        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
+    }
+}
+
+static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
+{
+    PCNetState *d = opaque;
+    uint32_t val = -1;
+    if (addr & 0x10)
+        val = pcnet_ioport_readw(d, addr & 0x0f);
+    else {
+        addr &= 0x0f;
+        val = pcnet_aprom_readb(d, addr+1);
+        val <<= 8;
+        val |= pcnet_aprom_readb(d, addr);
+    }
+#ifdef PCNET_DEBUG_IO
+    printf("pcnet_mmio_readw addr=0x" TARGET_FMT_plx" val = 0x%04x\n", addr,
+           val & 0xffff);
+#endif
+    return val;
+}
+
+static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    PCNetState *d = opaque;
+#ifdef PCNET_DEBUG_IO
+    printf("pcnet_mmio_writel addr=0x" TARGET_FMT_plx" val=0x%08x\n", addr,
+           val);
+#endif
+    if (addr & 0x10)
+        pcnet_ioport_writel(d, addr & 0x0f, val);
+    else {
+        addr &= 0x0f;
+        pcnet_aprom_writeb(d, addr, val & 0xff);
+        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
+        pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);
+        pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);
+    }
+}
+
+static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
+{
+    PCNetState *d = opaque;
+    uint32_t val;
+    if (addr & 0x10)
+        val = pcnet_ioport_readl(d, addr & 0x0f);
+    else {
+        addr &= 0x0f;
+        val = pcnet_aprom_readb(d, addr+3);
+        val <<= 8;
+        val |= pcnet_aprom_readb(d, addr+2);
+        val <<= 8;
+        val |= pcnet_aprom_readb(d, addr+1);
+        val <<= 8;
+        val |= pcnet_aprom_readb(d, addr);
+    }
+#ifdef PCNET_DEBUG_IO
+    printf("pcnet_mmio_readl addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr,
+           val);
+#endif
+    return val;
+}
+
+static const VMStateDescription vmstate_pci_pcnet = {
+    .name = "pcnet",
+    .version_id = 3,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
+    .fields      = (VMStateField []) {
+        VMSTATE_PCI_DEVICE(pci_dev, PCIPCNetState),
+        VMSTATE_STRUCT(state, PCIPCNetState, 0, vmstate_pcnet, PCNetState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+/* PCI interface */
+
+static CPUWriteMemoryFunc * const pcnet_mmio_write[] = {
+    &pcnet_mmio_writeb,
+    &pcnet_mmio_writew,
+    &pcnet_mmio_writel
+};
+
+static CPUReadMemoryFunc * const pcnet_mmio_read[] = {
+    &pcnet_mmio_readb,
+    &pcnet_mmio_readw,
+    &pcnet_mmio_readl
+};
+
+static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
+                            pcibus_t addr, pcibus_t size, int type)
+{
+    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev);
+
+#ifdef PCNET_DEBUG_IO
+    printf("pcnet_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n",
+           addr, size);
+#endif
+
+    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->state.mmio_index);
+}
+
+static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
+                                      uint8_t *buf, int len, int do_bswap)
+{
+    cpu_physical_memory_write(addr, buf, len);
+}
+
+static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
+                                     uint8_t *buf, int len, int do_bswap)
+{
+    cpu_physical_memory_read(addr, buf, len);
+}
+
+static void pci_pcnet_cleanup(VLANClientState *nc)
+{
+    PCNetState *d = DO_UPCAST(NICState, nc, nc)->opaque;
+
+    pcnet_common_cleanup(d);
+}
+
+static int pci_pcnet_uninit(PCIDevice *dev)
+{
+    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev);
+
+    cpu_unregister_io_memory(d->state.mmio_index);
+    qemu_del_timer(d->state.poll_timer);
+    qemu_free_timer(d->state.poll_timer);
+    qemu_del_vlan_client(&d->state.nic->nc);
+    return 0;
+}
+
+static NetClientInfo net_pci_pcnet_info = {
+    .type = NET_CLIENT_TYPE_NIC,
+    .size = sizeof(NICState),
+    .can_receive = pcnet_can_receive,
+    .receive = pcnet_receive,
+    .cleanup = pci_pcnet_cleanup,
+};
+
+static int pci_pcnet_init(PCIDevice *pci_dev)
+{
+    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev);
+    PCNetState *s = &d->state;
+    uint8_t *pci_conf;
+
+#if 0
+    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
+        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
+#endif
+
+    pci_conf = pci_dev->config;
+
+    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
+    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE);
+    pci_set_word(pci_conf + PCI_STATUS,
+                 PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
+    pci_conf[PCI_REVISION_ID] = 0x10;
+    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
+
+    pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, 0x0);
+    pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0);
+
+    pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
+    pci_conf[PCI_MIN_GNT] = 0x06;
+    pci_conf[PCI_MAX_LAT] = 0xff;
+
+    /* Handler for memory-mapped I/O */
+    s->mmio_index =
+      cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state);
+
+    pci_register_bar(pci_dev, 0, PCNET_IOPORT_SIZE,
+                           PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map);
+
+    pci_register_bar(pci_dev, 1, PCNET_PNPMMIO_SIZE,
+                           PCI_BASE_ADDRESS_SPACE_MEMORY, pcnet_mmio_map);
+
+    s->irq = pci_dev->irq[0];
+    s->phys_mem_read = pci_physical_memory_read;
+    s->phys_mem_write = pci_physical_memory_write;
+
+    if (!pci_dev->qdev.hotplugged) {
+        static int loaded = 0;
+        if (!loaded) {
+            rom_add_option("pxe-pcnet.bin");
+            loaded = 1;
+        }
+    }
+
+    return pcnet_common_init(&pci_dev->qdev, s, &net_pci_pcnet_info);
+}
+
+static void pci_reset(DeviceState *dev)
+{
+    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev.qdev, dev);
+
+    pcnet_h_reset(&d->state);
+}
+
+static PCIDeviceInfo pcnet_info = {
+    .qdev.name  = "pcnet",
+    .qdev.size  = sizeof(PCIPCNetState),
+    .qdev.reset = pci_reset,
+    .qdev.vmsd  = &vmstate_pci_pcnet,
+    .init       = pci_pcnet_init,
+    .exit       = pci_pcnet_uninit,
+    .qdev.props = (Property[]) {
+        DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void pci_pcnet_register_devices(void)
+{
+    pci_qdev_register(&pcnet_info);
+}
+
+device_init(pci_pcnet_register_devices)
diff --git a/hw/pcnet.c b/hw/pcnet.c
index b52935adf1..37010b8fcf 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -35,9 +35,8 @@
  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR92C990.txt
  */
 
-#include "pci.h"
+#include "qdev.h"
 #include "net.h"
-#include "loader.h"
 #include "qemu-timer.h"
 #include "qemu_socket.h"
 
@@ -52,11 +51,6 @@
 //#define PCNET_DEBUG_MATCH
 
 
-typedef struct {
-    PCIDevice pci_dev;
-    PCNetState state;
-} PCIPCNetState;
-
 struct qemu_ether_header {
     uint8_t ether_dhost[6];
     uint8_t ether_shost[6];
@@ -704,7 +698,6 @@ static void pcnet_poll_timer(void *opaque);
 static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
 static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
 static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
-static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
 
 static void pcnet_s_reset(PCNetState *s)
 {
@@ -1048,9 +1041,10 @@ ssize_t pcnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size_)
     int crc_err = 0;
     int size = size_;
 
-    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
+    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size ||
+        (CSR_LOOP(s) && !s->looptest)) {
         return -1;
-
+    }
 #ifdef PCNET_DEBUG
     printf("pcnet_receive size=%d\n", size);
 #endif
@@ -1537,7 +1531,7 @@ static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
     }
 }
 
-static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
+uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
 {
     uint32_t val;
     rap &= 127;
@@ -1594,27 +1588,6 @@ void pcnet_h_reset(void *opaque)
     pcnet_poll_timer(s);
 }
 
-static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCNetState *s = opaque;
-#ifdef PCNET_DEBUG
-    printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
-#endif
-    /* Check APROMWE bit to enable write access */
-    if (pcnet_bcr_readw(s,2) & 0x100)
-        s->prom[addr & 15] = val;
-}
-
-static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
-{
-    PCNetState *s = opaque;
-    uint32_t val = s->prom[addr & 15];
-#ifdef PCNET_DEBUG
-    printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
-#endif
-    return val;
-}
-
 void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
 {
     PCNetState *s = opaque;
@@ -1667,7 +1640,7 @@ uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
     return val;
 }
 
-static void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
+void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
 {
     PCNetState *s = opaque;
     pcnet_poll_timer(s);
@@ -1697,7 +1670,7 @@ static void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
     pcnet_update_irq(s);
 }
 
-static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
+uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
 {
     PCNetState *s = opaque;
     uint32_t val = -1;
@@ -1726,125 +1699,6 @@ static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
     return val;
 }
 
-static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
-                             pcibus_t addr, pcibus_t size, int type)
-{
-    PCNetState *d = &DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state;
-
-#ifdef PCNET_DEBUG_IO
-    printf("pcnet_ioport_map addr=0x%04"FMT_PCIBUS" size=0x%04"FMT_PCIBUS"\n",
-           addr, size);
-#endif
-
-    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
-    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
-
-    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
-    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
-    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
-    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
-}
-
-static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    PCNetState *d = opaque;
-#ifdef PCNET_DEBUG_IO
-    printf("pcnet_mmio_writeb addr=0x" TARGET_FMT_plx" val=0x%02x\n", addr,
-           val);
-#endif
-    if (!(addr & 0x10))
-        pcnet_aprom_writeb(d, addr & 0x0f, val);
-}
-
-static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
-    PCNetState *d = opaque;
-    uint32_t val = -1;
-    if (!(addr & 0x10))
-        val = pcnet_aprom_readb(d, addr & 0x0f);
-#ifdef PCNET_DEBUG_IO
-    printf("pcnet_mmio_readb addr=0x" TARGET_FMT_plx " val=0x%02x\n", addr,
-           val & 0xff);
-#endif
-    return val;
-}
-
-static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    PCNetState *d = opaque;
-#ifdef PCNET_DEBUG_IO
-    printf("pcnet_mmio_writew addr=0x" TARGET_FMT_plx " val=0x%04x\n", addr,
-           val);
-#endif
-    if (addr & 0x10)
-        pcnet_ioport_writew(d, addr & 0x0f, val);
-    else {
-        addr &= 0x0f;
-        pcnet_aprom_writeb(d, addr, val & 0xff);
-        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
-    }
-}
-
-static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
-    PCNetState *d = opaque;
-    uint32_t val = -1;
-    if (addr & 0x10)
-        val = pcnet_ioport_readw(d, addr & 0x0f);
-    else {
-        addr &= 0x0f;
-        val = pcnet_aprom_readb(d, addr+1);
-        val <<= 8;
-        val |= pcnet_aprom_readb(d, addr);
-    }
-#ifdef PCNET_DEBUG_IO
-    printf("pcnet_mmio_readw addr=0x" TARGET_FMT_plx" val = 0x%04x\n", addr,
-           val & 0xffff);
-#endif
-    return val;
-}
-
-static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    PCNetState *d = opaque;
-#ifdef PCNET_DEBUG_IO
-    printf("pcnet_mmio_writel addr=0x" TARGET_FMT_plx" val=0x%08x\n", addr,
-           val);
-#endif
-    if (addr & 0x10)
-        pcnet_ioport_writel(d, addr & 0x0f, val);
-    else {
-        addr &= 0x0f;
-        pcnet_aprom_writeb(d, addr, val & 0xff);
-        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
-        pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);
-        pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);
-    }
-}
-
-static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
-    PCNetState *d = opaque;
-    uint32_t val;
-    if (addr & 0x10)
-        val = pcnet_ioport_readl(d, addr & 0x0f);
-    else {
-        addr &= 0x0f;
-        val = pcnet_aprom_readb(d, addr+3);
-        val <<= 8;
-        val |= pcnet_aprom_readb(d, addr+2);
-        val <<= 8;
-        val |= pcnet_aprom_readb(d, addr+1);
-        val <<= 8;
-        val |= pcnet_aprom_readb(d, addr);
-    }
-#ifdef PCNET_DEBUG_IO
-    printf("pcnet_mmio_readl addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr,
-           val);
-#endif
-    return val;
-}
-
 static bool is_version_2(void *opaque, int version_id)
 {
     return version_id == 2;
@@ -1874,18 +1728,6 @@ const VMStateDescription vmstate_pcnet = {
     }
 };
 
-static const VMStateDescription vmstate_pci_pcnet = {
-    .name = "pcnet",
-    .version_id = 3,
-    .minimum_version_id = 2,
-    .minimum_version_id_old = 2,
-    .fields      = (VMStateField []) {
-        VMSTATE_PCI_DEVICE(pci_dev, PCIPCNetState),
-        VMSTATE_STRUCT(state, PCIPCNetState, 0, vmstate_pcnet, PCNetState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
 void pcnet_common_cleanup(PCNetState *d)
 {
     d->nic = NULL;
@@ -1900,147 +1742,3 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
     return 0;
 }
-
-/* PCI interface */
-
-static CPUWriteMemoryFunc * const pcnet_mmio_write[] = {
-    &pcnet_mmio_writeb,
-    &pcnet_mmio_writew,
-    &pcnet_mmio_writel
-};
-
-static CPUReadMemoryFunc * const pcnet_mmio_read[] = {
-    &pcnet_mmio_readb,
-    &pcnet_mmio_readw,
-    &pcnet_mmio_readl
-};
-
-static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
-                            pcibus_t addr, pcibus_t size, int type)
-{
-    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev);
-
-#ifdef PCNET_DEBUG_IO
-    printf("pcnet_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n",
-           addr, size);
-#endif
-
-    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->state.mmio_index);
-}
-
-static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
-                                      uint8_t *buf, int len, int do_bswap)
-{
-    cpu_physical_memory_write(addr, buf, len);
-}
-
-static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
-                                     uint8_t *buf, int len, int do_bswap)
-{
-    cpu_physical_memory_read(addr, buf, len);
-}
-
-static void pci_pcnet_cleanup(VLANClientState *nc)
-{
-    PCNetState *d = DO_UPCAST(NICState, nc, nc)->opaque;
-
-    pcnet_common_cleanup(d);
-}
-
-static int pci_pcnet_uninit(PCIDevice *dev)
-{
-    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev);
-
-    cpu_unregister_io_memory(d->state.mmio_index);
-    qemu_del_timer(d->state.poll_timer);
-    qemu_free_timer(d->state.poll_timer);
-    qemu_del_vlan_client(&d->state.nic->nc);
-    return 0;
-}
-
-static NetClientInfo net_pci_pcnet_info = {
-    .type = NET_CLIENT_TYPE_NIC,
-    .size = sizeof(NICState),
-    .can_receive = pcnet_can_receive,
-    .receive = pcnet_receive,
-    .cleanup = pci_pcnet_cleanup,
-};
-
-static int pci_pcnet_init(PCIDevice *pci_dev)
-{
-    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev);
-    PCNetState *s = &d->state;
-    uint8_t *pci_conf;
-
-#if 0
-    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
-        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
-#endif
-
-    pci_conf = pci_dev->config;
-
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE);
-    pci_set_word(pci_conf + PCI_STATUS,
-                 PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
-    pci_conf[PCI_REVISION_ID] = 0x10;
-    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
-
-    pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, 0x0);
-    pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0);
-
-    pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
-    pci_conf[PCI_MIN_GNT] = 0x06;
-    pci_conf[PCI_MAX_LAT] = 0xff;
-
-    /* Handler for memory-mapped I/O */
-    s->mmio_index =
-      cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state);
-
-    pci_register_bar(pci_dev, 0, PCNET_IOPORT_SIZE,
-                           PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map);
-
-    pci_register_bar(pci_dev, 1, PCNET_PNPMMIO_SIZE,
-                           PCI_BASE_ADDRESS_SPACE_MEMORY, pcnet_mmio_map);
-
-    s->irq = pci_dev->irq[0];
-    s->phys_mem_read = pci_physical_memory_read;
-    s->phys_mem_write = pci_physical_memory_write;
-
-    if (!pci_dev->qdev.hotplugged) {
-        static int loaded = 0;
-        if (!loaded) {
-            rom_add_option("pxe-pcnet.bin");
-            loaded = 1;
-        }
-    }
-
-    return pcnet_common_init(&pci_dev->qdev, s, &net_pci_pcnet_info);
-}
-
-static void pci_reset(DeviceState *dev)
-{
-    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev.qdev, dev);
-
-    pcnet_h_reset(&d->state);
-}
-
-static PCIDeviceInfo pcnet_info = {
-    .qdev.name  = "pcnet",
-    .qdev.size  = sizeof(PCIPCNetState),
-    .qdev.reset = pci_reset,
-    .qdev.vmsd  = &vmstate_pci_pcnet,
-    .init       = pci_pcnet_init,
-    .exit       = pci_pcnet_uninit,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
-};
-
-static void pcnet_register_devices(void)
-{
-    pci_qdev_register(&pcnet_info);
-}
-
-device_init(pcnet_register_devices)
diff --git a/hw/pcnet.h b/hw/pcnet.h
index efacc9fa59..534bdf9c2b 100644
--- a/hw/pcnet.h
+++ b/hw/pcnet.h
@@ -32,6 +32,9 @@ struct PCNetState_st {
 void pcnet_h_reset(void *opaque);
 void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val);
 uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr);
+void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val);
+uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr);
+uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
 int pcnet_can_receive(VLANClientState *nc);
 ssize_t pcnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size_);
 void pcnet_common_cleanup(PCNetState *d);
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index b09789cd11..791ca22763 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -92,6 +92,11 @@ static int pci_vga_initfn(PCIDevice *dev)
      pci_register_bar(&d->dev, 0, VGA_RAM_SIZE,
                       PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
 
+     if (!dev->rom_bar) {
+         /* compatibility with pc-0.13 and older */
+         vga_init_vbe(s);
+     }
+
      return 0;
 }
 
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 49528a9977..e5f9b2795a 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -324,13 +324,13 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
     MultiReqBuffer *mrb)
 {
     if (req->elem.out_num < 1 || req->elem.in_num < 1) {
-        fprintf(stderr, "virtio-blk missing headers\n");
+        error_report("virtio-blk missing headers");
         exit(1);
     }
 
     if (req->elem.out_sg[0].iov_len < sizeof(*req->out) ||
         req->elem.in_sg[req->elem.in_num - 1].iov_len < sizeof(*req->in)) {
-        fprintf(stderr, "virtio-blk header not in correct element\n");
+        error_report("virtio-blk header not in correct element");
         exit(1);
     }
 
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 7e1688cf69..1d61f191b6 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -120,8 +120,8 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
     if (!n->vhost_started) {
         int r = vhost_net_start(tap_get_vhost_net(n->nic->nc.peer), &n->vdev);
         if (r < 0) {
-            fprintf(stderr, "unable to start vhost net: %d: "
-                    "falling back on userspace virtio\n", -r);
+            error_report("unable to start vhost net: %d: "
+                         "falling back on userspace virtio", -r);
         } else {
             n->vhost_started = 1;
         }
@@ -271,7 +271,7 @@ static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd,
     uint8_t on;
 
     if (elem->out_num != 2 || elem->out_sg[1].iov_len != sizeof(on)) {
-        fprintf(stderr, "virtio-net ctrl invalid rx mode command\n");
+        error_report("virtio-net ctrl invalid rx mode command");
         exit(1);
     }
 
@@ -353,7 +353,7 @@ static int virtio_net_handle_vlan_table(VirtIONet *n, uint8_t cmd,
     uint16_t vid;
 
     if (elem->out_num != 2 || elem->out_sg[1].iov_len != sizeof(vid)) {
-        fprintf(stderr, "virtio-net ctrl invalid vlan command\n");
+        error_report("virtio-net ctrl invalid vlan command");
         return VIRTIO_NET_ERR;
     }
 
@@ -381,13 +381,13 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
 
     while (virtqueue_pop(vq, &elem)) {
         if ((elem.in_num < 1) || (elem.out_num < 1)) {
-            fprintf(stderr, "virtio-net ctrl missing headers\n");
+            error_report("virtio-net ctrl missing headers");
             exit(1);
         }
 
         if (elem.out_sg[0].iov_len < sizeof(ctrl) ||
             elem.in_sg[elem.in_num - 1].iov_len < sizeof(status)) {
-            fprintf(stderr, "virtio-net ctrl header not in correct element\n");
+            error_report("virtio-net ctrl header not in correct element");
             exit(1);
         }
 
@@ -591,21 +591,21 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_
         if (virtqueue_pop(n->rx_vq, &elem) == 0) {
             if (i == 0)
                 return -1;
-            fprintf(stderr, "virtio-net unexpected empty queue: "
+            error_report("virtio-net unexpected empty queue: "
                     "i %zd mergeable %d offset %zd, size %zd, "
-                    "guest hdr len %zd, host hdr len %zd guest features 0x%x\n",
+                    "guest hdr len %zd, host hdr len %zd guest features 0x%x",
                     i, n->mergeable_rx_bufs, offset, size,
                     guest_hdr_len, host_hdr_len, n->vdev.guest_features);
             exit(1);
         }
 
         if (elem.in_num < 1) {
-            fprintf(stderr, "virtio-net receive queue contains no in buffers\n");
+            error_report("virtio-net receive queue contains no in buffers");
             exit(1);
         }
 
         if (!n->mergeable_rx_bufs && elem.in_sg[0].iov_len != guest_hdr_len) {
-            fprintf(stderr, "virtio-net header not in first element\n");
+            error_report("virtio-net header not in first element");
             exit(1);
         }
 
@@ -630,12 +630,11 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_
          * Otherwise, drop it. */
         if (!n->mergeable_rx_bufs && offset < size) {
 #if 0
-            fprintf(stderr, "virtio-net truncated non-mergeable packet: "
-
-                    "i %zd mergeable %d offset %zd, size %zd, "
-                    "guest hdr len %zd, host hdr len %zd\n",
-                    i, n->mergeable_rx_bufs,
-                    offset, size, guest_hdr_len, host_hdr_len);
+            error_report("virtio-net truncated non-mergeable packet: "
+                         "i %zd mergeable %d offset %zd, size %zd, "
+                         "guest hdr len %zd, host hdr len %zd",
+                         i, n->mergeable_rx_bufs,
+                         offset, size, guest_hdr_len, host_hdr_len);
 #endif
             return size;
         }
@@ -695,7 +694,7 @@ static int32_t virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
             sizeof(struct virtio_net_hdr);
 
         if (out_num < 1 || out_sg->iov_len != hdr_len) {
-            fprintf(stderr, "virtio-net header not in first element\n");
+            error_report("virtio-net header not in first element");
             exit(1);
         }
 
@@ -981,10 +980,10 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
     n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
 
     if (net->tx && strcmp(net->tx, "timer") && strcmp(net->tx, "bh")) {
-        fprintf(stderr, "virtio-net: "
-                "Unknown option tx=%s, valid options: \"timer\" \"bh\"\n",
-                net->tx);
-        fprintf(stderr, "Defaulting to \"bh\"\n");
+        error_report("virtio-net: "
+                     "Unknown option tx=%s, valid options: \"timer\" \"bh\"",
+                     net->tx);
+        error_report("Defaulting to \"bh\"");
     }
 
     if (net->tx && !strcmp(net->tx, "timer")) {
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 729917d891..c65765a273 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -254,8 +254,8 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
         virtio_queue_set_vector(vdev, vdev->queue_sel, val);
         break;
     default:
-        fprintf(stderr, "%s: unexpected address 0x%x value 0x%x\n",
-                __func__, addr, val);
+        error_report("%s: unexpected address 0x%x value 0x%x",
+                     __func__, addr, val);
         break;
     }
 }
@@ -684,12 +684,14 @@ static int virtio_9p_init_pci(PCIDevice *pci_dev)
     VirtIODevice *vdev;
 
     vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf);
+    vdev->nvectors = proxy->nvectors;
     virtio_init_pci(proxy, vdev,
                     PCI_VENDOR_ID_REDHAT_QUMRANET,
                     0x1009,
                     0x2,
                     0x00);
-
+    /* make the actual value visible */
+    proxy->nvectors = vdev->nvectors;
     return 0;
 }
 #endif
@@ -758,6 +760,7 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.size = sizeof(VirtIOPCIProxy),
         .init      = virtio_9p_init_pci,
         .qdev.props = (Property[]) {
+            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
             DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
             DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
             DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
diff --git a/hw/virtio.c b/hw/virtio.c
index a2a657e132..849a60faaa 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -14,6 +14,7 @@
 #include <inttypes.h>
 
 #include "trace.h"
+#include "qemu-error.h"
 #include "virtio.h"
 #include "sysemu.h"
 
@@ -253,8 +254,8 @@ static int virtqueue_num_heads(VirtQueue *vq, unsigned int idx)
 
     /* Check it isn't doing very strange things with descriptor numbers. */
     if (num_heads > vq->vring.num) {
-        fprintf(stderr, "Guest moved used index from %u to %u",
-                idx, vring_avail_idx(vq));
+        error_report("Guest moved used index from %u to %u",
+                     idx, vring_avail_idx(vq));
         exit(1);
     }
 
@@ -271,7 +272,7 @@ static unsigned int virtqueue_get_head(VirtQueue *vq, unsigned int idx)
 
     /* If their number is silly, that's a fatal mistake. */
     if (head >= vq->vring.num) {
-        fprintf(stderr, "Guest says index %u is available", head);
+        error_report("Guest says index %u is available", head);
         exit(1);
     }
 
@@ -293,7 +294,7 @@ static unsigned virtqueue_next_desc(target_phys_addr_t desc_pa,
     wmb();
 
     if (next >= max) {
-        fprintf(stderr, "Desc next is %u", next);
+        error_report("Desc next is %u", next);
         exit(1);
     }
 
@@ -320,13 +321,13 @@ int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes)
 
         if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
             if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
-                fprintf(stderr, "Invalid size for indirect buffer table\n");
+                error_report("Invalid size for indirect buffer table");
                 exit(1);
             }
 
             /* If we've got too many, that implies a descriptor loop. */
             if (num_bufs >= max) {
-                fprintf(stderr, "Looped descriptor");
+                error_report("Looped descriptor");
                 exit(1);
             }
 
@@ -340,7 +341,7 @@ int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes)
         do {
             /* If we've got too many, that implies a descriptor loop. */
             if (++num_bufs > max) {
-                fprintf(stderr, "Looped descriptor");
+                error_report("Looped descriptor");
                 exit(1);
             }
 
@@ -374,7 +375,7 @@ void virtqueue_map_sg(struct iovec *sg, target_phys_addr_t *addr,
         len = sg[i].iov_len;
         sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
         if (sg[i].iov_base == NULL || len != sg[i].iov_len) {
-            fprintf(stderr, "virtio: trying to map MMIO memory\n");
+            error_report("virtio: trying to map MMIO memory");
             exit(1);
         }
     }
@@ -397,7 +398,7 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
 
     if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
         if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
-            fprintf(stderr, "Invalid size for indirect buffer table\n");
+            error_report("Invalid size for indirect buffer table");
             exit(1);
         }
 
@@ -423,7 +424,7 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
 
         /* If we've got too many, that implies a descriptor loop. */
         if ((elem->in_num + elem->out_num) > max) {
-            fprintf(stderr, "Looped descriptor");
+            error_report("Looped descriptor");
             exit(1);
         }
     } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
@@ -694,8 +695,8 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
     qemu_get_be16s(f, &vdev->queue_sel);
     qemu_get_be32s(f, &features);
     if (features & ~supported_features) {
-        fprintf(stderr, "Features 0x%x unsupported. Allowed features: 0x%x\n",
-                features, supported_features);
+        error_report("Features 0x%x unsupported. Allowed features: 0x%x",
+                     features, supported_features);
         return -1;
     }
     if (vdev->set_features)
@@ -717,11 +718,11 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
 	num_heads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx;
 	/* Check it isn't doing very strange things with descriptor numbers. */
 	if (num_heads > vdev->vq[i].vring.num) {
-		fprintf(stderr, "VQ %d size 0x%x Guest index 0x%x "
-                        "inconsistent with Host index 0x%x: delta 0x%x\n",
-			i, vdev->vq[i].vring.num,
-                        vring_avail_idx(&vdev->vq[i]),
-                        vdev->vq[i].last_avail_idx, num_heads);
+		error_report("VQ %d size 0x%x Guest index 0x%x "
+		             "inconsistent with Host index 0x%x: delta 0x%x",
+		             i, vdev->vq[i].vring.num,
+		             vring_avail_idx(&vdev->vq[i]),
+		             vdev->vq[i].last_avail_idx, num_heads);
 		return -1;
 	}
         if (vdev->binding->load_queue) {
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 9337fdbfef..d0f4e1b5b5 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1301,6 +1301,11 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
 
     vmsvga_init(&s->chip, VGA_RAM_SIZE);
 
+    if (!dev->rom_bar) {
+        /* compatibility with pc-0.13 and older */
+        vga_init_vbe(&s->chip.vga);
+    }
+
     return 0;
 }
 
diff --git a/ioport.c b/ioport.c
index ec3dc65cdd..aa4188a40f 100644
--- a/ioport.c
+++ b/ioport.c
@@ -174,6 +174,70 @@ int register_ioport_write(pio_addr_t start, int length, int size,
     return 0;
 }
 
+static uint32_t ioport_readb_thunk(void *opaque, uint32_t addr)
+{
+    IORange *ioport = opaque;
+    uint64_t data;
+
+    ioport->ops->read(ioport, addr - ioport->base, 1, &data);
+    return data;
+}
+
+static uint32_t ioport_readw_thunk(void *opaque, uint32_t addr)
+{
+    IORange *ioport = opaque;
+    uint64_t data;
+
+    ioport->ops->read(ioport, addr - ioport->base, 2, &data);
+    return data;
+}
+
+static uint32_t ioport_readl_thunk(void *opaque, uint32_t addr)
+{
+    IORange *ioport = opaque;
+    uint64_t data;
+
+    ioport->ops->read(ioport, addr - ioport->base, 4, &data);
+    return data;
+}
+
+static void ioport_writeb_thunk(void *opaque, uint32_t addr, uint32_t data)
+{
+    IORange *ioport = opaque;
+
+    ioport->ops->write(ioport, addr - ioport->base, 1, data);
+}
+
+static void ioport_writew_thunk(void *opaque, uint32_t addr, uint32_t data)
+{
+    IORange *ioport = opaque;
+
+    ioport->ops->write(ioport, addr - ioport->base, 2, data);
+}
+
+static void ioport_writel_thunk(void *opaque, uint32_t addr, uint32_t data)
+{
+    IORange *ioport = opaque;
+
+    ioport->ops->write(ioport, addr - ioport->base, 4, data);
+}
+
+void ioport_register(IORange *ioport)
+{
+    register_ioport_read(ioport->base, ioport->len, 1,
+                         ioport_readb_thunk, ioport);
+    register_ioport_read(ioport->base, ioport->len, 2,
+                         ioport_readw_thunk, ioport);
+    register_ioport_read(ioport->base, ioport->len, 4,
+                         ioport_readl_thunk, ioport);
+    register_ioport_write(ioport->base, ioport->len, 1,
+                          ioport_writeb_thunk, ioport);
+    register_ioport_write(ioport->base, ioport->len, 2,
+                          ioport_writew_thunk, ioport);
+    register_ioport_write(ioport->base, ioport->len, 4,
+                          ioport_writel_thunk, ioport);
+}
+
 void isa_unassign_ioport(pio_addr_t start, int length)
 {
     int i;
diff --git a/ioport.h b/ioport.h
index 3d3c8a3efd..5ae62a3a2c 100644
--- a/ioport.h
+++ b/ioport.h
@@ -25,6 +25,7 @@
 #define IOPORT_H
 
 #include "qemu-common.h"
+#include "iorange.h"
 
 typedef uint32_t pio_addr_t;
 #define FMT_pioaddr     PRIx32
@@ -36,6 +37,7 @@ typedef uint32_t pio_addr_t;
 typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
 typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
 
+void ioport_register(IORange *iorange);
 int register_ioport_read(pio_addr_t start, int length, int size,
                          IOPortReadFunc *func, void *opaque);
 int register_ioport_write(pio_addr_t start, int length, int size,
diff --git a/iorange.h b/iorange.h
new file mode 100644
index 0000000000..97831683f0
--- /dev/null
+++ b/iorange.h
@@ -0,0 +1,30 @@
+#ifndef IORANGE_H
+#define IORANGE_H
+
+#include <stdint.h>
+
+typedef struct IORange IORange;
+typedef struct IORangeOps IORangeOps;
+
+struct IORangeOps {
+    void (*read)(IORange *iorange, uint64_t offset, unsigned width,
+                 uint64_t *data);
+    void (*write)(IORange *iorange, uint64_t offset, unsigned width,
+                  uint64_t data);
+};
+
+struct IORange {
+    const IORangeOps *ops;
+    uint64_t base;
+    uint64_t len;
+};
+
+static inline void iorange_init(IORange *iorange, const IORangeOps *ops,
+                                uint64_t base, uint64_t len)
+{
+    iorange->ops = ops;
+    iorange->base = base;
+    iorange->len = len;
+}
+
+#endif
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 77683f7534..7c62fac938 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -3071,11 +3071,11 @@ struct target_stack_t {
 };
 
 struct target_ucontext {
-    abi_ulong uc_flags;
-    abi_ulong uc_link;
-    struct target_stack_t uc_stack;
-    struct target_sigcontext sc;
-    uint32_t extramask[TARGET_NSIG_WORDS - 1];
+    abi_ulong tuc_flags;
+    abi_ulong tuc_link;
+    struct target_stack_t tuc_stack;
+    struct target_sigcontext tuc_mcontext;
+    uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
 };
 
 /* Signal frames. */
@@ -3189,7 +3189,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
         goto badframe;
 
     /* Save the mask.  */
-    err |= __put_user(set->sig[0], &frame->uc.sc.oldmask);
+    err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
     if (err)
         goto badframe;
 
@@ -3198,7 +3198,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
             goto badframe;
     }
 
-    setup_sigcontext(&frame->uc.sc, env);
+    setup_sigcontext(&frame->uc.tuc_mcontext, env);
 
     /* Set up to return from userspace. If provided, use a stub
        already in userspace. */
@@ -3261,7 +3261,7 @@ long do_sigreturn(CPUState *env)
         goto badframe;
 
     /* Restore blocked signals */
-    if (__get_user(target_set.sig[0], &frame->uc.sc.oldmask))
+    if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
         goto badframe;
     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
         if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
@@ -3270,7 +3270,7 @@ long do_sigreturn(CPUState *env)
     target_to_host_sigset_internal(&set, &target_set);
     sigprocmask(SIG_SETMASK, &set, NULL);
 
-    restore_sigcontext(&frame->uc.sc, env);
+    restore_sigcontext(&frame->uc.tuc_mcontext, env);
     /* We got here through a sigreturn syscall, our path back is via an
        rtb insn so setup r14 for that.  */
     env->regs[14] = env->sregs[SR_PC];
diff --git a/make_device_config.sh b/make_device_config.sh
new file mode 100644
index 0000000000..8abadfef7c
--- /dev/null
+++ b/make_device_config.sh
@@ -0,0 +1,28 @@
+#! /bin/sh
+# Construct a target device config file from a default, pulling in any
+# files from include directives.
+
+dest=$1.tmp
+dep=$1.d
+src=$2
+src_dir=`dirname $src`
+all_includes=
+
+process_includes () {
+  cat $1 | grep '^include' | \
+  while read include file ; do
+    all_includes="$all_includes $src_dir/$file"
+    process_includes $src_dir/$file
+  done
+}
+
+f=$src
+while [ -n "$f" ] ; do
+  f=`awk '/^include / {ORS=" " ; print "'$src_dir'/" $2}' $f`
+  [ $? = 0 ] || exit 1
+  all_includes="$all_includes $f"
+done
+process_includes $src > $dest
+
+cat $src $all_includes | grep -v '^include' > $dest
+echo "$1: $all_includes" > $dep
diff --git a/pc-bios/optionrom/signrom.sh b/pc-bios/optionrom/signrom.sh
index 975b27dd60..9dc5c63dde 100755
--- a/pc-bios/optionrom/signrom.sh
+++ b/pc-bios/optionrom/signrom.sh
@@ -31,14 +31,13 @@ x=`dd if="$1" bs=1 count=1 skip=2 2>/dev/null | od -t u1 -A n`
 size=$(( $x * 512 - 1 ))
 
 # now get the checksum
-nums=`od -A n -t u1 -v "$1"`
+nums=`od -A n -t u1 -v -N $size "$1"`
 for i in ${nums}; do
     # add each byte's value to sum
-    sum=`expr $sum + $i`
+    sum=`expr \( $sum + $i \) % 256`
 done
 
-sum=$(( $sum % 256 ))
-sum=$(( 256 - $sum ))
+sum=$(( (256 - $sum) % 256 ))
 sum_octal=$( printf "%o" $sum )
 
 # and write the output file
diff --git a/simpletrace.h b/simpletrace.h
index 72614ec1d1..2f44ed3c3c 100644
--- a/simpletrace.h
+++ b/simpletrace.h
@@ -29,10 +29,10 @@ void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3);
 void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4);
 void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5);
 void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6);
-void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...));
-void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...));
+void st_print_trace(FILE *stream, fprintf_function stream_printf);
+void st_print_trace_events(FILE *stream, fprintf_function stream_printf);
 bool st_change_trace_event_state(const char *tname, bool tstate);
-void st_print_trace_file_status(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...));
+void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
 void st_set_trace_file_enabled(bool enable);
 bool st_set_trace_file(const char *file);
 void st_flush_trace_buffer(void);
diff --git a/slirp/misc.c b/slirp/misc.c
index 1aeb401082..19dbec491f 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -264,48 +264,6 @@ void lprint(const char *format, ...)
     va_end(args);
 }
 
-#ifdef BAD_SPRINTF
-
-#undef vsprintf
-#undef sprintf
-
-/*
- * Some BSD-derived systems have a sprintf which returns char *
- */
-
-int
-vsprintf_len(string, format, args)
-	char *string;
-	const char *format;
-	va_list args;
-{
-	vsprintf(string, format, args);
-	return strlen(string);
-}
-
-int
-#ifdef __STDC__
-sprintf_len(char *string, const char *format, ...)
-#else
-sprintf_len(va_alist) va_dcl
-#endif
-{
-	va_list args;
-#ifdef __STDC__
-	va_start(args, format);
-#else
-	char *string;
-	char *format;
-	va_start(args);
-	string = va_arg(args, char *);
-	format = va_arg(args, char *);
-#endif
-	vsprintf(string, format, args);
-	return strlen(string);
-}
-
-#endif
-
 void
 u_sleep(int usec)
 {
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 462292d577..dfd977aa0c 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -237,20 +237,6 @@ void if_start(Slirp *);
 void if_start(struct ttys *);
 #endif
 
-#ifdef BAD_SPRINTF
-# define vsprintf vsprintf_len
-# define sprintf sprintf_len
- extern int vsprintf_len(char *, const char *, va_list);
- extern int sprintf_len(char *, const char *, ...);
-#endif
-
-#ifdef DECLARE_SPRINTF
-# ifndef BAD_SPRINTF
- extern int vsprintf(char *, const char *, va_list);
-# endif
- extern int vfprintf(FILE *, const char *, va_list);
-#endif
-
 #ifndef HAVE_STRERROR
  extern char *strerror(int error);
 #endif
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index f19c7034ca..18db45c8e4 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -85,9 +85,6 @@
 /* Define if the machine is big endian */
 //#undef HOST_WORDS_BIGENDIAN
 
-/* Define if your sprintf returns char * instead of int */
-#undef BAD_SPRINTF
-
 /* Define if you have readv */
 #undef HAVE_READV
 
@@ -97,9 +94,6 @@
 #define DECLARE_IOVEC
 #endif
 
-/* Define if a declaration of sprintf/fprintf is needed */
-#undef DECLARE_SPRINTF
-
 /* Define if you have a POSIX.1 sys/wait.h */
 #undef HAVE_SYS_WAIT_H
 
diff --git a/trace-events b/trace-events
index 947f8b08cb..da03d4be12 100644
--- a/trace-events
+++ b/trace-events
@@ -189,3 +189,6 @@ disable sun4m_iommu_mem_writel_pgflush(uint32_t val) "page flush %x"
 disable sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret) "get flags addr %"PRIx64" => pte %"PRIx64", *pte = %x"
 disable sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte) "xlate dva %"PRIx64" => pa %"PRIx64" iopte = %x"
 disable sun4m_iommu_bad_addr(uint64_t addr) "bad addr %"PRIx64""
+
+# vl.c
+disable vm_state_notify(int running, int reason) "running %d reason %d"
diff --git a/tracetool b/tracetool
index d797ab79a3..fce491c505 100755
--- a/tracetool
+++ b/tracetool
@@ -23,14 +23,15 @@ Backends:
   --dtrace  DTrace/SystemTAP backend
 
 Output formats:
-  -h    Generate .h file
-  -c    Generate .c file
-  -d    Generate .d file (DTrace only)
-  -s    Generate .stp file (DTrace with SystemTAP only)
+  -h     Generate .h file
+  -c     Generate .c file
+  -d     Generate .d file (DTrace only)
+  --stap Generate .stp file (DTrace with SystemTAP only)
 
 Options:
-  --bindir [bindir]  QEMU binary install location
-  --target [arch]    QEMU target architecture
+  --binary      [path]  Full path to QEMU binary
+  --target-arch [arch]  QEMU emulator target arch
+  --target-type [type]  QEMU emulator target type ('system' or 'user')
 
 EOF
     exit 1
@@ -383,6 +384,12 @@ linetod_dtrace()
         name=${name##disable }
     fi
 
+    # DTrace provider syntax expects foo() for empty
+    # params, not foo(void)
+    if [ "$args" = "void" ]; then
+       args=""
+    fi
+
     # Define prototype for probe arguments
     cat <<EOF
         probe $name($args);
@@ -396,14 +403,14 @@ linetod_end_dtrace()
 EOF
 }
 
-linetos_begin_dtrace()
+linetostap_begin_dtrace()
 {
     return
 }
 
-linetos_dtrace()
+linetostap_dtrace()
 {
-    local name args arglist state
+    local i arg name args arglist state
     name=$(get_name "$1")
     args=$(get_args "$1")
     arglist=$(get_argnames "$1", "")
@@ -412,22 +419,19 @@ linetos_dtrace()
         name=${name##disable }
     fi
 
-    if [ "$target" = "i386" ]
-    then
-      binary="qemu"
-    else
-      binary="qemu-system-$target"
-    fi
-
     # Define prototype for probe arguments
     cat <<EOF
-probe qemu.system.$target.$name = process("$bindir/$binary").mark("$name")
+probe qemu.$targettype.$targetarch.$name = process("$binary").mark("$name")
 {
 EOF
 
     i=1
     for arg in $arglist
     do
+        # 'limit' is a reserved keyword
+        if [ "$arg" = "limit" ]; then
+          arg="_limit"
+        fi
         cat <<EOF
   $arg = \$arg$i;
 EOF
@@ -439,7 +443,7 @@ EOF
 EOF
 }
 
-linetos_end_dtrace()
+linetostap_end_dtrace()
 {
     return
 }
@@ -509,57 +513,61 @@ tracetod()
     convert d
 }
 
-tracetos()
+tracetostap()
 {
     if [ $backend != "dtrace" ]; then
        echo "SystemTAP tapset generator not applicable to $backend backend"
        exit 1
     fi
-    if [ -z "$target" ]; then
-       echo "--target is required for SystemTAP tapset generator"
+    if [ -z "$binary" ]; then
+       echo "--binary is required for SystemTAP tapset generator"
        exit 1
     fi
-    if [ -z "$bindir" ]; then
-       echo "--bindir is required for SystemTAP tapset generator"
+    if [ -z "$targettype" ]; then
+       echo "--target-type is required for SystemTAP tapset generator"
+       exit 1
+    fi
+    if [ -z "$targetarch" ]; then
+       echo "--target-arch is required for SystemTAP tapset generator"
        exit 1
     fi
     echo "/* This file is autogenerated by tracetool, do not edit. */"
-    convert s
-}
-
-# Choose backend
-case "$1" in
-"--nop" | "--simple" | "--ust" | "--dtrace") backend="${1#--}" ;;
-*) usage ;;
-esac
-shift
-
-bindir=
-case "$1" in
-  "--bindir")
-    bindir=$2
-    shift
-    shift
-    ;;
-esac
-
-target=
-case "$1" in
-  "--target")
-    target=$2
-    shift
-    shift
-    ;;
-esac
-
-
-case "$1" in
-"-h") tracetoh ;;
-"-c") tracetoc ;;
-"-d") tracetod ;;
-"-s") tracetos ;;
-"--check-backend") exit 0 ;; # used by ./configure to test for backend
-*) usage ;;
-esac
+    convert stap
+}
+
+
+backend=
+output=
+binary=
+targettype=
+targetarch=
+
+
+until [ -z "$1" ]
+do
+  case "$1" in
+    "--nop" | "--simple" | "--ust" | "--dtrace") backend="${1#--}" ;;
+
+    "--binary") shift ; binary="$1" ;;
+    "--target-arch") shift ; targetarch="$1" ;;
+    "--target-type") shift ; targettype="$1" ;;
+
+    "-h" | "-c" | "-d") output="${1#-}" ;;
+    "--stap") output="${1#--}" ;;
+
+    "--check-backend") exit 0 ;; # used by ./configure to test for backend
+
+    *)
+      usage;;
+  esac
+  shift
+done
+
+if [ "$backend" = "" -o "$output" = "" ]; then
+  usage
+fi
+
+gen="traceto$output"
+"$gen"
 
 exit 0
diff --git a/vl.c b/vl.c
index 9ee6479b7c..805e11f5c5 100644
--- a/vl.c
+++ b/vl.c
@@ -158,6 +158,7 @@ int main(int argc, char **argv)
 
 #include "slirp/libslirp.h"
 
+#include "trace.h"
 #include "qemu-queue.h"
 #include "cpus.h"
 #include "arch_init.h"
@@ -1074,6 +1075,8 @@ void vm_state_notify(int running, int reason)
 {
     VMChangeStateEntry *e;
 
+    trace_vm_state_notify(running, reason);
+
     for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
         e->cb(e->opaque, running, reason);
     }