diff options
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); } |