diff options
83 files changed, 1943 insertions, 1338 deletions
@@ -33,7 +33,7 @@ configure: ; .PHONY: all clean cscope distclean dvi html info install install-doc \ pdf recurse-all speed tar tarbin test build-all -$(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw) +$(call set-vpath, $(SRC_PATH)) LIBS+=-lz $(LIBS_TOOLS) @@ -91,19 +91,18 @@ qemu-options.def: $(SRC_PATH)/qemu-options.hx SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS)) -subdir-%: $(GENERATED_HEADERS) +subdir-%: $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)" TARGET_DIR="$*/" all,) ifneq ($(wildcard config-host.mak),) include $(SRC_PATH)/Makefile.objs endif -$(universal-obj-y) $(common-obj-y): $(GENERATED_HEADERS) subdir-libcacard: $(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o -$(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(common-obj-y) subdir-libdis +$(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(common-obj-y) $(extra-obj-y) subdir-libdis -$(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) $(universal-obj-y) $(trace-obj-y) subdir-libdis-user subdir-libuser +$(filter %-user,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) subdir-libdis-user subdir-libuser ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS)) romsubdir-%: @@ -121,7 +120,7 @@ QEMU_CFLAGS += -I$(SRC_PATH)/include ui/cocoa.o: ui/cocoa.m -ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS) +ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o hw/baum.o: QEMU_CFLAGS += $(SDL_CFLAGS) ui/vnc.o: QEMU_CFLAGS += $(VNC_TLS_CFLAGS) @@ -142,16 +141,19 @@ libcacard.la: install-libcacard: @echo "libtool is missing, please install and rerun configure"; exit 1 else -libcacard.la: $(GENERATED_HEADERS) $(oslib-obj-y) qemu-timer-common.o $(addsuffix .lo, $(basename $(trace-obj-y))) +libcacard.la: $(oslib-obj-y) qemu-timer-common.o $(addsuffix .lo, $(basename $(trace-obj-y))) $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" libcacard.la,) install-libcacard: libcacard.la $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" install-libcacard,) endif + +vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) qemu-timer-common.o libcacard/vscclient.o + $(call quiet-command,$(CC) -o $@ $^ $(libcacard_libs) $(LIBS)," LINK $@") + ###################################################################### qemu-img.o: qemu-img-cmds.h -qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o qemu-ga.o: $(GENERATED_HEADERS) tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \ qemu-timer-common.o main-loop.o notify.o iohandler.o cutils.o async.o @@ -162,7 +164,6 @@ qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) $(block-obj-y) qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y) qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o -qemu-bridge-helper.o: $(GENERATED_HEADERS) fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o oslib-posix.o $(trace-obj-y) fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap @@ -170,7 +171,6 @@ fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $@") -$(qapi-obj-y): $(GENERATED_HEADERS) qapi-dir := $(BUILD_DIR)/qapi-generated qemu-ga$(EXESUF): LIBS = $(LIBS_QGA) qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir) @@ -203,8 +203,8 @@ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py QGALIB_OBJ=$(addprefix $(qapi-dir)/, qga-qapi-types.o qga-qapi-visit.o qga-qmp-marshal.o) QGALIB_GEN=$(addprefix $(qapi-dir)/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h) -$(QGALIB_OBJ): $(QGALIB_GEN) $(GENERATED_HEADERS) -$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN) $(GENERATED_HEADERS) +$(QGALIB_OBJ): $(QGALIB_GEN) +$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN) qemu-ga$(EXESUF): qemu-ga.o $(qga-obj-y) $(tools-obj-y) $(qapi-obj-y) $(qobject-obj-y) $(version-obj-y) $(QGALIB_OBJ) @@ -218,6 +218,7 @@ clean: rm -Rf .libs rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o qga/*.d rm -f qom/*.o qom/*.d + rm -f usb/*.o usb/*.d hw/*.o hw/*.d rm -f qemu-img-cmds.h rm -f trace/*.o trace/*.d rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp @@ -399,5 +400,10 @@ tar: cd /tmp && tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS --exclude .git --exclude .svn rm -rf /tmp/$(FILE) +# Add a dependency on the generated files, so that they are always +# rebuilt before other object files +Makefile: $(GENERATED_HEADERS) + # Include automatically generated dependency files --include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d qga/*.d) +-include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d) +-include $(wildcard qga/*.d hw/*.d hw/usb/*.d) diff --git a/Makefile.hw b/Makefile.hw index 33f1ab0183..2bcbaffb4f 100644 --- a/Makefile.hw +++ b/Makefile.hw @@ -7,7 +7,7 @@ include $(SRC_PATH)/rules.mak .PHONY: all -$(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw) +$(call set-vpath, $(SRC_PATH)) QEMU_CFLAGS+=-I.. QEMU_CFLAGS += -I$(SRC_PATH)/include @@ -19,7 +19,8 @@ all: $(hw-obj-y) @true clean: - rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~ + rm -f $(addsuffix /*.o, $(dir $(sort $(hw-obj-y)))) + rm -f $(addsuffix /*.d, $(dir $(sort $(hw-obj-y)))) # Include automatically generated dependency files --include $(wildcard *.d */*.d) +-include $(patsubst %.o, %.d, $(hw-obj-y)) diff --git a/Makefile.objs b/Makefile.objs index 70c5c79a6e..74110dda7e 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -12,9 +12,7 @@ universal-obj-y += $(qobject-obj-y) ####################################################################### # QOM -include $(SRC_PATH)/qom/Makefile -qom-obj-y = $(addprefix qom/, $(qom-y)) -qom-obj-twice-y = $(addprefix qom/, $(qom-twice-y)) +qom-obj-y = qom/ universal-obj-y += $(qom-obj-y) @@ -47,45 +45,13 @@ block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-progress.o qemu-sock block-obj-y += $(coroutine-obj-y) $(qobject-obj-y) $(version-obj-y) block-obj-$(CONFIG_POSIX) += posix-aio-compat.o block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o - -block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o -block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o -block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o -block-nested-y += qed-check.o -block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o -block-nested-y += stream.o -block-nested-$(CONFIG_WIN32) += raw-win32.o -block-nested-$(CONFIG_POSIX) += raw-posix.o -block-nested-$(CONFIG_LIBISCSI) += iscsi.o -block-nested-$(CONFIG_CURL) += curl.o -block-nested-$(CONFIG_RBD) += rbd.o - -block-obj-y += $(addprefix block/, $(block-nested-y)) - -net-obj-y = net.o -net-nested-y = queue.o checksum.o util.o -net-nested-y += socket.o -net-nested-y += dump.o -net-nested-$(CONFIG_POSIX) += tap.o -net-nested-$(CONFIG_LINUX) += tap-linux.o -net-nested-$(CONFIG_WIN32) += tap-win32.o -net-nested-$(CONFIG_BSD) += tap-bsd.o -net-nested-$(CONFIG_SOLARIS) += tap-solaris.o -net-nested-$(CONFIG_AIX) += tap-aix.o -net-nested-$(CONFIG_HAIKU) += tap-haiku.o -net-nested-$(CONFIG_SLIRP) += slirp.o -net-nested-$(CONFIG_VDE) += vde.o -net-obj-y += $(addprefix net/, $(net-nested-y)) +block-obj-y += block/ ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy) # 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 -fsdev-nested-y = qemu-fsdev.o virtio-9p-marshal.o -else -fsdev-nested-y = qemu-fsdev-dummy.o endif -fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y)) ###################################################################### # Target independent part of system emulation. The long term path is to @@ -93,104 +59,40 @@ fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y)) # single QEMU executable should support all CPUs and machines. common-obj-y = $(block-obj-y) blockdev.o -common-obj-y += $(net-obj-y) -common-obj-y += $(qom-obj-twice-y) -common-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX)) +common-obj-y += net.o net/ +common-obj-y += qom/ common-obj-y += readline.o console.o cursor.o common-obj-y += $(oslib-obj-y) common-obj-$(CONFIG_WIN32) += os-win32.o common-obj-$(CONFIG_POSIX) += os-posix.o +common-obj-$(CONFIG_LINUX) += fsdev/ +extra-obj-$(CONFIG_LINUX) += fsdev/ + common-obj-y += tcg-runtime.o host-utils.o main-loop.o -common-obj-y += irq.o input.o -common-obj-$(CONFIG_PTIMER) += ptimer.o -common-obj-$(CONFIG_MAX7310) += max7310.o -common-obj-$(CONFIG_WM8750) += wm8750.o -common-obj-$(CONFIG_TWL92230) += twl92230.o -common-obj-$(CONFIG_TSC2005) += tsc2005.o -common-obj-$(CONFIG_LM832X) += lm832x.o -common-obj-$(CONFIG_TMP105) += tmp105.o -common-obj-$(CONFIG_STELLARIS_INPUT) += stellaris_input.o -common-obj-$(CONFIG_SSD0303) += ssd0303.o -common-obj-$(CONFIG_SSD0323) += ssd0323.o -common-obj-$(CONFIG_ADS7846) += ads7846.o -common-obj-$(CONFIG_MAX111X) += max111x.o -common-obj-$(CONFIG_DS1338) += ds1338.o -common-obj-y += i2c.o smbus.o smbus_eeprom.o -common-obj-y += eeprom93xx.o -common-obj-y += scsi-disk.o cdrom.o -common-obj-y += scsi-generic.o scsi-bus.o -common-obj-y += hid.o -common-obj-y += usb/core.o usb/bus.o usb/desc.o usb/dev-hub.o -common-obj-y += usb/host-$(HOST_USB).o -common-obj-y += usb/dev-hid.o usb/dev-storage.o usb/dev-wacom.o -common-obj-y += usb/dev-serial.o usb/dev-network.o usb/dev-audio.o -common-obj-$(CONFIG_SSI) += ssi.o -common-obj-$(CONFIG_SSI_SD) += ssi-sd.o -common-obj-$(CONFIG_SD) += sd.o -common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o -common-obj-y += bt-hci-csr.o usb/dev-bluetooth.o +common-obj-y += input.o common-obj-y += buffered_file.o migration.o migration-tcp.o common-obj-y += qemu-char.o #aio.o -common-obj-y += msmouse.o ps2.o -common-obj-y += qdev.o qdev-properties.o qdev-monitor.o common-obj-y += block-migration.o iohandler.o common-obj-y += pflib.o common-obj-y += bitmap.o bitops.o -common-obj-$(CONFIG_BRLAPI) += baum.o common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o common-obj-$(CONFIG_WIN32) += version.o -common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o spice-qemu-char.o - -audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o -audio-obj-$(CONFIG_SDL) += sdlaudio.o -audio-obj-$(CONFIG_OSS) += ossaudio.o -audio-obj-$(CONFIG_SPICE) += spiceaudio.o -audio-obj-$(CONFIG_COREAUDIO) += coreaudio.o -audio-obj-$(CONFIG_ALSA) += alsaaudio.o -audio-obj-$(CONFIG_DSOUND) += dsoundaudio.o -audio-obj-$(CONFIG_FMOD) += fmodaudio.o -audio-obj-$(CONFIG_ESD) += esdaudio.o -audio-obj-$(CONFIG_PA) += paaudio.o -audio-obj-$(CONFIG_WINWAVE) += winwaveaudio.o -audio-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o -audio-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o -audio-obj-y += wavcapture.o -common-obj-y += $(addprefix audio/, $(audio-obj-y)) - -ui-obj-y += keymaps.o -ui-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o -ui-obj-$(CONFIG_COCOA) += cocoa.o -ui-obj-$(CONFIG_CURSES) += curses.o -vnc-obj-y += vnc.o d3des.o -vnc-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o -vnc-obj-y += vnc-enc-tight.o vnc-palette.o -vnc-obj-y += vnc-enc-zrle.o -vnc-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o -vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o -ifdef CONFIG_VNC_THREAD -vnc-obj-y += vnc-jobs-async.o -else -vnc-obj-y += vnc-jobs-sync.o -endif -common-obj-y += $(addprefix ui/, $(ui-obj-y)) -common-obj-$(CONFIG_VNC) += $(addprefix ui/, $(vnc-obj-y)) +common-obj-$(CONFIG_SPICE) += spice-qemu-char.o + +common-obj-y += audio/ +common-obj-y += hw/ +common-obj-y += ui/ +common-obj-y += bt-host.o bt-vhci.o common-obj-y += iov.o acl.o common-obj-$(CONFIG_POSIX) += compatfd.o common-obj-y += notify.o event_notifier.o common-obj-y += qemu-timer.o qemu-timer-common.o -slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o -slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o -slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o arp_table.o -common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y)) - -# xen backend driver support -common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o -common-obj-$(CONFIG_XEN_BACKEND) += xen_console.o xenfb.o xen_disk.o xen_nic.o +common-obj-$(CONFIG_SLIRP) += slirp/ ###################################################################### # libuser @@ -202,152 +104,12 @@ user-obj-y += cutils.o cache-utils.o user-obj-y += module.o user-obj-y += qemu-user.o user-obj-y += $(trace-obj-y) -user-obj-y += $(qom-obj-twice-y) +user-obj-y += qom/ ###################################################################### # libhw -hw-obj-y = -hw-obj-y += vl.o loader.o -hw-obj-$(CONFIG_VIRTIO) += virtio-console.o -hw-obj-y += usb/libhw.o -hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o -hw-obj-y += fw_cfg.o -hw-obj-$(CONFIG_PCI) += pci.o pci_bridge.o pci_bridge_dev.o -hw-obj-$(CONFIG_PCI) += msix.o msi.o -hw-obj-$(CONFIG_PCI) += shpc.o -hw-obj-$(CONFIG_PCI) += slotid_cap.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 -hw-obj-$(CONFIG_NAND) += nand.o -hw-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o -hw-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o - -hw-obj-$(CONFIG_M48T59) += m48t59.o -hw-obj-$(CONFIG_ESCC) += escc.o -hw-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o - -hw-obj-$(CONFIG_SERIAL) += serial.o -hw-obj-$(CONFIG_PARALLEL) += parallel.o -hw-obj-$(CONFIG_I8254) += i8254_common.o i8254.o -hw-obj-$(CONFIG_PCSPK) += pcspk.o -hw-obj-$(CONFIG_PCKBD) += pckbd.o -hw-obj-$(CONFIG_USB_UHCI) += usb/hcd-uhci.o -hw-obj-$(CONFIG_USB_OHCI) += usb/hcd-ohci.o -hw-obj-$(CONFIG_USB_EHCI) += usb/hcd-ehci.o -hw-obj-$(CONFIG_USB_XHCI) += usb/hcd-xhci.o -hw-obj-$(CONFIG_FDC) += fdc.o -hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o -hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o -hw-obj-$(CONFIG_DMA) += dma.o -hw-obj-$(CONFIG_I82374) += i82374.o -hw-obj-$(CONFIG_HPET) += hpet.o -hw-obj-$(CONFIG_APPLESMC) += applesmc.o -hw-obj-$(CONFIG_SMARTCARD) += usb/dev-smartcard-reader.o ccid-card-passthru.o -hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o -hw-obj-$(CONFIG_USB_REDIR) += usb/redirect.o -hw-obj-$(CONFIG_I8259) += i8259_common.o i8259.o - -# PPC devices -hw-obj-$(CONFIG_PREP_PCI) += prep_pci.o -hw-obj-$(CONFIG_I82378) += i82378.o -# Mac shared devices -hw-obj-$(CONFIG_MACIO) += macio.o -hw-obj-$(CONFIG_CUDA) += cuda.o -hw-obj-$(CONFIG_ADB) += adb.o -hw-obj-$(CONFIG_MAC_NVRAM) += mac_nvram.o -hw-obj-$(CONFIG_MAC_DBDMA) += mac_dbdma.o -# OldWorld PowerMac -hw-obj-$(CONFIG_HEATHROW_PIC) += heathrow_pic.o -hw-obj-$(CONFIG_GRACKLE_PCI) += grackle_pci.o -# NewWorld PowerMac -hw-obj-$(CONFIG_UNIN_PCI) += unin_pci.o -hw-obj-$(CONFIG_DEC_PCI) += dec_pci.o -# PowerPC E500 boards -hw-obj-$(CONFIG_PPCE500_PCI) += ppce500_pci.o - -# MIPS devices -hw-obj-$(CONFIG_PIIX4) += piix4.o -hw-obj-$(CONFIG_G364FB) += g364fb.o -hw-obj-$(CONFIG_JAZZ_LED) += jazz_led.o - -# PCI watchdog devices -hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o - -hw-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o - -# PCI network cards -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_E1000_PCI) += e1000.o -hw-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o - -hw-obj-$(CONFIG_SMC91C111) += smc91c111.o -hw-obj-$(CONFIG_LAN9118) += lan9118.o -hw-obj-$(CONFIG_NE2000_ISA) += ne2000-isa.o -hw-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o - -# IDE -hw-obj-$(CONFIG_IDE_CORE) += ide/core.o ide/atapi.o -hw-obj-$(CONFIG_IDE_QDEV) += ide/qdev.o -hw-obj-$(CONFIG_IDE_PCI) += ide/pci.o -hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o -hw-obj-$(CONFIG_IDE_PIIX) += ide/piix.o -hw-obj-$(CONFIG_IDE_CMD646) += ide/cmd646.o -hw-obj-$(CONFIG_IDE_MACIO) += ide/macio.o -hw-obj-$(CONFIG_IDE_VIA) += ide/via.o -hw-obj-$(CONFIG_AHCI) += ide/ahci.o -hw-obj-$(CONFIG_AHCI) += ide/ich.o - -# SCSI layer -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 -hw-obj-y += qdev-addr.o - -# VGA -hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o -hw-obj-$(CONFIG_VGA_ISA) += vga-isa.o -hw-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o -hw-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o -hw-obj-$(CONFIG_VMMOUSE) += vmmouse.o -hw-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o - -hw-obj-$(CONFIG_RC4030) += rc4030.o -hw-obj-$(CONFIG_DP8393X) += dp8393x.o -hw-obj-$(CONFIG_DS1225Y) += ds1225y.o -hw-obj-$(CONFIG_MIPSNET) += mipsnet.o - -hw-obj-y += qtest.o - -# Sound -sound-obj-y = -sound-obj-$(CONFIG_SB16) += sb16.o -sound-obj-$(CONFIG_ES1370) += es1370.o -sound-obj-$(CONFIG_AC97) += ac97.o -sound-obj-$(CONFIG_ADLIB) += fmopl.o adlib.o -sound-obj-$(CONFIG_GUS) += gus.o gusemu_hal.o gusemu_mixer.o -sound-obj-$(CONFIG_CS4231A) += cs4231a.o -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) - -9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p.o -9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o -9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o -9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o cofile.o -9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-synth.o -9pfs-nested-$(CONFIG_OPEN_BY_HANDLE) += virtio-9p-handle.o -9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-proxy.o - -hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y)) +hw-obj-y = vl.o dma-helpers.o qtest.o hw/ ###################################################################### # libdis @@ -425,31 +187,29 @@ ifneq ($(TRACE_BACKEND),dtrace) trace-obj-y = trace.o endif -trace-nested-$(CONFIG_TRACE_DEFAULT) += default.o - -trace-nested-$(CONFIG_TRACE_SIMPLE) += simple.o +trace-obj-$(CONFIG_TRACE_DEFAULT) += trace/default.o +trace-obj-$(CONFIG_TRACE_SIMPLE) += trace/simple.o trace-obj-$(CONFIG_TRACE_SIMPLE) += qemu-timer-common.o - -trace-nested-$(CONFIG_TRACE_STDERR) += stderr.o - -trace-nested-y += control.o - -trace-obj-y += $(addprefix trace/, $(trace-nested-y)) +trace-obj-$(CONFIG_TRACE_STDERR) += trace/stderr.o +trace-obj-y += trace/control.o $(trace-obj-y): $(GENERATED_HEADERS) ###################################################################### # smartcard -libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o card_7816.o +libcacard-y += libcacard/cac.o libcacard/event.o +libcacard-y += libcacard/vcard.o libcacard/vreader.o +libcacard-y += libcacard/vcard_emul_nss.o +libcacard-y += libcacard/vcard_emul_type.o +libcacard-y += libcacard/card_7816.o + +common-obj-$(CONFIG_SMARTCARD_NSS) += $(libcacard-y) ###################################################################### # qapi -qapi-nested-y = qapi-visit-core.o qapi-dealloc-visitor.o qmp-input-visitor.o -qapi-nested-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o -qapi-nested-y += string-input-visitor.o string-output-visitor.o -qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) +qapi-obj-y = qapi/ common-obj-y += qmp-marshal.o qapi-visit.o qapi-types.o common-obj-y += qmp.o hmp.o @@ -459,11 +219,7 @@ universal-obj-y += $(qapi-obj-y) ###################################################################### # guest agent -qga-nested-y = commands.o guest-agent-command-state.o -qga-nested-$(CONFIG_POSIX) += commands-posix.o channel-posix.o -qga-nested-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o -qga-obj-y = $(addprefix qga/, $(qga-nested-y)) -qga-obj-y += qemu-ga.o module.o +qga-obj-y = qga/ qemu-ga.o module.o qga-obj-$(CONFIG_WIN32) += oslib-win32.o qga-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-sockets.o qemu-option.o @@ -473,3 +229,13 @@ vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS) QEMU_CFLAGS+=$(GLIB_CFLAGS) +nested-vars += \ + hw-obj-y \ + qga-obj-y \ + block-obj-y \ + qom-obj-y \ + qapi-obj-y \ + user-obj-y \ + common-obj-y \ + extra-obj-y +dummy := $(call unnest-vars) diff --git a/Makefile.target b/Makefile.target index c94abfd3a4..2907aad0c4 100644 --- a/Makefile.target +++ b/Makefile.target @@ -1,10 +1,5 @@ # -*- Mode: makefile -*- -GENERATED_HEADERS = config-target.h -CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y) -CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y) -CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y) - include ../config-host.mak include config-devices.mak include config-target.mak @@ -13,14 +8,11 @@ ifneq ($(HWDIR),) include $(HWDIR)/config.mak endif -TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH) -$(call set-vpath, $(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw) +$(call set-vpath, $(SRC_PATH)) ifdef CONFIG_LINUX QEMU_CFLAGS += -I../linux-headers endif -QEMU_CFLAGS += -I.. -I$(TARGET_PATH) -DNEED_CPU_H - -include $(SRC_PATH)/Makefile.objs +QEMU_CFLAGS += -I.. -I$(SRC_PATH)/target-$(TARGET_BASE_ARCH) -DNEED_CPU_H QEMU_CFLAGS+=-I$(SRC_PATH)/include @@ -77,78 +69,34 @@ all: $(PROGS) stap ######################################################### # cpu emulator library -libobj-y = exec.o translate-all.o cpu-exec.o translate.o -libobj-y += tcg/tcg.o tcg/optimize.o -libobj-$(CONFIG_TCG_INTERPRETER) += tci.o -libobj-y += fpu/softfloat.o -ifneq ($(TARGET_BASE_ARCH), sparc) -ifneq ($(TARGET_BASE_ARCH), alpha) -libobj-y += op_helper.o -endif -endif -libobj-y += helper.o -ifneq ($(TARGET_BASE_ARCH), ppc) -libobj-y += cpu.o -endif -libobj-$(TARGET_SPARC64) += vis_helper.o -libobj-$(CONFIG_NEED_MMU) += mmu.o -libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o -ifeq ($(TARGET_BASE_ARCH), sparc) -libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o -endif -libobj-$(TARGET_SPARC) += int32_helper.o -libobj-$(TARGET_SPARC64) += int64_helper.o -libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o - -libobj-y += disas.o -libobj-$(CONFIG_TCI_DIS) += tci-dis.o +obj-y = exec.o translate-all.o cpu-exec.o +obj-y += tcg/tcg.o tcg/optimize.o +obj-$(CONFIG_TCG_INTERPRETER) += tci.o +obj-y += fpu/softfloat.o +obj-y += disas.o +obj-$(CONFIG_TCI_DIS) += tci-dis.o +obj-y += target-$(TARGET_BASE_ARCH)/ +obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o tci-dis.o: QEMU_CFLAGS += -I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/tci -$(libobj-y): $(GENERATED_HEADERS) - # HELPER_CFLAGS is used for all the legacy code compiled with static register # variables -ifneq ($(TARGET_BASE_ARCH), sparc) -op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) -endif user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS) # Note: this is a workaround. The real fix is to avoid compiling # cpu_signal_handler() in user-exec.c. -signal.o: QEMU_CFLAGS += $(HELPER_CFLAGS) +%/signal.o: QEMU_CFLAGS += $(HELPER_CFLAGS) ######################################################### # Linux user emulator target ifdef CONFIG_LINUX_USER -$(call set-vpath, $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR)) - QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user -obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \ - elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \ - user-exec.o $(oslib-obj-y) - -obj-$(TARGET_HAS_BFLT) += flatload.o - -obj-$(TARGET_I386) += vm86.o - -obj-i386-y += ioport-user.o -nwfpe-obj-y = fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o fpopcode.o -nwfpe-obj-y += single_cpdo.o double_cpdo.o extended_cpdo.o -obj-arm-y += $(addprefix nwfpe/, $(nwfpe-obj-y)) -obj-arm-y += arm-semi.o - -obj-m68k-y += m68k-sim.o m68k-semi.o - -$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS) - -obj-y += $(addprefix ../, $(universal-obj-y)) -obj-y += $(addprefix ../libuser/, $(user-obj-y)) -obj-y += $(addprefix ../libdis-user/, $(libdis-y)) -obj-y += $(libobj-y) +obj-y += linux-user/ +obj-y += gdbstub.o thunk.o user-exec.o $(oslib-obj-y) endif #CONFIG_LINUX_USER @@ -157,274 +105,81 @@ endif #CONFIG_LINUX_USER ifdef CONFIG_BSD_USER -$(call set-vpath, $(SRC_PATH)/bsd-user) - QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ARCH) -obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \ - gdbstub.o uaccess.o user-exec.o - -obj-i386-y += ioport-user.o - -$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS) - -obj-y += $(addprefix ../, $(universal-obj-y)) -obj-y += $(addprefix ../libuser/, $(user-obj-y)) -obj-y += $(addprefix ../libdis-user/, $(libdis-y)) -obj-y += $(libobj-y) +obj-y += bsd-user/ +obj-y += gdbstub.o user-exec.o endif #CONFIG_BSD_USER ######################################################### # System emulator target ifdef CONFIG_SOFTMMU +CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y) +CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y) +CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y) +CONFIG_NO_GET_MEMORY_MAPPING = $(if $(subst n,,$(CONFIG_HAVE_GET_MEMORY_MAPPING)),n,y) +CONFIG_NO_CORE_DUMP = $(if $(subst n,,$(CONFIG_HAVE_CORE_DUMP)),n,y) -obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o ioport.o -# virtio has to be here due to weird dependency between PCI and virtio-net. -# need to fix this properly -obj-$(CONFIG_NO_PCI) += pci-stub.o -obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o -obj-$(CONFIG_VIRTIO) += virtio-scsi.o -obj-y += vhost_net.o -obj-$(CONFIG_VHOST_NET) += vhost.o -obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o -obj-$(CONFIG_KVM) += kvm.o kvm-all.o +obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o +obj-y += hw/ +obj-$(CONFIG_KVM) += kvm-all.o obj-$(CONFIG_NO_KVM) += kvm-stub.o -obj-$(CONFIG_VGA) += vga.o obj-y += memory.o savevm.o cputlb.o -obj-y += memory_mapping.o -obj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += arch_memory_mapping.o -obj-$(CONFIG_HAVE_CORE_DUMP) += arch_dump.o +obj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += memory_mapping.o +obj-$(CONFIG_HAVE_CORE_DUMP) += dump.o +obj-$(CONFIG_NO_GET_MEMORY_MAPPING) += memory_mapping-stub.o +obj-$(CONFIG_NO_CORE_DUMP) += dump-stub.o LIBS+=-lz -obj-i386-$(CONFIG_KVM) += hyperv.o - QEMU_CFLAGS += $(VNC_TLS_CFLAGS) QEMU_CFLAGS += $(VNC_SASL_CFLAGS) QEMU_CFLAGS += $(VNC_JPEG_CFLAGS) QEMU_CFLAGS += $(VNC_PNG_CFLAGS) # xen support -obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o xen-mapcache.o +obj-$(CONFIG_XEN) += xen-all.o xen-mapcache.o obj-$(CONFIG_NO_XEN) += xen-stub.o -obj-i386-$(CONFIG_XEN) += xen_platform.o xen_apic.o - -# Inter-VM PCI shared memory -CONFIG_IVSHMEM = -ifeq ($(CONFIG_KVM), y) - ifeq ($(CONFIG_PCI), y) - CONFIG_IVSHMEM = y - endif -endif -obj-$(CONFIG_IVSHMEM) += ivshmem.o - -# Generic hotplugging -obj-y += device-hotplug.o - # Hardware support -obj-i386-y += mc146818rtc.o pc.o -obj-i386-y += apic_common.o apic.o kvmvapic.o -obj-i386-y += sga.o ioapic_common.o ioapic.o piix_pci.o -obj-i386-y += vmport.o -obj-i386-y += pci-hotplug.o smbios.o wdt_ib700.o -obj-i386-y += debugcon.o multiboot.o -obj-i386-y += pc_piix.o -obj-i386-y += pc_sysfw.o -obj-i386-$(CONFIG_KVM) += kvm/clock.o kvm/apic.o kvm/i8259.o kvm/ioapic.o kvm/i8254.o -obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o - -# shared objects -obj-ppc-y = ppc.o ppc_booke.o -# PREP target -obj-ppc-y += mc146818rtc.o -obj-ppc-y += ppc_prep.o -# OldWorld PowerMac -obj-ppc-y += ppc_oldworld.o -# NewWorld PowerMac -obj-ppc-y += ppc_newworld.o -# IBM pSeries (sPAPR) -obj-ppc-$(CONFIG_PSERIES) += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o -obj-ppc-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o -obj-ppc-$(CONFIG_PSERIES) += spapr_pci.o device-hotplug.o pci-hotplug.o -# PowerPC 4xx boards -obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o -obj-ppc-y += ppc440_bamboo.o -# PowerPC E500 boards -obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o -# PowerPC 440 Xilinx ML507 reference board. -obj-ppc-y += virtex_ml507.o -obj-ppc-$(CONFIG_KVM) += kvm_ppc.o -obj-ppc-$(CONFIG_FDT) += device_tree.o -# PowerPC OpenPIC -obj-ppc-y += openpic.o - -# Xilinx PPC peripherals -obj-ppc-y += xilinx_intc.o -obj-ppc-y += xilinx_timer.o -obj-ppc-y += xilinx_uartlite.o -obj-ppc-y += xilinx_ethlite.o - -# LM32 boards -obj-lm32-y += lm32_boards.o -obj-lm32-y += milkymist.o - -# LM32 peripherals -obj-lm32-y += lm32_pic.o -obj-lm32-y += lm32_juart.o -obj-lm32-y += lm32_timer.o -obj-lm32-y += lm32_uart.o -obj-lm32-y += lm32_sys.o -obj-lm32-y += milkymist-ac97.o -obj-lm32-y += milkymist-hpdmc.o -obj-lm32-y += milkymist-memcard.o -obj-lm32-y += milkymist-minimac2.o -obj-lm32-y += milkymist-pfpu.o -obj-lm32-y += milkymist-softusb.o -obj-lm32-y += milkymist-sysctl.o -obj-lm32-$(CONFIG_OPENGL) += milkymist-tmu2.o -obj-lm32-y += milkymist-uart.o -obj-lm32-y += milkymist-vgafb.o -obj-lm32-y += framebuffer.o - -obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o -obj-mips-y += mips_addr.o mips_timer.o mips_int.o -obj-mips-y += gt64xxx.o mc146818rtc.o -obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o - -obj-microblaze-y = petalogix_s3adsp1800_mmu.o -obj-microblaze-y += petalogix_ml605_mmu.o -obj-microblaze-y += microblaze_boot.o - -obj-microblaze-y += microblaze_pic_cpu.o -obj-microblaze-y += xilinx_intc.o -obj-microblaze-y += xilinx_timer.o -obj-microblaze-y += xilinx_uartlite.o -obj-microblaze-y += xilinx_ethlite.o -obj-microblaze-y += xilinx_axidma.o -obj-microblaze-y += xilinx_axienet.o - -obj-microblaze-$(CONFIG_FDT) += device_tree.o - -# Boards -obj-cris-y = cris_pic_cpu.o -obj-cris-y += cris-boot.o -obj-cris-y += axis_dev88.o - -# IO blocks -obj-cris-y += etraxfs_dma.o -obj-cris-y += etraxfs_pic.o -obj-cris-y += etraxfs_eth.o -obj-cris-y += etraxfs_timer.o -obj-cris-y += etraxfs_ser.o - ifeq ($(TARGET_ARCH), sparc64) -obj-sparc-y = sun4u.o apb_pci.o -obj-sparc-y += mc146818rtc.o +obj-y += hw/sparc64/ else -obj-sparc-y = sun4m.o lance.o tcx.o sun4m_iommu.o slavio_intctl.o -obj-sparc-y += slavio_timer.o slavio_misc.o sparc32_dma.o -obj-sparc-y += cs4231.o eccmemctl.o sbi.o sun4c_intctl.o leon3.o - -# GRLIB -obj-sparc-y += grlib_gptimer.o grlib_irqmp.o grlib_apbuart.o +obj-y += hw/$(TARGET_BASE_ARCH)/ endif -obj-arm-y = integratorcp.o versatilepb.o arm_pic.o arm_timer.o -obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o -obj-arm-y += versatile_pci.o -obj-arm-y += versatile_i2c.o -obj-arm-y += cadence_uart.o -obj-arm-y += cadence_ttc.o -obj-arm-y += cadence_gem.o -obj-arm-y += xilinx_zynq.o zynq_slcr.o -obj-arm-y += arm_gic.o -obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o -obj-arm-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o -obj-arm-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o -obj-arm-y += exynos4210_pmu.o exynos4210_mct.o exynos4210_fimd.o -obj-arm-y += arm_l2x0.o -obj-arm-y += arm_mptimer.o a15mpcore.o -obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o -obj-arm-y += highbank.o -obj-arm-y += pl061.o -obj-arm-y += xgmac.o -obj-arm-y += arm-semi.o -obj-arm-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o -obj-arm-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o -obj-arm-y += gumstix.o -obj-arm-y += zaurus.o ide/microdrive.o spitz.o tosa.o tc6393xb.o -obj-arm-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o \ - omap_gpio.o omap_intc.o omap_uart.o -obj-arm-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o \ - omap_gpmc.o omap_sdrc.o omap_spi.o omap_tap.o omap_l4.o -obj-arm-y += omap_sx1.o palm.o tsc210x.o -obj-arm-y += nseries.o blizzard.o onenand.o cbus.o tusb6010.o usb/hcd-musb.o -obj-arm-y += mst_fpga.o mainstone.o -obj-arm-y += z2.o -obj-arm-y += musicpal.o bitbang_i2c.o marvell_88w8618_audio.o -obj-arm-y += framebuffer.o -obj-arm-y += vexpress.o -obj-arm-y += strongarm.o -obj-arm-y += collie.o -obj-arm-y += pl041.o lm4549.o -obj-arm-$(CONFIG_FDT) += device_tree.o - -obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o -obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o -obj-sh4-y += ide/mmio.o - -obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o -obj-m68k-y += m68k-semi.o dummy_m68k.o - -obj-s390x-y = s390-virtio-bus.o s390-virtio.o - -obj-alpha-y = mc146818rtc.o -obj-alpha-y += alpha_pci.o alpha_dp264.o alpha_typhoon.o - -obj-xtensa-y += xtensa_pic.o -obj-xtensa-y += xtensa_sim.o -obj-xtensa-y += xtensa_lx60.o -obj-xtensa-y += xtensa-semi.o -obj-xtensa-y += core-dc232b.o -obj-xtensa-y += core-dc233c.o -obj-xtensa-y += core-fsf.o - main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) -monitor.o: hmp-commands.h qmp-commands-old.h - -$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS) - -obj-y += $(addprefix ../, $(universal-obj-y)) -obj-y += $(addprefix ../, $(common-obj-y)) -obj-y += $(addprefix ../libdis/, $(libdis-y)) -obj-y += $(libobj-y) -obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y)) -obj-y += $(addprefix ../, $(trace-obj-y)) +GENERATED_HEADERS += hmp-commands.h qmp-commands-old.h endif # CONFIG_SOFTMMU -obj-y += dump.o +nested-vars += obj-y -ifndef CONFIG_LINUX_USER -ifndef CONFIG_BSD_USER -# libcacard needs qemu-thread support, and besides is only needed by devices -# so not requires with linux-user / bsd-user targets -obj-$(CONFIG_SMARTCARD_NSS) += $(addprefix ../libcacard/, $(libcacard-y)) -endif # CONFIG_BSD_USER -endif # CONFIG_LINUX_USER +# This resolves all nested paths, so it must come last +include $(SRC_PATH)/Makefile.objs -obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o +all-obj-y = $(obj-y) +all-obj-y += $(addprefix ../, $(universal-obj-y)) + +ifdef CONFIG_SOFTMMU +all-obj-y += $(addprefix ../, $(common-obj-y)) +all-obj-y += $(addprefix ../libdis/, $(libdis-y)) +all-obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y)) +all-obj-y += $(addprefix ../, $(trace-obj-y)) +else +all-obj-y += $(addprefix ../libuser/, $(user-obj-y)) +all-obj-y += $(addprefix ../libdis-user/, $(libdis-y)) +endif #CONFIG_LINUX_USER ifdef QEMU_PROGW # The linker builds a windows executable. Make also a console executable. -$(QEMU_PROGW): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) +$(QEMU_PROGW): $(all-obj-y) $(call LINK,$^) $(QEMU_PROG): $(QEMU_PROGW) $(call quiet-command,$(OBJCOPY) --subsystem console $(QEMU_PROGW) $(QEMU_PROG)," GEN $(TARGET_DIR)$(QEMU_PROG)") else -$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) +$(QEMU_PROG): $(all-obj-y) $(call LINK,$^) endif @@ -457,5 +212,8 @@ ifdef CONFIG_TRACE_SYSTEMTAP $(INSTALL_DATA) $(QEMU_PROG).stp "$(DESTDIR)$(qemu_datadir)/../systemtap/tapset" endif +GENERATED_HEADERS += config-target.h +Makefile: $(GENERATED_HEADERS) + # Include automatically generated dependency files -include $(wildcard *.d */*.d) diff --git a/audio/Makefile.objs b/audio/Makefile.objs new file mode 100644 index 0000000000..0f2932d1b3 --- /dev/null +++ b/audio/Makefile.objs @@ -0,0 +1,14 @@ +common-obj-y = audio.o noaudio.o wavaudio.o mixeng.o +common-obj-$(CONFIG_SDL) += sdlaudio.o +common-obj-$(CONFIG_OSS) += ossaudio.o +common-obj-$(CONFIG_SPICE) += spiceaudio.o +common-obj-$(CONFIG_COREAUDIO) += coreaudio.o +common-obj-$(CONFIG_ALSA) += alsaaudio.o +common-obj-$(CONFIG_DSOUND) += dsoundaudio.o +common-obj-$(CONFIG_FMOD) += fmodaudio.o +common-obj-$(CONFIG_ESD) += esdaudio.o +common-obj-$(CONFIG_PA) += paaudio.o +common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o +common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o +common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o +common-obj-y += wavcapture.o diff --git a/block/Makefile.objs b/block/Makefile.objs new file mode 100644 index 0000000000..b5754d39bf --- /dev/null +++ b/block/Makefile.objs @@ -0,0 +1,11 @@ +block-obj-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o +block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o +block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o +block-obj-y += qed-check.o +block-obj-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o +block-obj-y += stream.o +block-obj-$(CONFIG_WIN32) += raw-win32.o +block-obj-$(CONFIG_POSIX) += raw-posix.o +block-obj-$(CONFIG_LIBISCSI) += iscsi.o +block-obj-$(CONFIG_CURL) += curl.o +block-obj-$(CONFIG_RBD) += rbd.o diff --git a/bsd-user/Makefile.objs b/bsd-user/Makefile.objs new file mode 100644 index 0000000000..5e77f57782 --- /dev/null +++ b/bsd-user/Makefile.objs @@ -0,0 +1,2 @@ +obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \ + uaccess.o @@ -42,6 +42,7 @@ compile_prog() { # symbolically link $1 to $2. Portable version of "ln -sf". symlink() { rm -rf "$2" + mkdir -p "$(dirname "$2")" ln -s "$1" "$2" } @@ -2928,6 +2929,9 @@ if test "$softmmu" = yes ; then fi fi fi +if test "$smartcard_nss" = "yes" ; then + tools="vscclient\$(EXESUF) $tools" +fi # Mac OS X ships with a broken assembler roms= @@ -3452,14 +3456,12 @@ if test -f ${config_host_ld}~ ; then fi for d in libdis libdis-user; do - mkdir -p $d symlink "$source_path/Makefile.dis" "$d/Makefile" echo > $d/config.mak done # use included Linux headers if test "$linux" = "yes" ; then - mkdir -p linux-headers case "$cpu" in i386|x86_64) symlink "$source_path/linux-headers/asm-x86" linux-headers/asm @@ -3515,18 +3517,6 @@ case "$target" in esac mkdir -p $target_dir -mkdir -p $target_dir/fpu -mkdir -p $target_dir/tcg -mkdir -p $target_dir/ide -mkdir -p $target_dir/usb -mkdir -p $target_dir/9pfs -mkdir -p $target_dir/kvm -if test "$target" = "arm-linux-user" -o "$target" = "armeb-linux-user" -o "$target" = "arm-bsd-user" -o "$target" = "armeb-bsd-user" ; then - mkdir -p $target_dir/nwfpe -fi -symlink "$source_path/Makefile.target" "$target_dir/Makefile" - - echo "# Automatically generated by configure - do not modify" > $config_target_mak bflt="no" @@ -3677,9 +3667,16 @@ case "$target_arch2" in exit 1 ;; esac +# TARGET_BASE_ARCH needs to be defined after TARGET_ARCH +if [ "$TARGET_BASE_ARCH" = "" ]; then + TARGET_BASE_ARCH=$TARGET_ARCH +fi + +symlink "$source_path/Makefile.target" "$target_dir/Makefile" + case "$target_arch2" in - alpha | sparc*) + alpha | sparc* | xtensa*) echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak ;; esac @@ -3692,10 +3689,6 @@ echo "TARGET_ARCH=$TARGET_ARCH" >> $config_target_mak target_arch_name="`echo $TARGET_ARCH | LC_ALL=C tr '[a-z]' '[A-Z]'`" echo "TARGET_$target_arch_name=y" >> $config_target_mak echo "TARGET_ARCH2=$target_arch2" >> $config_target_mak -# TARGET_BASE_ARCH needs to be defined after TARGET_ARCH -if [ "$TARGET_BASE_ARCH" = "" ]; then - TARGET_BASE_ARCH=$TARGET_ARCH -fi echo "TARGET_BASE_ARCH=$TARGET_BASE_ARCH" >> $config_target_mak if [ "$TARGET_ABI_DIR" = "" ]; then TARGET_ABI_DIR=$TARGET_ARCH @@ -3902,12 +3895,6 @@ if test "$target_softmmu" = "yes" ; then esac fi -if test "$target_softmmu" = "yes" -a \( \ - "$TARGET_ARCH" = "microblaze" -o \ - "$TARGET_ARCH" = "cris" \) ; then - echo "CONFIG_NEED_MMU=y" >> $config_target_mak -fi - if test "$gprof" = "yes" ; then echo "TARGET_GPROF=yes" >> $config_target_mak if test "$target_linux_user" = "yes" ; then @@ -3949,15 +3936,13 @@ done # for target in $targets # build tree in object directory in case the source is not in the current directory DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32" -DIRS="$DIRS slirp audio block net pc-bios/optionrom" -DIRS="$DIRS pc-bios/spapr-rtas" +DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas" DIRS="$DIRS roms/seabios roms/vgabios" -DIRS="$DIRS fsdev ui usb" -DIRS="$DIRS qapi qapi-generated" -DIRS="$DIRS qga trace qom" +DIRS="$DIRS qapi-generated" +DIRS="$DIRS libcacard libcacard/libcacard libcacard/trace" FILES="Makefile tests/tcg/Makefile qdict-test-data.txt" FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit" -FILES="$FILES tests/tcg/lm32/Makefile" +FILES="$FILES tests/tcg/lm32/Makefile libcacard/Makefile" FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps" FILES="$FILES pc-bios/spapr-rtas/Makefile" FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile" @@ -3992,24 +3977,11 @@ done for hwlib in 32 64; do d=libhw$hwlib - mkdir -p $d - mkdir -p $d/ide - mkdir -p $d/usb symlink "$source_path/Makefile.hw" "$d/Makefile" - mkdir -p $d/9pfs echo "QEMU_CFLAGS+=-DTARGET_PHYS_ADDR_BITS=$hwlib" > $d/config.mak done -if [ "$source_path" != `pwd` ]; then - # out of tree build - mkdir -p libcacard - symlink "$source_path/libcacard/Makefile" libcacard/Makefile -fi - d=libuser -mkdir -p $d -mkdir -p $d/trace -mkdir -p $d/qom symlink "$source_path/Makefile.user" "$d/Makefile" if test "$docs" = "yes" ; then @@ -22,8 +22,6 @@ #include "qemu-common.h" #include "qemu-tls.h" #include "cpu-common.h" -#include "memory_mapping.h" -#include "dump.h" /* some important defines: * @@ -525,72 +523,4 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf); int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr, uint8_t *buf, int len, int is_write); -#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING) -int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env); -bool cpu_paging_enabled(CPUArchState *env); -#else -static inline int cpu_get_memory_mapping(MemoryMappingList *list, - CPUArchState *env) -{ - return -1; -} - -static inline bool cpu_paging_enabled(CPUArchState *env) -{ - return true; -} -#endif - -typedef int (*write_core_dump_function)(void *buf, size_t size, void *opaque); -#if defined(CONFIG_HAVE_CORE_DUMP) -int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env, - int cpuid, void *opaque); -int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env, - int cpuid, void *opaque); -int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env, - void *opaque); -int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env, - void *opaque); -int cpu_get_dump_info(ArchDumpInfo *info); -size_t cpu_get_note_size(int class, int machine, int nr_cpus); -#else -static inline int cpu_write_elf64_note(write_core_dump_function f, - CPUArchState *env, int cpuid, - void *opaque) -{ - return -1; -} - -static inline int cpu_write_elf32_note(write_core_dump_function f, - CPUArchState *env, int cpuid, - void *opaque) -{ - return -1; -} - -static inline int cpu_write_elf64_qemunote(write_core_dump_function f, - CPUArchState *env, - void *opaque) -{ - return -1; -} - -static inline int cpu_write_elf32_qemunote(write_core_dump_function f, - CPUArchState *env, - void *opaque) -{ - return -1; -} - -static inline int cpu_get_dump_info(ArchDumpInfo *info) -{ - return -1; -} - -static inline int cpu_get_note_size(int class, int machine, int nr_cpus) -{ - return -1; -} -#endif - #endif /* CPU_ALL_H */ diff --git a/dump-stub.c b/dump-stub.c new file mode 100644 index 0000000000..165c005b42 --- /dev/null +++ b/dump-stub.c @@ -0,0 +1,64 @@ +/* + * QEMU dump + * + * Copyright Fujitsu, Corp. 2011, 2012 + * + * Authors: + * Wen Congyang <wency@cn.fujitsu.com> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "qemu-common.h" +#include "dump.h" +#include "qerror.h" +#include "qmp-commands.h" + +/* we need this function in hmp.c */ +void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin, + int64_t begin, bool has_length, int64_t length, + Error **errp) +{ + error_set(errp, QERR_UNSUPPORTED); +} + +int cpu_write_elf64_note(write_core_dump_function f, + CPUArchState *env, int cpuid, + void *opaque) +{ + return -1; +} + +int cpu_write_elf32_note(write_core_dump_function f, + CPUArchState *env, int cpuid, + void *opaque) +{ + return -1; +} + +int cpu_write_elf64_qemunote(write_core_dump_function f, + CPUArchState *env, + void *opaque) +{ + return -1; +} + +int cpu_write_elf32_qemunote(write_core_dump_function f, + CPUArchState *env, + void *opaque) +{ + return -1; +} + +int cpu_get_dump_info(ArchDumpInfo *info) +{ + return -1; +} + +ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) +{ + return -1; +} + @@ -12,10 +12,7 @@ */ #include "qemu-common.h" -#include <unistd.h> #include "elf.h" -#include <sys/procfs.h> -#include <glib.h> #include "cpu.h" #include "cpu-all.h" #include "targphys.h" @@ -23,13 +20,11 @@ #include "kvm.h" #include "dump.h" #include "sysemu.h" -#include "bswap.h" #include "memory_mapping.h" #include "error.h" #include "qmp-commands.h" #include "gdbstub.h" -#if defined(CONFIG_HAVE_CORE_DUMP) static uint16_t cpu_convert_to_target16(uint16_t val, int endian) { if (endian == ELFDATA2LSB) { @@ -750,6 +745,13 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter, goto cleanup; } + s->note_size = cpu_get_note_size(s->dump_info.d_class, + s->dump_info.d_machine, nr_cpus); + if (ret < 0) { + error_set(errp, QERR_UNSUPPORTED); + goto cleanup; + } + /* get memory mapping */ memory_mapping_list_init(&s->list); if (paging) { @@ -784,8 +786,6 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter, } } - s->note_size = cpu_get_note_size(s->dump_info.d_class, - s->dump_info.d_machine, nr_cpus); if (s->dump_info.d_class == ELFCLASS64) { if (s->have_section) { s->memory_offset = sizeof(Elf64_Ehdr) + @@ -871,13 +871,3 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin, g_free(s); } - -#else -/* we need this function in hmp.c */ -void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin, - int64_t begin, bool has_length, int64_t length, - Error **errp) -{ - error_set(errp, QERR_UNSUPPORTED); -} -#endif @@ -20,4 +20,16 @@ typedef struct ArchDumpInfo { int d_class; /* ELFCLASS32 or ELFCLASS64 */ } ArchDumpInfo; +typedef int (*write_core_dump_function)(void *buf, size_t size, void *opaque); +int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env, + int cpuid, void *opaque); +int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env, + int cpuid, void *opaque); +int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env, + void *opaque); +int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env, + void *opaque); +int cpu_get_dump_info(ArchDumpInfo *info); +ssize_t cpu_get_note_size(int class, int machine, int nr_cpus); + #endif @@ -1494,7 +1494,8 @@ void tb_invalidate_phys_addr(target_phys_addr_t addr) static void breakpoint_invalidate(CPUArchState *env, target_ulong pc) { - tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc)); + tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc) | + (pc & ~TARGET_PAGE_MASK)); } #endif #endif /* TARGET_HAS_ICE */ diff --git a/fsdev/Makefile.objs b/fsdev/Makefile.objs new file mode 100644 index 0000000000..cb1e2500b9 --- /dev/null +++ b/fsdev/Makefile.objs @@ -0,0 +1,9 @@ +ifeq ($(CONFIG_REALLY_VIRTFS),y) +common-obj-y = qemu-fsdev.o virtio-9p-marshal.o + +# Toplevel always builds this; targets without virtio will put it in +# common-obj-y +extra-obj-y = qemu-fsdev-dummy.o +else +common-obj-y = qemu-fsdev-dummy.o +endif diff --git a/hw/9pfs/Makefile.objs b/hw/9pfs/Makefile.objs new file mode 100644 index 0000000000..972df24050 --- /dev/null +++ b/hw/9pfs/Makefile.objs @@ -0,0 +1,9 @@ +hw-obj-y = virtio-9p.o +hw-obj-y += virtio-9p-local.o virtio-9p-xattr.o +hw-obj-y += virtio-9p-xattr-user.o virtio-9p-posix-acl.o +hw-obj-y += virtio-9p-coth.o cofs.o codir.o cofile.o +hw-obj-y += coxattr.o virtio-9p-synth.o +hw-obj-$(CONFIG_OPEN_BY_HANDLE) += virtio-9p-handle.o +hw-obj-y += virtio-9p-proxy.o + +obj-y += virtio-9p-device.o diff --git a/hw/Makefile.objs b/hw/Makefile.objs new file mode 100644 index 0000000000..7e17504278 --- /dev/null +++ b/hw/Makefile.objs @@ -0,0 +1,165 @@ +hw-obj-y = usb/ ide/ +hw-obj-y += loader.o +hw-obj-$(CONFIG_VIRTIO) += virtio-console.o +hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o +hw-obj-y += fw_cfg.o +hw-obj-$(CONFIG_PCI) += pci.o pci_bridge.o pci_bridge_dev.o +hw-obj-$(CONFIG_PCI) += msix.o msi.o +hw-obj-$(CONFIG_PCI) += shpc.o +hw-obj-$(CONFIG_PCI) += slotid_cap.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 +hw-obj-$(CONFIG_NAND) += nand.o +hw-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o +hw-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o + +hw-obj-$(CONFIG_M48T59) += m48t59.o +hw-obj-$(CONFIG_ESCC) += escc.o +hw-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o + +hw-obj-$(CONFIG_SERIAL) += serial.o +hw-obj-$(CONFIG_PARALLEL) += parallel.o +hw-obj-$(CONFIG_I8254) += i8254_common.o i8254.o +hw-obj-$(CONFIG_PCSPK) += pcspk.o +hw-obj-$(CONFIG_PCKBD) += pckbd.o +hw-obj-$(CONFIG_FDC) += fdc.o +hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o +hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o +hw-obj-$(CONFIG_DMA) += dma.o +hw-obj-$(CONFIG_I82374) += i82374.o +hw-obj-$(CONFIG_HPET) += hpet.o +hw-obj-$(CONFIG_APPLESMC) += applesmc.o +hw-obj-$(CONFIG_SMARTCARD) += ccid-card-passthru.o +hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o +hw-obj-$(CONFIG_I8259) += i8259_common.o i8259.o + +# PPC devices +hw-obj-$(CONFIG_PREP_PCI) += prep_pci.o +hw-obj-$(CONFIG_I82378) += i82378.o +# Mac shared devices +hw-obj-$(CONFIG_MACIO) += macio.o +hw-obj-$(CONFIG_CUDA) += cuda.o +hw-obj-$(CONFIG_ADB) += adb.o +hw-obj-$(CONFIG_MAC_NVRAM) += mac_nvram.o +hw-obj-$(CONFIG_MAC_DBDMA) += mac_dbdma.o +# OldWorld PowerMac +hw-obj-$(CONFIG_HEATHROW_PIC) += heathrow_pic.o +hw-obj-$(CONFIG_GRACKLE_PCI) += grackle_pci.o +# NewWorld PowerMac +hw-obj-$(CONFIG_UNIN_PCI) += unin_pci.o +hw-obj-$(CONFIG_DEC_PCI) += dec_pci.o +# PowerPC E500 boards +hw-obj-$(CONFIG_PPCE500_PCI) += ppce500_pci.o + +# MIPS devices +hw-obj-$(CONFIG_PIIX4) += piix4.o +hw-obj-$(CONFIG_G364FB) += g364fb.o +hw-obj-$(CONFIG_JAZZ_LED) += jazz_led.o + +# PCI watchdog devices +hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o + +hw-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o + +# PCI network cards +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_E1000_PCI) += e1000.o +hw-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o + +hw-obj-$(CONFIG_SMC91C111) += smc91c111.o +hw-obj-$(CONFIG_LAN9118) += lan9118.o +hw-obj-$(CONFIG_NE2000_ISA) += ne2000-isa.o +hw-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o + +# SCSI layer +hw-obj-$(CONFIG_LSI_SCSI_PCI) += lsi53c895a.o +hw-obj-$(CONFIG_ESP) += esp.o + +hw-obj-y += sysbus.o isa-bus.o +hw-obj-y += qdev-addr.o + +# VGA +hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o +hw-obj-$(CONFIG_VGA_ISA) += vga-isa.o +hw-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o +hw-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o +hw-obj-$(CONFIG_VMMOUSE) += vmmouse.o +hw-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o + +hw-obj-$(CONFIG_RC4030) += rc4030.o +hw-obj-$(CONFIG_DP8393X) += dp8393x.o +hw-obj-$(CONFIG_DS1225Y) += ds1225y.o +hw-obj-$(CONFIG_MIPSNET) += mipsnet.o + +# Sound +sound-obj-y = +sound-obj-$(CONFIG_SB16) += sb16.o +sound-obj-$(CONFIG_ES1370) += es1370.o +sound-obj-$(CONFIG_AC97) += ac97.o +sound-obj-$(CONFIG_ADLIB) += fmopl.o adlib.o +sound-obj-$(CONFIG_GUS) += gus.o gusemu_hal.o gusemu_mixer.o +sound-obj-$(CONFIG_CS4231A) += cs4231a.o +sound-obj-$(CONFIG_HDA) += intel-hda.o hda-audio.o + +$(obj)/adlib.o $(obj)/fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0 + +hw-obj-$(CONFIG_SOUND) += $(sound-obj-y) + +hw-obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/ + +common-obj-y += usb/ +common-obj-y += irq.o +common-obj-$(CONFIG_PTIMER) += ptimer.o +common-obj-$(CONFIG_MAX7310) += max7310.o +common-obj-$(CONFIG_WM8750) += wm8750.o +common-obj-$(CONFIG_TWL92230) += twl92230.o +common-obj-$(CONFIG_TSC2005) += tsc2005.o +common-obj-$(CONFIG_LM832X) += lm832x.o +common-obj-$(CONFIG_TMP105) += tmp105.o +common-obj-$(CONFIG_STELLARIS_INPUT) += stellaris_input.o +common-obj-$(CONFIG_SSD0303) += ssd0303.o +common-obj-$(CONFIG_SSD0323) += ssd0323.o +common-obj-$(CONFIG_ADS7846) += ads7846.o +common-obj-$(CONFIG_MAX111X) += max111x.o +common-obj-$(CONFIG_DS1338) += ds1338.o +common-obj-y += i2c.o smbus.o smbus_eeprom.o +common-obj-y += eeprom93xx.o +common-obj-y += scsi-disk.o cdrom.o +common-obj-y += scsi-generic.o scsi-bus.o +common-obj-y += hid.o +common-obj-$(CONFIG_SSI) += ssi.o +common-obj-$(CONFIG_SSI_SD) += ssi-sd.o +common-obj-$(CONFIG_SD) += sd.o +common-obj-y += bt.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o +common-obj-y += bt-hci-csr.o +common-obj-y += msmouse.o ps2.o +common-obj-y += qdev.o qdev-properties.o qdev-monitor.o +common-obj-$(CONFIG_BRLAPI) += baum.o + +# xen backend driver support +common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o +common-obj-$(CONFIG_XEN_BACKEND) += xen_console.o xenfb.o xen_disk.o xen_nic.o + +# Per-target files +# virtio has to be here due to weird dependency between PCI and virtio-net. +# need to fix this properly +obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o +obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o virtio-scsi.o +obj-$(CONFIG_SOFTMMU) += vhost_net.o +obj-$(CONFIG_VHOST_NET) += vhost.o +obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/ +obj-$(CONFIG_NO_PCI) += pci-stub.o +obj-$(CONFIG_VGA) += vga.o +obj-$(CONFIG_SOFTMMU) += device-hotplug.o +obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o + +# Inter-VM PCI shared memory +ifeq ($(CONFIG_PCI), y) +obj-$(CONFIG_KVM) += ivshmem.o +endif diff --git a/hw/alpha/Makefile.objs b/hw/alpha/Makefile.objs new file mode 100644 index 0000000000..af1c07fa7c --- /dev/null +++ b/hw/alpha/Makefile.objs @@ -0,0 +1,4 @@ +obj-y = mc146818rtc.o +obj-y += alpha_pci.o alpha_dp264.o alpha_typhoon.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs new file mode 100644 index 0000000000..a0ff6a62d6 --- /dev/null +++ b/hw/arm/Makefile.objs @@ -0,0 +1,40 @@ +obj-y = integratorcp.o versatilepb.o arm_pic.o arm_timer.o +obj-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o +obj-y += versatile_pci.o +obj-y += versatile_i2c.o +obj-y += cadence_uart.o +obj-y += cadence_ttc.o +obj-y += cadence_gem.o +obj-y += xilinx_zynq.o zynq_slcr.o +obj-y += arm_gic.o +obj-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o +obj-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o +obj-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o +obj-y += exynos4210_pmu.o exynos4210_mct.o exynos4210_fimd.o +obj-y += arm_l2x0.o +obj-y += arm_mptimer.o a15mpcore.o +obj-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o +obj-y += highbank.o +obj-y += pl061.o +obj-y += xgmac.o +obj-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o +obj-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o +obj-y += gumstix.o +obj-y += zaurus.o ide/microdrive.o spitz.o tosa.o tc6393xb.o +obj-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o \ + omap_gpio.o omap_intc.o omap_uart.o +obj-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o \ + omap_gpmc.o omap_sdrc.o omap_spi.o omap_tap.o omap_l4.o +obj-y += omap_sx1.o palm.o tsc210x.o +obj-y += nseries.o blizzard.o onenand.o cbus.o tusb6010.o usb/hcd-musb.o +obj-y += mst_fpga.o mainstone.o +obj-y += z2.o +obj-y += musicpal.o bitbang_i2c.o marvell_88w8618_audio.o +obj-y += framebuffer.o +obj-y += vexpress.o +obj-y += strongarm.o +obj-y += collie.o +obj-y += pl041.o lm4549.o +obj-$(CONFIG_FDT) += ../device_tree.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/cris/Makefile.objs b/hw/cris/Makefile.objs new file mode 100644 index 0000000000..aa9298a0ed --- /dev/null +++ b/hw/cris/Makefile.objs @@ -0,0 +1,13 @@ +# Boards +obj-y = cris_pic_cpu.o +obj-y += cris-boot.o +obj-y += axis_dev88.o + +# IO blocks +obj-y += etraxfs_dma.o +obj-y += etraxfs_pic.o +obj-y += etraxfs_eth.o +obj-y += etraxfs_timer.o +obj-y += etraxfs_ser.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs new file mode 100644 index 0000000000..d43f1df5f0 --- /dev/null +++ b/hw/i386/Makefile.objs @@ -0,0 +1,13 @@ +obj-y += mc146818rtc.o pc.o +obj-y += apic_common.o apic.o kvmvapic.o +obj-y += sga.o ioapic_common.o ioapic.o piix_pci.o +obj-y += vmport.o +obj-y += pci-hotplug.o smbios.o wdt_ib700.o +obj-y += debugcon.o multiboot.o +obj-y += pc_piix.o +obj-y += pc_sysfw.o +obj-$(CONFIG_XEN) += xen_platform.o xen_apic.o +obj-$(CONFIG_KVM) += kvm/clock.o kvm/apic.o kvm/i8259.o kvm/ioapic.o kvm/i8254.o +obj-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/ide/Makefile.objs b/hw/ide/Makefile.objs new file mode 100644 index 0000000000..cf718dd016 --- /dev/null +++ b/hw/ide/Makefile.objs @@ -0,0 +1,10 @@ +hw-obj-$(CONFIG_IDE_CORE) += core.o atapi.o +hw-obj-$(CONFIG_IDE_QDEV) += qdev.o +hw-obj-$(CONFIG_IDE_PCI) += pci.o +hw-obj-$(CONFIG_IDE_ISA) += isa.o +hw-obj-$(CONFIG_IDE_PIIX) += piix.o +hw-obj-$(CONFIG_IDE_CMD646) += cmd646.o +hw-obj-$(CONFIG_IDE_MACIO) += macio.o +hw-obj-$(CONFIG_IDE_VIA) += via.o +hw-obj-$(CONFIG_AHCI) += ahci.o +hw-obj-$(CONFIG_AHCI) += ich.o diff --git a/hw/lm32/Makefile.objs b/hw/lm32/Makefile.objs new file mode 100644 index 0000000000..4e1843c11d --- /dev/null +++ b/hw/lm32/Makefile.objs @@ -0,0 +1,23 @@ +# LM32 boards +obj-y += lm32_boards.o +obj-y += milkymist.o + +# LM32 peripherals +obj-y += lm32_pic.o +obj-y += lm32_juart.o +obj-y += lm32_timer.o +obj-y += lm32_uart.o +obj-y += lm32_sys.o +obj-y += milkymist-ac97.o +obj-y += milkymist-hpdmc.o +obj-y += milkymist-memcard.o +obj-y += milkymist-minimac2.o +obj-y += milkymist-pfpu.o +obj-y += milkymist-softusb.o +obj-y += milkymist-sysctl.o +obj-$(CONFIG_OPENGL) += milkymist-tmu2.o +obj-y += milkymist-uart.o +obj-y += milkymist-vgafb.o +obj-y += framebuffer.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/m68k/Makefile.objs b/hw/m68k/Makefile.objs new file mode 100644 index 0000000000..93b6d25baf --- /dev/null +++ b/hw/m68k/Makefile.objs @@ -0,0 +1,4 @@ +obj-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o +obj-y += dummy_m68k.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/microblaze/Makefile.objs b/hw/microblaze/Makefile.objs new file mode 100644 index 0000000000..020f7b6e9b --- /dev/null +++ b/hw/microblaze/Makefile.objs @@ -0,0 +1,14 @@ +obj-y = petalogix_s3adsp1800_mmu.o +obj-y += petalogix_ml605_mmu.o +obj-y += microblaze_boot.o + +obj-y += microblaze_pic_cpu.o +obj-y += xilinx_intc.o +obj-y += xilinx_timer.o +obj-y += xilinx_uartlite.o +obj-y += xilinx_ethlite.o +obj-y += xilinx_axidma.o +obj-y += xilinx_axienet.o +obj-$(CONFIG_FDT) += ../device_tree.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs new file mode 100644 index 0000000000..29a5d0db04 --- /dev/null +++ b/hw/mips/Makefile.objs @@ -0,0 +1,6 @@ +obj-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o +obj-y += mips_addr.o mips_timer.o mips_int.o +obj-y += gt64xxx.o mc146818rtc.o +obj-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs new file mode 100644 index 0000000000..d0ef8a26cf --- /dev/null +++ b/hw/ppc/Makefile.objs @@ -0,0 +1,31 @@ +# shared objects +obj-y = ppc.o ppc_booke.o +# PREP target +obj-y += mc146818rtc.o +obj-y += ppc_prep.o +# OldWorld PowerMac +obj-y += ppc_oldworld.o +# NewWorld PowerMac +obj-y += ppc_newworld.o +# IBM pSeries (sPAPR) +obj-$(CONFIG_PSERIES) += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o +obj-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o +obj-$(CONFIG_PSERIES) += spapr_pci.o pci-hotplug.o +# PowerPC 4xx boards +obj-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o +obj-y += ppc440_bamboo.o +# PowerPC E500 boards +obj-y += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o +# PowerPC 440 Xilinx ML507 reference board. +obj-y += virtex_ml507.o +# PowerPC OpenPIC +obj-y += openpic.o +obj-$(CONFIG_FDT) += ../device_tree.o + +# Xilinx PPC peripherals +obj-y += xilinx_intc.o +obj-y += xilinx_timer.o +obj-y += xilinx_uartlite.o +obj-y += xilinx_ethlite.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs new file mode 100644 index 0000000000..dcdcac8a81 --- /dev/null +++ b/hw/s390x/Makefile.objs @@ -0,0 +1,3 @@ +obj-y = s390-virtio-bus.o s390-virtio.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index f10f3ec25c..4a798210ce 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -1507,10 +1507,9 @@ static void put_scsi_requests(QEMUFile *f, void *pv, size_t size) QTAILQ_FOREACH(req, &s->requests, next) { assert(!req->io_canceled); assert(req->status == -1); - assert(req->retry); assert(req->enqueued); - qemu_put_sbyte(f, 1); + qemu_put_sbyte(f, req->retry ? 1 : 2); qemu_put_buffer(f, req->cmd.buf, sizeof(req->cmd.buf)); qemu_put_be32s(f, &req->tag); qemu_put_be32s(f, &req->lun); @@ -1528,8 +1527,9 @@ static int get_scsi_requests(QEMUFile *f, void *pv, size_t size) { SCSIDevice *s = pv; SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus); + int8_t sbyte; - while (qemu_get_sbyte(f)) { + while ((sbyte = qemu_get_sbyte(f)) > 0) { uint8_t buf[SCSI_CMD_BUF_SIZE]; uint32_t tag; uint32_t lun; @@ -1539,6 +1539,7 @@ static int get_scsi_requests(QEMUFile *f, void *pv, size_t size) qemu_get_be32s(f, &tag); qemu_get_be32s(f, &lun); req = scsi_req_new(s, tag, lun, buf, NULL); + req->retry = (sbyte == 1); if (bus->info->load_request) { req->hba_private = bus->info->load_request(f, req); } @@ -1547,7 +1548,6 @@ static int get_scsi_requests(QEMUFile *f, void *pv, size_t size) } /* Just restart it later. */ - req->retry = true; scsi_req_enqueue_internal(req); /* At this point, the request will be kept alive by the reference diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 045c764d9b..1691491c03 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -132,8 +132,14 @@ static void scsi_disk_save_request(QEMUFile *f, SCSIRequest *req) qemu_put_be64s(f, &r->sector); qemu_put_be32s(f, &r->sector_count); qemu_put_be32s(f, &r->buflen); - if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) { - qemu_put_buffer(f, r->iov.iov_base, r->iov.iov_len); + if (r->buflen) { + if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { + qemu_put_buffer(f, r->iov.iov_base, r->iov.iov_len); + } else if (!req->retry) { + uint32_t len = r->iov.iov_len; + qemu_put_be32s(f, &len); + qemu_put_buffer(f, r->iov.iov_base, r->iov.iov_len); + } } } @@ -148,6 +154,12 @@ static void scsi_disk_load_request(QEMUFile *f, SCSIRequest *req) scsi_init_iovec(r, r->buflen); if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { qemu_get_buffer(f, r->iov.iov_base, r->iov.iov_len); + } else if (!r->req.retry) { + uint32_t len; + qemu_get_be32s(f, &len); + r->iov.iov_len = len; + assert(r->iov.iov_len <= r->buflen); + qemu_get_buffer(f, r->iov.iov_base, r->iov.iov_len); } } diff --git a/hw/sh4/Makefile.objs b/hw/sh4/Makefile.objs new file mode 100644 index 0000000000..68c5921790 --- /dev/null +++ b/hw/sh4/Makefile.objs @@ -0,0 +1,5 @@ +obj-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o +obj-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o +obj-y += ide/mmio.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/sparc/Makefile.objs b/hw/sparc/Makefile.objs new file mode 100644 index 0000000000..a39a511c52 --- /dev/null +++ b/hw/sparc/Makefile.objs @@ -0,0 +1,8 @@ +obj-y = sun4m.o lance.o tcx.o sun4m_iommu.o slavio_intctl.o +obj-y += slavio_timer.o slavio_misc.o sparc32_dma.o +obj-y += cs4231.o eccmemctl.o sbi.o sun4c_intctl.o leon3.o + +# GRLIB +obj-y += grlib_gptimer.o grlib_irqmp.o grlib_apbuart.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/sparc64/Makefile.objs b/hw/sparc64/Makefile.objs new file mode 100644 index 0000000000..8c65fc4215 --- /dev/null +++ b/hw/sparc64/Makefile.objs @@ -0,0 +1,4 @@ +obj-y = sun4u.o apb_pci.o +obj-y += mc146818rtc.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs new file mode 100644 index 0000000000..9c7ddf5cb2 --- /dev/null +++ b/hw/usb/Makefile.objs @@ -0,0 +1,13 @@ +hw-obj-$(CONFIG_USB_UHCI) += hcd-uhci.o +hw-obj-$(CONFIG_USB_OHCI) += hcd-ohci.o +hw-obj-$(CONFIG_USB_EHCI) += hcd-ehci.o +hw-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o +hw-obj-y += libhw.o + +hw-obj-$(CONFIG_SMARTCARD) += dev-smartcard-reader.o +hw-obj-$(CONFIG_USB_REDIR) += redirect.o + +common-obj-y += core.o bus.o desc.o dev-hub.o +common-obj-y += host-$(HOST_USB).o dev-bluetooth.o +common-obj-y += dev-hid.o dev-storage.o dev-wacom.o +common-obj-y += dev-serial.o dev-network.o dev-audio.o diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index a96c0b9e5e..097d7b4a6d 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -48,10 +48,9 @@ struct usb_msd_csw { typedef struct { USBDevice dev; enum USBMSDMode mode; + uint32_t scsi_off; uint32_t scsi_len; - uint8_t *scsi_buf; uint32_t data_len; - uint32_t residue; struct usb_msd_csw csw; SCSIRequest *req; SCSIBus bus; @@ -179,9 +178,9 @@ static void usb_msd_copy_data(MSDState *s, USBPacket *p) len = p->iov.size - p->result; if (len > s->scsi_len) len = s->scsi_len; - usb_packet_copy(p, s->scsi_buf, len); + usb_packet_copy(p, scsi_req_get_buf(s->req) + s->scsi_off, len); s->scsi_len -= len; - s->scsi_buf += len; + s->scsi_off += len; s->data_len -= len; if (s->scsi_len == 0 || s->data_len == 0) { scsi_req_continue(s->req); @@ -201,6 +200,18 @@ static void usb_msd_send_status(MSDState *s, USBPacket *p) memset(&s->csw, 0, sizeof(s->csw)); } +static void usb_msd_packet_complete(MSDState *s) +{ + USBPacket *p = s->packet; + + /* Set s->packet to NULL before calling usb_packet_complete + because another request may be issued before + usb_packet_complete returns. */ + DPRINTF("Packet complete %p\n", p); + s->packet = NULL; + usb_packet_complete(&s->dev, p); +} + static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len) { MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); @@ -208,17 +219,12 @@ static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len) assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV)); s->scsi_len = len; - s->scsi_buf = scsi_req_get_buf(req); + s->scsi_off = 0; if (p) { usb_msd_copy_data(s, p); p = s->packet; if (p && p->result == p->iov.size) { - /* Set s->packet to NULL before calling usb_packet_complete - because another request may be issued before - usb_packet_complete returns. */ - DPRINTF("Packet complete %p\n", p); - s->packet = NULL; - usb_packet_complete(&s->dev, p); + usb_msd_packet_complete(s); } } } @@ -229,11 +235,10 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status, size_t r USBPacket *p = s->packet; DPRINTF("Command complete %d tag 0x%x\n", status, req->tag); - s->residue = s->data_len; s->csw.sig = cpu_to_le32(0x53425355); s->csw.tag = cpu_to_le32(req->tag); - s->csw.residue = cpu_to_le32(s->residue); + s->csw.residue = cpu_to_le32(s->data_len); s->csw.status = status != 0; if (s->packet) { @@ -252,8 +257,7 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status, size_t r s->mode = USB_MSDM_CSW; } } - s->packet = NULL; - usb_packet_complete(&s->dev, p); + usb_msd_packet_complete(s); } else if (s->data_len == 0) { s->mode = USB_MSDM_CSW; } @@ -283,10 +287,8 @@ static void usb_msd_handle_reset(USBDevice *dev) assert(s->req == NULL); if (s->packet) { - USBPacket *p = s->packet; - s->packet = NULL; - p->result = USB_RET_STALL; - usb_packet_complete(dev, p); + s->packet->result = USB_RET_STALL; + usb_msd_packet_complete(s); } s->mode = USB_MSDM_CBW; @@ -378,7 +380,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) } DPRINTF("Command tag 0x%x flags %08x len %d data %d\n", tag, cbw.flags, cbw.cmd_len, s->data_len); - s->residue = 0; + assert(le32_to_cpu(s->csw.residue) == 0); s->scsi_len = 0; s->req = scsi_req_new(s->scsi_dev, tag, 0, cbw.cmd, NULL); scsi_req_enqueue(s->req); @@ -397,7 +399,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) if (s->scsi_len) { usb_msd_copy_data(s, p); } - if (s->residue) { + if (le32_to_cpu(s->csw.residue)) { int len = p->iov.size - p->result; if (len) { usb_packet_skip(p, len); @@ -458,7 +460,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) if (s->scsi_len) { usb_msd_copy_data(s, p); } - if (s->residue) { + if (le32_to_cpu(s->csw.residue)) { int len = p->iov.size - p->result; if (len) { usb_packet_skip(p, len); @@ -504,6 +506,17 @@ static void usb_msd_password_cb(void *opaque, int err) qdev_unplug(&s->dev.qdev, NULL); } +static void *usb_msd_load_request(QEMUFile *f, SCSIRequest *req) +{ + MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); + + /* nothing to load, just store req in our state struct */ + assert(s->req == NULL); + scsi_req_ref(req); + s->req = req; + return NULL; +} + static const struct SCSIBusInfo usb_msd_scsi_info = { .tcq = false, .max_target = 0, @@ -511,7 +524,8 @@ static const struct SCSIBusInfo usb_msd_scsi_info = { .transfer_data = usb_msd_transfer_data, .complete = usb_msd_command_complete, - .cancel = usb_msd_request_cancelled + .cancel = usb_msd_request_cancelled, + .load_request = usb_msd_load_request, }; static int usb_msd_initfn(USBDevice *dev) @@ -631,11 +645,18 @@ static USBDevice *usb_msd_init(USBBus *bus, const char *filename) static const VMStateDescription vmstate_usb_msd = { .name = "usb-storage", - .unmigratable = 1, /* FIXME: handle transactions which are in flight */ .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField []) { VMSTATE_USB_DEVICE(dev, MSDState), + VMSTATE_UINT32(mode, MSDState), + VMSTATE_UINT32(scsi_len, MSDState), + VMSTATE_UINT32(scsi_off, MSDState), + VMSTATE_UINT32(data_len, MSDState), + VMSTATE_UINT32(csw.sig, MSDState), + VMSTATE_UINT32(csw.tag, MSDState), + VMSTATE_UINT32(csw.residue, MSDState), + VMSTATE_UINT8(csw.status, MSDState), VMSTATE_END_OF_LIST() } }; diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index e759c996ce..5298204d9d 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -334,6 +334,7 @@ typedef struct EHCIfstn { uint32_t backptr; // Standard next link pointer } EHCIfstn; +typedef struct EHCIPacket EHCIPacket; typedef struct EHCIQueue EHCIQueue; typedef struct EHCIState EHCIState; @@ -343,26 +344,36 @@ enum async_state { EHCI_ASYNC_FINISHED, }; +struct EHCIPacket { + EHCIQueue *queue; + QTAILQ_ENTRY(EHCIPacket) next; + + EHCIqtd qtd; /* copy of current QTD (being worked on) */ + uint32_t qtdaddr; /* address QTD read from */ + + USBPacket packet; + QEMUSGList sgl; + int pid; + uint32_t tbytes; + enum async_state async; + int usb_status; +}; + struct EHCIQueue { EHCIState *ehci; QTAILQ_ENTRY(EHCIQueue) next; uint32_t seen; uint64_t ts; + int async; /* cached data from guest - needs to be flushed * when guest removes an entry (doorbell, handshake sequence) */ - EHCIqh qh; // copy of current QH (being worked on) - uint32_t qhaddr; // address QH read from - EHCIqtd qtd; // copy of current QTD (being worked on) - uint32_t qtdaddr; // address QTD read from - - USBPacket packet; - QEMUSGList sgl; - int pid; - uint32_t tbytes; - enum async_state async; - int usb_status; + EHCIqh qh; /* copy of current QH (being worked on) */ + uint32_t qhaddr; /* address QH read from */ + uint32_t qtdaddr; /* address QTD read from */ + USBDevice *dev; + QTAILQ_HEAD(, EHCIPacket) packets; }; typedef QTAILQ_HEAD(EHCIQueueHead, EHCIQueue) EHCIQueueHead; @@ -375,7 +386,6 @@ struct EHCIState { int companion_count; /* properties */ - uint32_t freq; uint32_t maxframes; /* @@ -403,7 +413,7 @@ struct EHCIState { * Internal states, shadow registers, etc */ QEMUTimer *frame_timer; - int attach_poll_counter; + QEMUBH *async_bh; int astate; // Current state in asynchronous schedule int pstate; // Current state in periodic schedule USBPort ports[NB_PORTS]; @@ -419,6 +429,7 @@ struct EHCIState { QEMUSGList isgl; uint64_t last_run_ns; + uint32_t async_stepdown; }; #define SET_LAST_RUN_CLOCK(s) \ @@ -574,14 +585,37 @@ static inline void ehci_commit_interrupt(EHCIState *s) s->usbsts_pending = 0; } +static void ehci_update_halt(EHCIState *s) +{ + if (s->usbcmd & USBCMD_RUNSTOP) { + ehci_clear_usbsts(s, USBSTS_HALT); + } else { + if (s->astate == EST_INACTIVE && s->pstate == EST_INACTIVE) { + ehci_set_usbsts(s, USBSTS_HALT); + } + } +} + static void ehci_set_state(EHCIState *s, int async, int state) { if (async) { trace_usb_ehci_state("async", state2str(state)); s->astate = state; + if (s->astate == EST_INACTIVE) { + ehci_clear_usbsts(s, USBSTS_ASS); + ehci_update_halt(s); + } else { + ehci_set_usbsts(s, USBSTS_ASS); + } } else { trace_usb_ehci_state("periodic", state2str(state)); s->pstate = state; + if (s->pstate == EST_INACTIVE) { + ehci_clear_usbsts(s, USBSTS_PSS); + ehci_update_halt(s); + } else { + ehci_set_usbsts(s, USBSTS_PSS); + } } } @@ -655,27 +689,71 @@ static void ehci_trace_sitd(EHCIState *s, target_phys_addr_t addr, (bool)(sitd->results & SITD_RESULTS_ACTIVE)); } +static inline bool ehci_enabled(EHCIState *s) +{ + return s->usbcmd & USBCMD_RUNSTOP; +} + +static inline bool ehci_async_enabled(EHCIState *s) +{ + return ehci_enabled(s) && (s->usbcmd & USBCMD_ASE); +} + +static inline bool ehci_periodic_enabled(EHCIState *s) +{ + return ehci_enabled(s) && (s->usbcmd & USBCMD_PSE); +} + +/* packet management */ + +static EHCIPacket *ehci_alloc_packet(EHCIQueue *q) +{ + EHCIPacket *p; + + p = g_new0(EHCIPacket, 1); + p->queue = q; + usb_packet_init(&p->packet); + QTAILQ_INSERT_TAIL(&q->packets, p, next); + trace_usb_ehci_packet_action(p->queue, p, "alloc"); + return p; +} + +static void ehci_free_packet(EHCIPacket *p) +{ + trace_usb_ehci_packet_action(p->queue, p, "free"); + if (p->async == EHCI_ASYNC_INFLIGHT) { + usb_cancel_packet(&p->packet); + } + QTAILQ_REMOVE(&p->queue->packets, p, next); + usb_packet_cleanup(&p->packet); + g_free(p); +} + /* queue management */ -static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, int async) +static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, uint32_t addr, int async) { EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues; EHCIQueue *q; q = g_malloc0(sizeof(*q)); q->ehci = ehci; - usb_packet_init(&q->packet); + q->qhaddr = addr; + q->async = async; + QTAILQ_INIT(&q->packets); QTAILQ_INSERT_HEAD(head, q, next); trace_usb_ehci_queue_action(q, "alloc"); return q; } -static void ehci_free_queue(EHCIQueue *q, int async) +static void ehci_free_queue(EHCIQueue *q) { - EHCIQueueHead *head = async ? &q->ehci->aqueues : &q->ehci->pqueues; + EHCIQueueHead *head = q->async ? &q->ehci->aqueues : &q->ehci->pqueues; + EHCIPacket *p; + trace_usb_ehci_queue_action(q, "free"); - if (q->async == EHCI_ASYNC_INFLIGHT) { - usb_cancel_packet(&q->packet); + while ((p = QTAILQ_FIRST(&q->packets)) != NULL) { + ehci_free_packet(p); } QTAILQ_REMOVE(head, q, next); g_free(q); @@ -698,6 +776,7 @@ static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr, static void ehci_queues_rip_unused(EHCIState *ehci, int async, int flush) { EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues; + uint64_t maxage = FRAME_TIMER_NS * ehci->maxframes * 4; EHCIQueue *q, *tmp; QTAILQ_FOREACH_SAFE(q, head, next, tmp) { @@ -706,11 +785,10 @@ static void ehci_queues_rip_unused(EHCIState *ehci, int async, int flush) q->ts = ehci->last_run_ns; continue; } - if (!flush && ehci->last_run_ns < q->ts + 250000000) { - /* allow 0.25 sec idle */ + if (!flush && ehci->last_run_ns < q->ts + maxage) { continue; } - ehci_free_queue(q, async); + ehci_free_queue(q); } } @@ -720,11 +798,10 @@ static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev, int async) EHCIQueue *q, *tmp; QTAILQ_FOREACH_SAFE(q, head, next, tmp) { - if (!usb_packet_is_inflight(&q->packet) || - q->packet.ep->dev != dev) { + if (q->dev != dev) { continue; } - ehci_free_queue(q, async); + ehci_free_queue(q); } } @@ -734,7 +811,7 @@ static void ehci_queues_rip_all(EHCIState *ehci, int async) EHCIQueue *q, *tmp; QTAILQ_FOREACH_SAFE(q, head, next, tmp) { - ehci_free_queue(q, async); + ehci_free_queue(q); } } @@ -812,6 +889,8 @@ static void ehci_wakeup(USBPort *port) USBPort *companion = s->companion_ports[port->index]; if (companion->ops->wakeup) { companion->ops->wakeup(companion); + } else { + qemu_bh_schedule(s->async_bh); } } } @@ -904,7 +983,6 @@ static void ehci_reset(void *opaque) s->astate = EST_INACTIVE; s->pstate = EST_INACTIVE; - s->attach_poll_counter = 0; for(i = 0; i < NB_PORTS; i++) { if (s->companion_ports[i]) { @@ -920,6 +998,7 @@ static void ehci_reset(void *opaque) ehci_queues_rip_all(s, 0); ehci_queues_rip_all(s, 1); qemu_del_timer(s->frame_timer); + qemu_bh_cancel(s->async_bh); } static uint32_t ehci_mem_readb(void *ptr, target_phys_addr_t addr) @@ -1064,22 +1143,20 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) /* Do any register specific pre-write processing here. */ switch(addr) { case USBCMD: - if ((val & USBCMD_RUNSTOP) && !(s->usbcmd & USBCMD_RUNSTOP)) { - qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock)); - SET_LAST_RUN_CLOCK(s); - ehci_clear_usbsts(s, USBSTS_HALT); - } - - if (!(val & USBCMD_RUNSTOP) && (s->usbcmd & USBCMD_RUNSTOP)) { - qemu_del_timer(s->frame_timer); - ehci_queues_rip_all(s, 0); - ehci_queues_rip_all(s, 1); - ehci_set_usbsts(s, USBSTS_HALT); - } - if (val & USBCMD_HCRESET) { ehci_reset(s); val = s->usbcmd; + break; + } + + if (((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & val) != + ((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & s->usbcmd)) { + if (s->pstate == EST_INACTIVE) { + SET_LAST_RUN_CLOCK(s); + } + ehci_update_halt(s); + s->async_stepdown = 0; + qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock)); } /* not supporting dynamic frame list size at the moment */ @@ -1114,7 +1191,7 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) break; case PERIODICLISTBASE: - if ((s->usbcmd & USBCMD_PSE) && (s->usbcmd & USBCMD_RUNSTOP)) { + if (ehci_periodic_enabled(s)) { fprintf(stderr, "ehci: PERIODIC list base register set while periodic schedule\n" " is enabled and HC is enabled\n"); @@ -1122,7 +1199,7 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) break; case ASYNCLISTADDR: - if ((s->usbcmd & USBCMD_ASE) && (s->usbcmd & USBCMD_RUNSTOP)) { + if (ehci_async_enabled(s)) { fprintf(stderr, "ehci: ASYNC list address register set while async schedule\n" " is enabled and HC is enabled\n"); @@ -1169,21 +1246,25 @@ static inline int put_dwords(EHCIState *ehci, uint32_t addr, static int ehci_qh_do_overlay(EHCIQueue *q) { + EHCIPacket *p = QTAILQ_FIRST(&q->packets); int i; int dtoggle; int ping; int eps; int reload; + assert(p != NULL); + assert(p->qtdaddr == q->qtdaddr); + // remember values in fields to preserve in qh after overlay dtoggle = q->qh.token & QTD_TOKEN_DTOGGLE; ping = q->qh.token & QTD_TOKEN_PING; - q->qh.current_qtd = q->qtdaddr; - q->qh.next_qtd = q->qtd.next; - q->qh.altnext_qtd = q->qtd.altnext; - q->qh.token = q->qtd.token; + q->qh.current_qtd = p->qtdaddr; + q->qh.next_qtd = p->qtd.next; + q->qh.altnext_qtd = p->qtd.altnext; + q->qh.token = p->qtd.token; eps = get_field(q->qh.epchar, QH_EPCHAR_EPS); @@ -1196,7 +1277,7 @@ static int ehci_qh_do_overlay(EHCIQueue *q) set_field(&q->qh.altnext_qtd, reload, QH_ALTNEXT_NAKCNT); for (i = 0; i < 5; i++) { - q->qh.bufptr[i] = q->qtd.bufptr[i]; + q->qh.bufptr[i] = p->qtd.bufptr[i]; } if (!(q->qh.epchar & QH_EPCHAR_DTC)) { @@ -1214,15 +1295,15 @@ static int ehci_qh_do_overlay(EHCIQueue *q) return 0; } -static int ehci_init_transfer(EHCIQueue *q) +static int ehci_init_transfer(EHCIPacket *p) { uint32_t cpage, offset, bytes, plen; dma_addr_t page; - cpage = get_field(q->qh.token, QTD_TOKEN_CPAGE); - bytes = get_field(q->qh.token, QTD_TOKEN_TBYTES); - offset = q->qh.bufptr[0] & ~QTD_BUFPTR_MASK; - pci_dma_sglist_init(&q->sgl, &q->ehci->dev, 5); + cpage = get_field(p->qtd.token, QTD_TOKEN_CPAGE); + bytes = get_field(p->qtd.token, QTD_TOKEN_TBYTES); + offset = p->qtd.bufptr[0] & ~QTD_BUFPTR_MASK; + pci_dma_sglist_init(&p->sgl, &p->queue->ehci->dev, 5); while (bytes > 0) { if (cpage > 4) { @@ -1230,7 +1311,7 @@ static int ehci_init_transfer(EHCIQueue *q) return USB_RET_PROCERR; } - page = q->qh.bufptr[cpage] & QTD_BUFPTR_MASK; + page = p->qtd.bufptr[cpage] & QTD_BUFPTR_MASK; page += offset; plen = bytes; if (plen > 4096 - offset) { @@ -1239,7 +1320,7 @@ static int ehci_init_transfer(EHCIQueue *q) cpage++; } - qemu_sglist_add(&q->sgl, page, plen); + qemu_sglist_add(&p->sgl, page, plen); bytes -= plen; } return 0; @@ -1249,8 +1330,6 @@ static void ehci_finish_transfer(EHCIQueue *q, int status) { uint32_t cpage, offset; - qemu_sglist_destroy(&q->sgl); - if (status > 0) { /* update cpage & offset */ cpage = get_field(q->qh.token, QTD_TOKEN_CPAGE); @@ -1268,7 +1347,7 @@ static void ehci_finish_transfer(EHCIQueue *q, int status) static void ehci_async_complete_packet(USBPort *port, USBPacket *packet) { - EHCIQueue *q; + EHCIPacket *p; EHCIState *s = port->opaque; uint32_t portsc = s->portsc[port->index]; @@ -1278,23 +1357,31 @@ static void ehci_async_complete_packet(USBPort *port, USBPacket *packet) return; } - q = container_of(packet, EHCIQueue, packet); - trace_usb_ehci_queue_action(q, "wakeup"); - assert(q->async == EHCI_ASYNC_INFLIGHT); - q->async = EHCI_ASYNC_FINISHED; - q->usb_status = packet->result; + p = container_of(packet, EHCIPacket, packet); + trace_usb_ehci_packet_action(p->queue, p, "wakeup"); + assert(p->async == EHCI_ASYNC_INFLIGHT); + p->async = EHCI_ASYNC_FINISHED; + p->usb_status = packet->result; + + if (p->queue->async) { + qemu_bh_schedule(p->queue->ehci->async_bh); + } } static void ehci_execute_complete(EHCIQueue *q) { - assert(q->async != EHCI_ASYNC_INFLIGHT); - q->async = EHCI_ASYNC_NONE; + EHCIPacket *p = QTAILQ_FIRST(&q->packets); + + assert(p != NULL); + assert(p->qtdaddr == q->qtdaddr); + assert(p->async != EHCI_ASYNC_INFLIGHT); + p->async = EHCI_ASYNC_NONE; DPRINTF("execute_complete: qhaddr 0x%x, next %x, qtdaddr 0x%x, status %d\n", q->qhaddr, q->qh.next, q->qtdaddr, q->usb_status); - if (q->usb_status < 0) { - switch(q->usb_status) { + if (p->usb_status < 0) { + switch (p->usb_status) { case USB_RET_IOERROR: case USB_RET_NODEV: q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_XACTERR); @@ -1314,28 +1401,29 @@ static void ehci_execute_complete(EHCIQueue *q) break; default: /* should not be triggerable */ - fprintf(stderr, "USB invalid response %d to handle\n", q->usb_status); + fprintf(stderr, "USB invalid response %d\n", p->usb_status); assert(0); break; } - } else if ((q->usb_status > q->tbytes) && (q->pid == USB_TOKEN_IN)) { - q->usb_status = USB_RET_BABBLE; + } else if ((p->usb_status > p->tbytes) && (p->pid == USB_TOKEN_IN)) { + p->usb_status = USB_RET_BABBLE; q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_BABBLE); ehci_record_interrupt(q->ehci, USBSTS_ERRINT); } else { // TODO check 4.12 for splits - if (q->tbytes && q->pid == USB_TOKEN_IN) { - q->tbytes -= q->usb_status; + if (p->tbytes && p->pid == USB_TOKEN_IN) { + p->tbytes -= p->usb_status; } else { - q->tbytes = 0; + p->tbytes = 0; } - DPRINTF("updating tbytes to %d\n", q->tbytes); - set_field(&q->qh.token, q->tbytes, QTD_TOKEN_TBYTES); + DPRINTF("updating tbytes to %d\n", p->tbytes); + set_field(&q->qh.token, p->tbytes, QTD_TOKEN_TBYTES); } - ehci_finish_transfer(q, q->usb_status); - usb_packet_unmap(&q->packet); + ehci_finish_transfer(q, p->usb_status); + qemu_sglist_destroy(&p->sgl); + usb_packet_unmap(&p->packet); q->qh.token ^= QTD_TOKEN_DTOGGLE; q->qh.token &= ~QTD_TOKEN_ACTIVE; @@ -1347,48 +1435,51 @@ static void ehci_execute_complete(EHCIQueue *q) // 4.10.3 -static int ehci_execute(EHCIQueue *q) +static int ehci_execute(EHCIPacket *p, const char *action) { - USBDevice *dev; USBEndpoint *ep; int ret; int endp; - int devadr; - if ( !(q->qh.token & QTD_TOKEN_ACTIVE)) { - fprintf(stderr, "Attempting to execute inactive QH\n"); + if (!(p->qtd.token & QTD_TOKEN_ACTIVE)) { + fprintf(stderr, "Attempting to execute inactive qtd\n"); return USB_RET_PROCERR; } - q->tbytes = (q->qh.token & QTD_TOKEN_TBYTES_MASK) >> QTD_TOKEN_TBYTES_SH; - if (q->tbytes > BUFF_SIZE) { + p->tbytes = (p->qtd.token & QTD_TOKEN_TBYTES_MASK) >> QTD_TOKEN_TBYTES_SH; + if (p->tbytes > BUFF_SIZE) { fprintf(stderr, "Request for more bytes than allowed\n"); return USB_RET_PROCERR; } - q->pid = (q->qh.token & QTD_TOKEN_PID_MASK) >> QTD_TOKEN_PID_SH; - switch(q->pid) { - case 0: q->pid = USB_TOKEN_OUT; break; - case 1: q->pid = USB_TOKEN_IN; break; - case 2: q->pid = USB_TOKEN_SETUP; break; - default: fprintf(stderr, "bad token\n"); break; + p->pid = (p->qtd.token & QTD_TOKEN_PID_MASK) >> QTD_TOKEN_PID_SH; + switch (p->pid) { + case 0: + p->pid = USB_TOKEN_OUT; + break; + case 1: + p->pid = USB_TOKEN_IN; + break; + case 2: + p->pid = USB_TOKEN_SETUP; + break; + default: + fprintf(stderr, "bad token\n"); + break; } - if (ehci_init_transfer(q) != 0) { + if (ehci_init_transfer(p) != 0) { return USB_RET_PROCERR; } - endp = get_field(q->qh.epchar, QH_EPCHAR_EP); - devadr = get_field(q->qh.epchar, QH_EPCHAR_DEVADDR); + endp = get_field(p->queue->qh.epchar, QH_EPCHAR_EP); + ep = usb_ep_get(p->queue->dev, p->pid, endp); - /* TODO: associating device with ehci port */ - dev = ehci_find_device(q->ehci, devadr); - ep = usb_ep_get(dev, q->pid, endp); + usb_packet_setup(&p->packet, p->pid, ep); + usb_packet_map(&p->packet, &p->sgl); - usb_packet_setup(&q->packet, q->pid, ep); - usb_packet_map(&q->packet, &q->sgl); - - ret = usb_handle_packet(dev, &q->packet); + trace_usb_ehci_packet_action(p->queue, p, action); + ret = usb_handle_packet(p->queue->dev, &p->packet); DPRINTF("submit: qh %x next %x qtd %x pid %x len %zd " "(total %d) endp %x ret %d\n", q->qhaddr, q->qh.next, q->qtdaddr, q->pid, @@ -1504,6 +1595,24 @@ static int ehci_process_itd(EHCIState *ehci, return 0; } + +/* + * Write the qh back to guest physical memory. This step isn't + * in the EHCI spec but we need to do it since we don't share + * physical memory with our guest VM. + * + * The first three dwords are read-only for the EHCI, so skip them + * when writing back the qh. + */ +static void ehci_flush_qh(EHCIQueue *q) +{ + uint32_t *qh = (uint32_t *) &q->qh; + uint32_t dwords = sizeof(EHCIqh) >> 2; + uint32_t addr = NLPTR_GET(q->qhaddr); + + put_dwords(q->ehci, addr + 3 * sizeof(uint32_t), qh + 3, dwords - 3); +} + /* This state is the entry point for asynchronous schedule * processing. Entry here consitutes a EHCI start event state (4.8.5) */ @@ -1601,17 +1710,18 @@ out: static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async) { - uint32_t entry; + EHCIPacket *p; + uint32_t entry, devaddr; EHCIQueue *q; entry = ehci_get_fetch_addr(ehci, async); q = ehci_find_queue_by_qh(ehci, entry, async); if (NULL == q) { - q = ehci_alloc_queue(ehci, async); + q = ehci_alloc_queue(ehci, entry, async); } - q->qhaddr = entry; - q->seen++; + p = QTAILQ_FIRST(&q->packets); + q->seen++; if (q->seen > 1) { /* we are going in circles -- stop processing */ ehci_set_state(ehci, async, EST_ACTIVE); @@ -1623,14 +1733,28 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async) (uint32_t *) &q->qh, sizeof(EHCIqh) >> 2); ehci_trace_qh(q, NLPTR_GET(q->qhaddr), &q->qh); - if (q->async == EHCI_ASYNC_INFLIGHT) { + devaddr = get_field(q->qh.epchar, QH_EPCHAR_DEVADDR); + if (q->dev != NULL && q->dev->addr != devaddr) { + if (!QTAILQ_EMPTY(&q->packets)) { + /* should not happen (guest bug) */ + while ((p = QTAILQ_FIRST(&q->packets)) != NULL) { + ehci_free_packet(p); + } + } + q->dev = NULL; + } + if (q->dev == NULL) { + q->dev = ehci_find_device(q->ehci, devaddr); + } + + if (p && p->async == EHCI_ASYNC_INFLIGHT) { /* I/O still in progress -- skip queue */ ehci_set_state(ehci, async, EST_HORIZONTALQH); goto out; } - if (q->async == EHCI_ASYNC_FINISHED) { + if (p && p->async == EHCI_ASYNC_FINISHED) { /* I/O finished -- continue processing queue */ - trace_usb_ehci_queue_action(q, "resume"); + trace_usb_ehci_packet_action(p->queue, p, "complete"); ehci_set_state(ehci, async, EST_EXECUTING); goto out; } @@ -1726,7 +1850,7 @@ static int ehci_state_fetchsitd(EHCIState *ehci, int async) } /* Section 4.10.2 - paragraph 3 */ -static int ehci_state_advqueue(EHCIQueue *q, int async) +static int ehci_state_advqueue(EHCIQueue *q) { #if 0 /* TO-DO: 4.10.2 - paragraph 2 @@ -1745,81 +1869,117 @@ static int ehci_state_advqueue(EHCIQueue *q, int async) if (((q->qh.token & QTD_TOKEN_TBYTES_MASK) != 0) && (NLPTR_TBIT(q->qh.altnext_qtd) == 0)) { q->qtdaddr = q->qh.altnext_qtd; - ehci_set_state(q->ehci, async, EST_FETCHQTD); + ehci_set_state(q->ehci, q->async, EST_FETCHQTD); /* * next qTD is valid */ } else if (NLPTR_TBIT(q->qh.next_qtd) == 0) { q->qtdaddr = q->qh.next_qtd; - ehci_set_state(q->ehci, async, EST_FETCHQTD); + ehci_set_state(q->ehci, q->async, EST_FETCHQTD); /* * no valid qTD, try next QH */ } else { - ehci_set_state(q->ehci, async, EST_HORIZONTALQH); + ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); } return 1; } /* Section 4.10.2 - paragraph 4 */ -static int ehci_state_fetchqtd(EHCIQueue *q, int async) +static int ehci_state_fetchqtd(EHCIQueue *q) { + EHCIqtd qtd; + EHCIPacket *p; int again = 0; - get_dwords(q->ehci, NLPTR_GET(q->qtdaddr), (uint32_t *) &q->qtd, + get_dwords(q->ehci, NLPTR_GET(q->qtdaddr), (uint32_t *) &qtd, sizeof(EHCIqtd) >> 2); - ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), &q->qtd); + ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), &qtd); - if (q->qtd.token & QTD_TOKEN_ACTIVE) { - ehci_set_state(q->ehci, async, EST_EXECUTE); + p = QTAILQ_FIRST(&q->packets); + while (p != NULL && p->qtdaddr != q->qtdaddr) { + /* should not happen (guest bug) */ + ehci_free_packet(p); + p = QTAILQ_FIRST(&q->packets); + } + if (p != NULL) { + ehci_qh_do_overlay(q); + ehci_flush_qh(q); + if (p->async == EHCI_ASYNC_INFLIGHT) { + ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); + } else { + ehci_set_state(q->ehci, q->async, EST_EXECUTING); + } + again = 1; + } else if (qtd.token & QTD_TOKEN_ACTIVE) { + p = ehci_alloc_packet(q); + p->qtdaddr = q->qtdaddr; + p->qtd = qtd; + ehci_set_state(q->ehci, q->async, EST_EXECUTE); again = 1; } else { - ehci_set_state(q->ehci, async, EST_HORIZONTALQH); + ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); again = 1; } return again; } -static int ehci_state_horizqh(EHCIQueue *q, int async) +static int ehci_state_horizqh(EHCIQueue *q) { int again = 0; - if (ehci_get_fetch_addr(q->ehci, async) != q->qh.next) { - ehci_set_fetch_addr(q->ehci, async, q->qh.next); - ehci_set_state(q->ehci, async, EST_FETCHENTRY); + if (ehci_get_fetch_addr(q->ehci, q->async) != q->qh.next) { + ehci_set_fetch_addr(q->ehci, q->async, q->qh.next); + ehci_set_state(q->ehci, q->async, EST_FETCHENTRY); again = 1; } else { - ehci_set_state(q->ehci, async, EST_ACTIVE); + ehci_set_state(q->ehci, q->async, EST_ACTIVE); } return again; } -/* - * Write the qh back to guest physical memory. This step isn't - * in the EHCI spec but we need to do it since we don't share - * physical memory with our guest VM. - * - * The first three dwords are read-only for the EHCI, so skip them - * when writing back the qh. - */ -static void ehci_flush_qh(EHCIQueue *q) +static void ehci_fill_queue(EHCIPacket *p) { - uint32_t *qh = (uint32_t *) &q->qh; - uint32_t dwords = sizeof(EHCIqh) >> 2; - uint32_t addr = NLPTR_GET(q->qhaddr); + EHCIQueue *q = p->queue; + EHCIqtd qtd = p->qtd; + uint32_t qtdaddr; - put_dwords(q->ehci, addr + 3 * sizeof(uint32_t), qh + 3, dwords - 3); + for (;;) { + if (NLPTR_TBIT(qtd.altnext) == 0) { + break; + } + if (NLPTR_TBIT(qtd.next) != 0) { + break; + } + qtdaddr = qtd.next; + get_dwords(q->ehci, NLPTR_GET(qtdaddr), + (uint32_t *) &qtd, sizeof(EHCIqtd) >> 2); + ehci_trace_qtd(q, NLPTR_GET(qtdaddr), &qtd); + if (!(qtd.token & QTD_TOKEN_ACTIVE)) { + break; + } + p = ehci_alloc_packet(q); + p->qtdaddr = qtdaddr; + p->qtd = qtd; + p->usb_status = ehci_execute(p, "queue"); + assert(p->usb_status = USB_RET_ASYNC); + p->async = EHCI_ASYNC_INFLIGHT; + } } -static int ehci_state_execute(EHCIQueue *q, int async) +static int ehci_state_execute(EHCIQueue *q) { + EHCIPacket *p = QTAILQ_FIRST(&q->packets); int again = 0; + assert(p != NULL); + assert(p->qtdaddr == q->qtdaddr); + if (ehci_qh_do_overlay(q) != 0) { return -1; } @@ -1828,55 +1988,60 @@ static int ehci_state_execute(EHCIQueue *q, int async) // TODO write back ptr to async list when done or out of time // TODO Windows does not seem to ever set the MULT field - if (!async) { + if (!q->async) { int transactCtr = get_field(q->qh.epcap, QH_EPCAP_MULT); if (!transactCtr) { - ehci_set_state(q->ehci, async, EST_HORIZONTALQH); + ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); again = 1; goto out; } } - if (async) { + if (q->async) { ehci_set_usbsts(q->ehci, USBSTS_REC); } - q->usb_status = ehci_execute(q); - if (q->usb_status == USB_RET_PROCERR) { + p->usb_status = ehci_execute(p, "process"); + if (p->usb_status == USB_RET_PROCERR) { again = -1; goto out; } - if (q->usb_status == USB_RET_ASYNC) { + if (p->usb_status == USB_RET_ASYNC) { ehci_flush_qh(q); - trace_usb_ehci_queue_action(q, "suspend"); - q->async = EHCI_ASYNC_INFLIGHT; - ehci_set_state(q->ehci, async, EST_HORIZONTALQH); + trace_usb_ehci_packet_action(p->queue, p, "async"); + p->async = EHCI_ASYNC_INFLIGHT; + ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); again = 1; + ehci_fill_queue(p); goto out; } - ehci_set_state(q->ehci, async, EST_EXECUTING); + ehci_set_state(q->ehci, q->async, EST_EXECUTING); again = 1; out: return again; } -static int ehci_state_executing(EHCIQueue *q, int async) +static int ehci_state_executing(EHCIQueue *q) { + EHCIPacket *p = QTAILQ_FIRST(&q->packets); int again = 0; + assert(p != NULL); + assert(p->qtdaddr == q->qtdaddr); + ehci_execute_complete(q); - if (q->usb_status == USB_RET_ASYNC) { + if (p->usb_status == USB_RET_ASYNC) { goto out; } - if (q->usb_status == USB_RET_PROCERR) { + if (p->usb_status == USB_RET_PROCERR) { again = -1; goto out; } // 4.10.3 - if (!async) { + if (!q->async) { int transactCtr = get_field(q->qh.epcap, QH_EPCAP_MULT); transactCtr--; set_field(&q->qh.epcap, transactCtr, QH_EPCAP_MULT); @@ -1885,10 +2050,10 @@ static int ehci_state_executing(EHCIQueue *q, int async) } /* 4.10.5 */ - if (q->usb_status == USB_RET_NAK) { - ehci_set_state(q->ehci, async, EST_HORIZONTALQH); + if (p->usb_status == USB_RET_NAK) { + ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); } else { - ehci_set_state(q->ehci, async, EST_WRITEBACK); + ehci_set_state(q->ehci, q->async, EST_WRITEBACK); } again = 1; @@ -1899,14 +2064,19 @@ out: } -static int ehci_state_writeback(EHCIQueue *q, int async) +static int ehci_state_writeback(EHCIQueue *q) { + EHCIPacket *p = QTAILQ_FIRST(&q->packets); int again = 0; /* Write back the QTD from the QH area */ - ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), (EHCIqtd*) &q->qh.next_qtd); - put_dwords(q->ehci, NLPTR_GET(q->qtdaddr), (uint32_t *) &q->qh.next_qtd, + assert(p != NULL); + assert(p->qtdaddr == q->qtdaddr); + + ehci_trace_qtd(q, NLPTR_GET(p->qtdaddr), (EHCIqtd *) &q->qh.next_qtd); + put_dwords(q->ehci, NLPTR_GET(p->qtdaddr), (uint32_t *) &q->qh.next_qtd, sizeof(EHCIqtd) >> 2); + ehci_free_packet(p); /* * EHCI specs say go horizontal here. @@ -1917,10 +2087,10 @@ static int ehci_state_writeback(EHCIQueue *q, int async) * bit is clear. */ if (q->qh.token & QTD_TOKEN_HALT) { - ehci_set_state(q->ehci, async, EST_HORIZONTALQH); + ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); again = 1; } else { - ehci_set_state(q->ehci, async, EST_ADVANCEQUEUE); + ehci_set_state(q->ehci, q->async, EST_ADVANCEQUEUE); again = 1; } return again; @@ -1930,8 +2100,7 @@ static int ehci_state_writeback(EHCIQueue *q, int async) * This is the state machine that is common to both async and periodic */ -static void ehci_advance_state(EHCIState *ehci, - int async) +static void ehci_advance_state(EHCIState *ehci, int async) { EHCIQueue *q = NULL; int again; @@ -1948,7 +2117,12 @@ static void ehci_advance_state(EHCIState *ehci, case EST_FETCHQH: q = ehci_state_fetchqh(ehci, async); - again = q ? 1 : 0; + if (q != NULL) { + assert(q->async == async); + again = 1; + } else { + again = 0; + } break; case EST_FETCHITD: @@ -1960,29 +2134,35 @@ static void ehci_advance_state(EHCIState *ehci, break; case EST_ADVANCEQUEUE: - again = ehci_state_advqueue(q, async); + again = ehci_state_advqueue(q); break; case EST_FETCHQTD: - again = ehci_state_fetchqtd(q, async); + again = ehci_state_fetchqtd(q); break; case EST_HORIZONTALQH: - again = ehci_state_horizqh(q, async); + again = ehci_state_horizqh(q); break; case EST_EXECUTE: - again = ehci_state_execute(q, async); + again = ehci_state_execute(q); + if (async) { + ehci->async_stepdown = 0; + } break; case EST_EXECUTING: assert(q != NULL); - again = ehci_state_executing(q, async); + if (async) { + ehci->async_stepdown = 0; + } + again = ehci_state_executing(q); break; case EST_WRITEBACK: assert(q != NULL); - again = ehci_state_writeback(q, async); + again = ehci_state_writeback(q); break; default: @@ -2009,17 +2189,15 @@ static void ehci_advance_async_state(EHCIState *ehci) switch(ehci_get_state(ehci, async)) { case EST_INACTIVE: - if (!(ehci->usbcmd & USBCMD_ASE)) { + if (!ehci_async_enabled(ehci)) { break; } - ehci_set_usbsts(ehci, USBSTS_ASS); ehci_set_state(ehci, async, EST_ACTIVE); // No break, fall through to ACTIVE case EST_ACTIVE: - if ( !(ehci->usbcmd & USBCMD_ASE)) { + if (!ehci_async_enabled(ehci)) { ehci_queues_rip_all(ehci, async); - ehci_clear_usbsts(ehci, USBSTS_ASS); ehci_set_state(ehci, async, EST_INACTIVE); break; } @@ -2070,17 +2248,15 @@ static void ehci_advance_periodic_state(EHCIState *ehci) switch(ehci_get_state(ehci, async)) { case EST_INACTIVE: - if ( !(ehci->frindex & 7) && (ehci->usbcmd & USBCMD_PSE)) { - ehci_set_usbsts(ehci, USBSTS_PSS); + if (!(ehci->frindex & 7) && ehci_periodic_enabled(ehci)) { ehci_set_state(ehci, async, EST_ACTIVE); // No break, fall through to ACTIVE } else break; case EST_ACTIVE: - if ( !(ehci->frindex & 7) && !(ehci->usbcmd & USBCMD_PSE)) { + if (!(ehci->frindex & 7) && !ehci_periodic_enabled(ehci)) { ehci_queues_rip_all(ehci, async); - ehci_clear_usbsts(ehci, USBSTS_PSS); ehci_set_state(ehci, async, EST_INACTIVE); break; } @@ -2111,58 +2287,86 @@ static void ehci_advance_periodic_state(EHCIState *ehci) } } +static void ehci_update_frindex(EHCIState *ehci, int frames) +{ + int i; + + if (!ehci_enabled(ehci)) { + return; + } + + for (i = 0; i < frames; i++) { + ehci->frindex += 8; + + if (ehci->frindex == 0x00002000) { + ehci_set_interrupt(ehci, USBSTS_FLR); + } + + if (ehci->frindex == 0x00004000) { + ehci_set_interrupt(ehci, USBSTS_FLR); + ehci->frindex = 0; + } + } +} + static void ehci_frame_timer(void *opaque) { EHCIState *ehci = opaque; + int schedules = 0; int64_t expire_time, t_now; uint64_t ns_elapsed; - int frames; + int frames, skipped_frames; int i; - int skipped_frames = 0; t_now = qemu_get_clock_ns(vm_clock); - expire_time = t_now + (get_ticks_per_sec() / ehci->freq); - ns_elapsed = t_now - ehci->last_run_ns; frames = ns_elapsed / FRAME_TIMER_NS; - for (i = 0; i < frames; i++) { - if ( !(ehci->usbsts & USBSTS_HALT)) { - ehci->frindex += 8; - - if (ehci->frindex == 0x00002000) { - ehci_set_interrupt(ehci, USBSTS_FLR); - } + if (ehci_periodic_enabled(ehci) || ehci->pstate != EST_INACTIVE) { + schedules++; + expire_time = t_now + (get_ticks_per_sec() / FRAME_TIMER_FREQ); - if (ehci->frindex == 0x00004000) { - ehci_set_interrupt(ehci, USBSTS_FLR); - ehci->frindex = 0; - } + if (frames > ehci->maxframes) { + skipped_frames = frames - ehci->maxframes; + ehci_update_frindex(ehci, skipped_frames); + ehci->last_run_ns += FRAME_TIMER_NS * skipped_frames; + frames -= skipped_frames; + DPRINTF("WARNING - EHCI skipped %d frames\n", skipped_frames); } - if (frames - i > ehci->maxframes) { - skipped_frames++; - } else { + for (i = 0; i < frames; i++) { + ehci_update_frindex(ehci, 1); ehci_advance_periodic_state(ehci); + ehci->last_run_ns += FRAME_TIMER_NS; } - - ehci->last_run_ns += FRAME_TIMER_NS; - } - -#if 0 - if (skipped_frames) { - DPRINTF("WARNING - EHCI skipped %d frames\n", skipped_frames); + } else { + if (ehci->async_stepdown < ehci->maxframes / 2) { + ehci->async_stepdown++; + } + expire_time = t_now + (get_ticks_per_sec() + * ehci->async_stepdown / FRAME_TIMER_FREQ); + ehci_update_frindex(ehci, frames); + ehci->last_run_ns += FRAME_TIMER_NS * frames; } -#endif /* Async is not inside loop since it executes everything it can once * called */ - ehci_advance_async_state(ehci); + if (ehci_async_enabled(ehci) || ehci->astate != EST_INACTIVE) { + schedules++; + qemu_bh_schedule(ehci->async_bh); + } - qemu_mod_timer(ehci->frame_timer, expire_time); + if (schedules) { + qemu_mod_timer(ehci->frame_timer, expire_time); + } } +static void ehci_async_bh(void *opaque) +{ + EHCIState *ehci = opaque; + ehci_advance_async_state(ehci); +} static const MemoryRegionOps ehci_mem_ops = { .old_mmio = { @@ -2192,7 +2396,6 @@ static const VMStateDescription vmstate_ehci = { }; static Property ehci_properties[] = { - DEFINE_PROP_UINT32("freq", EHCIState, freq, FRAME_TIMER_FREQ), DEFINE_PROP_UINT32("maxframes", EHCIState, maxframes, 128), DEFINE_PROP_END_OF_LIST(), }; @@ -2298,6 +2501,7 @@ static int usb_ehci_initfn(PCIDevice *dev) } s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s); + s->async_bh = qemu_bh_new(ehci_async_bh, s); QTAILQ_INIT(&s->aqueues); QTAILQ_INIT(&s->pqueues); diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index 9e211a0bb4..9871e24f50 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -131,10 +131,14 @@ struct UHCIState { uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */ int64_t expire_time; QEMUTimer *frame_timer; + QEMUBH *bh; + uint32_t frame_bytes; + uint32_t frame_bandwidth; UHCIPort ports[NB_PORTS]; /* Interrupts that should be raised at the end of the current frame. */ uint32_t pending_int_mask; + int irq_pin; /* Active packets */ QTAILQ_HEAD(, UHCIQueue) queues; @@ -337,7 +341,7 @@ static void uhci_update_irq(UHCIState *s) } else { level = 0; } - qemu_set_irq(s->dev.irq[3], level); + qemu_set_irq(s->dev.irq[s->irq_pin], level); } static void uhci_reset(void *opaque) @@ -369,16 +373,10 @@ static void uhci_reset(void *opaque) } uhci_async_cancel_all(s); + qemu_bh_cancel(s->bh); uhci_update_irq(s); } -static void uhci_pre_save(void *opaque) -{ - UHCIState *s = opaque; - - uhci_async_cancel_all(s); -} - static const VMStateDescription vmstate_uhci_port = { .name = "uhci port", .version_id = 1, @@ -395,7 +393,6 @@ static const VMStateDescription vmstate_uhci = { .version_id = 2, .minimum_version_id = 1, .minimum_version_id_old = 1, - .pre_save = uhci_pre_save, .fields = (VMStateField []) { VMSTATE_PCI_DEVICE(dev, UHCIState), VMSTATE_UINT8_EQUAL(num_ports_vmstate, UHCIState), @@ -905,7 +902,9 @@ static void uhci_async_complete(USBPort *port, USBPacket *packet) uhci_async_free(async); } else { async->done = 1; - uhci_process_frame(s); + if (s->frame_bytes < s->frame_bandwidth) { + qemu_bh_schedule(s->bh); + } } } @@ -985,7 +984,7 @@ static void uhci_fill_queue(UHCIState *s, UHCI_TD *td) static void uhci_process_frame(UHCIState *s) { uint32_t frame_addr, link, old_td_ctrl, val, int_mask; - uint32_t curr_qh, td_count = 0, bytes_count = 0; + uint32_t curr_qh, td_count = 0; int cnt, ret; UHCI_TD td; UHCI_QH qh; @@ -1002,6 +1001,12 @@ static void uhci_process_frame(UHCIState *s) qhdb_reset(&qhdb); for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) { + if (s->frame_bytes >= s->frame_bandwidth) { + /* We've reached the usb 1.1 bandwidth, which is + 1280 bytes/frame, stop processing */ + trace_usb_uhci_frame_stop_bandwidth(); + break; + } if (is_qh(link)) { /* QH */ trace_usb_uhci_qh_load(link & ~0xf); @@ -1011,18 +1016,12 @@ static void uhci_process_frame(UHCIState *s) * We're going in circles. Which is not a bug because * HCD is allowed to do that as part of the BW management. * - * Stop processing here if - * (a) no transaction has been done since we've been - * here last time, or - * (b) we've reached the usb 1.1 bandwidth, which is - * 1280 bytes/frame. + * Stop processing here if no transaction has been done + * since we've been here last time. */ if (td_count == 0) { trace_usb_uhci_frame_loop_stop_idle(); break; - } else if (bytes_count >= 1280) { - trace_usb_uhci_frame_loop_stop_bandwidth(); - break; } else { trace_usb_uhci_frame_loop_continue(); td_count = 0; @@ -1085,7 +1084,7 @@ static void uhci_process_frame(UHCIState *s) trace_usb_uhci_td_complete(curr_qh & ~0xf, link & ~0xf); link = td.link; td_count++; - bytes_count += (td.ctrl & 0x7ff) + 1; + s->frame_bytes += (td.ctrl & 0x7ff) + 1; if (curr_qh) { /* update QH element link */ @@ -1112,12 +1111,20 @@ out: s->pending_int_mask |= int_mask; } +static void uhci_bh(void *opaque) +{ + UHCIState *s = opaque; + uhci_process_frame(s); +} + static void uhci_frame_timer(void *opaque) { UHCIState *s = opaque; /* prepare the timer for the next frame */ s->expire_time += (get_ticks_per_sec() / FRAME_TIMER_FREQ); + s->frame_bytes = 0; + qemu_bh_cancel(s->bh); if (!(s->cmd & UHCI_CMD_RS)) { /* Full stop */ @@ -1178,15 +1185,31 @@ static USBBusOps uhci_bus_ops = { static int usb_uhci_common_initfn(PCIDevice *dev) { + PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); UHCIState *s = DO_UPCAST(UHCIState, dev, dev); uint8_t *pci_conf = s->dev.config; int i; pci_conf[PCI_CLASS_PROG] = 0x00; /* TODO: reset value should be 0. */ - pci_conf[PCI_INTERRUPT_PIN] = 4; /* interrupt pin D */ pci_conf[USB_SBRN] = USB_RELEASE_1; // release number + switch (pc->device_id) { + case PCI_DEVICE_ID_INTEL_82801I_UHCI1: + s->irq_pin = 0; /* A */ + break; + case PCI_DEVICE_ID_INTEL_82801I_UHCI2: + s->irq_pin = 1; /* B */ + break; + case PCI_DEVICE_ID_INTEL_82801I_UHCI3: + s->irq_pin = 2; /* C */ + break; + default: + s->irq_pin = 3; /* D */ + break; + } + pci_config_set_interrupt_pin(pci_conf, s->irq_pin + 1); + if (s->masterbus) { USBPort *ports[NB_PORTS]; for(i = 0; i < NB_PORTS; i++) { @@ -1204,6 +1227,7 @@ static int usb_uhci_common_initfn(PCIDevice *dev) USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); } } + s->bh = qemu_bh_new(uhci_bh, s); s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s); s->num_ports_vmstate = NB_PORTS; QTAILQ_INIT(&s->queues); @@ -1244,6 +1268,7 @@ static int usb_uhci_exit(PCIDevice *dev) static Property uhci_properties[] = { DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), + DEFINE_PROP_UINT32("bandwidth", UHCIState, frame_bandwidth, 1280), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 5cf1a64699..6c2ff024e0 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -23,6 +23,7 @@ #include "hw/usb.h" #include "hw/pci.h" #include "hw/msi.h" +#include "trace.h" //#define DEBUG_XHCI //#define DEBUG_DATA @@ -421,7 +422,6 @@ typedef struct XHCIEvRingSeg { uint32_t rsvd; } XHCIEvRingSeg; -#ifdef DEBUG_XHCI static const char *TRBType_names[] = { [TRB_RESERVED] = "TRB_RESERVED", [TR_NORMAL] = "TR_NORMAL", @@ -473,7 +473,6 @@ static const char *trb_name(XHCITRB *trb) return lookup_name(TRB_TYPE(*trb), TRBType_names, ARRAY_SIZE(TRBType_names)); } -#endif static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid); @@ -505,14 +504,13 @@ static void xhci_irq_update(XHCIState *xhci) level = 1; } - DPRINTF("xhci_irq_update(): %d\n", level); - if (xhci->msi && msi_enabled(&xhci->pci_dev)) { if (level) { - DPRINTF("xhci_irq_update(): MSI signal\n"); + trace_usb_xhci_irq_msi(0); msi_notify(&xhci->pci_dev, 0); } } else { + trace_usb_xhci_irq_intx(level); qemu_set_irq(xhci->irq, level); } } @@ -542,9 +540,8 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event) } ev_trb.control = cpu_to_le32(ev_trb.control); - DPRINTF("xhci_write_event(): [%d] %016"PRIx64" %08x %08x %s\n", - xhci->er_ep_idx, ev_trb.parameter, ev_trb.status, ev_trb.control, - trb_name(&ev_trb)); + trace_usb_xhci_queue_event(xhci->er_ep_idx, trb_name(&ev_trb), + ev_trb.parameter, ev_trb.status, ev_trb.control); addr = xhci->er_start + TRB_SIZE*xhci->er_ep_idx; pci_dma_write(&xhci->pci_dev, addr, &ev_trb, TRB_SIZE); @@ -704,10 +701,8 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb, le32_to_cpus(&trb->status); le32_to_cpus(&trb->control); - DPRINTF("xhci: TRB fetched [" DMA_ADDR_FMT "]: " - "%016" PRIx64 " %08x %08x %s\n", - ring->dequeue, trb->parameter, trb->status, trb->control, - trb_name(trb)); + trace_usb_xhci_fetch_trb(ring->dequeue, trb_name(trb), + trb->parameter, trb->status, trb->control); if ((trb->control & TRB_C) != ring->ccs) { return 0; @@ -746,10 +741,6 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) le32_to_cpus(&trb.status); le32_to_cpus(&trb.control); - DPRINTF("xhci: TRB peeked [" DMA_ADDR_FMT "]: " - "%016" PRIx64 " %08x %08x\n", - dequeue, trb.parameter, trb.status, trb.control); - if ((trb.control & TRB_C) != ccs) { return -length; } @@ -812,14 +803,13 @@ static void xhci_er_reset(XHCIState *xhci) static void xhci_run(XHCIState *xhci) { - DPRINTF("xhci_run()\n"); - + trace_usb_xhci_run(); xhci->usbsts &= ~USBSTS_HCH; } static void xhci_stop(XHCIState *xhci) { - DPRINTF("xhci_stop()\n"); + trace_usb_xhci_stop(); xhci->usbsts |= USBSTS_HCH; xhci->crcr_low &= ~CRCR_CRR; } @@ -852,11 +842,10 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid, dma_addr_t dequeue; int i; + trace_usb_xhci_ep_enable(slotid, epid); assert(slotid >= 1 && slotid <= MAXSLOTS); assert(epid >= 1 && epid <= 31); - DPRINTF("xhci_enable_ep(%d, %d)\n", slotid, epid); - slot = &xhci->slots[slotid-1]; if (slot->eps[epid-1]) { fprintf(stderr, "xhci: slot %d ep %d already enabled!\n", slotid, epid); @@ -971,11 +960,10 @@ static TRBCCode xhci_disable_ep(XHCIState *xhci, unsigned int slotid, XHCISlot *slot; XHCIEPContext *epctx; + trace_usb_xhci_ep_disable(slotid, epid); assert(slotid >= 1 && slotid <= MAXSLOTS); assert(epid >= 1 && epid <= 31); - DPRINTF("xhci_disable_ep(%d, %d)\n", slotid, epid); - slot = &xhci->slots[slotid-1]; if (!slot->eps[epid-1]) { @@ -1001,8 +989,7 @@ static TRBCCode xhci_stop_ep(XHCIState *xhci, unsigned int slotid, XHCISlot *slot; XHCIEPContext *epctx; - DPRINTF("xhci_stop_ep(%d, %d)\n", slotid, epid); - + trace_usb_xhci_ep_stop(slotid, epid); assert(slotid >= 1 && slotid <= MAXSLOTS); if (epid < 1 || epid > 31) { @@ -1036,10 +1023,9 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid, XHCIEPContext *epctx; USBDevice *dev; + trace_usb_xhci_ep_reset(slotid, epid); assert(slotid >= 1 && slotid <= MAXSLOTS); - DPRINTF("xhci_reset_ep(%d, %d)\n", slotid, epid); - if (epid < 1 || epid > 31) { fprintf(stderr, "xhci: bad ep %d\n", epid); return CC_TRB_ERROR; @@ -1416,12 +1402,14 @@ static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev) static int xhci_complete_packet(XHCITransfer *xfer, int ret) { if (ret == USB_RET_ASYNC) { + trace_usb_xhci_xfer_async(xfer); xfer->running_async = 1; xfer->running_retry = 0; xfer->complete = 0; xfer->cancelled = 0; return 0; } else if (ret == USB_RET_NAK) { + trace_usb_xhci_xfer_nak(xfer); xfer->running_async = 0; xfer->running_retry = 1; xfer->complete = 0; @@ -1436,10 +1424,12 @@ static int xhci_complete_packet(XHCITransfer *xfer, int ret) if (ret >= 0) { xfer->status = CC_SUCCESS; xhci_xfer_data(xfer, xfer->data, ret, xfer->in_xfer, 0, 1); + trace_usb_xhci_xfer_success(xfer, ret); return 0; } /* error */ + trace_usb_xhci_xfer_error(xfer, ret); switch (ret) { case USB_RET_NODEV: xfer->status = CC_USB_TRANSACTION_ERROR; @@ -1475,11 +1465,12 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) USBDevice *dev; int ret; - DPRINTF("xhci_fire_ctl_transfer(slot=%d)\n", xfer->slotid); - trb_setup = &xfer->trbs[0]; trb_status = &xfer->trbs[xfer->trb_count-1]; + trace_usb_xhci_xfer_start(xfer, xfer->slotid, xfer->epid, + trb_setup->parameter >> 48); + /* at most one Event Data TRB allowed after STATUS */ if (TRB_TYPE(*trb_status) == TR_EVDATA && xfer->trb_count > 2) { trb_status--; @@ -1620,15 +1611,14 @@ static int xhci_fire_transfer(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext unsigned int length = 0; XHCITRB *trb; - DPRINTF("xhci_fire_transfer(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid); - for (i = 0; i < xfer->trb_count; i++) { trb = &xfer->trbs[i]; if (TRB_TYPE(*trb) == TR_NORMAL || TRB_TYPE(*trb) == TR_ISOCH) { length += trb->status & 0x1ffff; } } - DPRINTF("xhci: total TD length=%d\n", length); + + trace_usb_xhci_xfer_start(xfer, xfer->slotid, xfer->epid, length); if (!epctx->has_bg) { xfer->data_length = length; @@ -1664,9 +1654,9 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid int length; int i; + trace_usb_xhci_ep_kick(slotid, epid); assert(slotid >= 1 && slotid <= MAXSLOTS); assert(epid >= 1 && epid <= 31); - DPRINTF("xhci_kick_ep(%d, %d)\n", slotid, epid); if (!xhci->slots[slotid-1].enabled) { fprintf(stderr, "xhci: xhci_kick_ep for disabled slot %d\n", slotid); @@ -1684,15 +1674,13 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid XHCITransfer *xfer = epctx->retry; int result; - DPRINTF("xhci: retry nack'ed transfer ...\n"); + trace_usb_xhci_xfer_retry(xfer); assert(xfer->running_retry); xhci_setup_packet(xfer, xfer->packet.ep->dev); result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); if (result == USB_RET_NAK) { - DPRINTF("xhci: ... xfer still nacked\n"); return; } - DPRINTF("xhci: ... result %d\n", result); xhci_complete_packet(xfer, result); assert(!xfer->running_retry); epctx->retry = NULL; @@ -1708,21 +1696,14 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid while (1) { XHCITransfer *xfer = &epctx->transfers[epctx->next_xfer]; if (xfer->running_async || xfer->running_retry || xfer->backgrounded) { - DPRINTF("xhci: ep is busy (#%d,%d,%d,%d)\n", - epctx->next_xfer, xfer->running_async, - xfer->running_retry, xfer->backgrounded); break; - } else { - DPRINTF("xhci: ep: using #%d\n", epctx->next_xfer); } length = xhci_ring_chain_length(xhci, &epctx->ring); if (length < 0) { - DPRINTF("xhci: incomplete TD (%d TRBs)\n", -length); break; } else if (length == 0) { break; } - DPRINTF("xhci: fetching %d-TRB TD\n", length); if (xfer->trbs && xfer->trb_alloced < length) { xfer->trb_count = 0; xfer->trb_alloced = 0; @@ -1757,7 +1738,6 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid } if (epctx->state == EP_HALTED) { - DPRINTF("xhci: ep halted, stopping schedule\n"); break; } if (xfer->running_retry) { @@ -1770,8 +1750,8 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid static TRBCCode xhci_enable_slot(XHCIState *xhci, unsigned int slotid) { + trace_usb_xhci_slot_enable(slotid); assert(slotid >= 1 && slotid <= MAXSLOTS); - DPRINTF("xhci_enable_slot(%d)\n", slotid); xhci->slots[slotid-1].enabled = 1; xhci->slots[slotid-1].port = 0; memset(xhci->slots[slotid-1].eps, 0, sizeof(XHCIEPContext*)*31); @@ -1783,8 +1763,8 @@ static TRBCCode xhci_disable_slot(XHCIState *xhci, unsigned int slotid) { int i; + trace_usb_xhci_slot_disable(slotid); assert(slotid >= 1 && slotid <= MAXSLOTS); - DPRINTF("xhci_disable_slot(%d)\n", slotid); for (i = 1; i <= 31; i++) { if (xhci->slots[slotid-1].eps[i-1]) { @@ -1810,8 +1790,8 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid, int i; TRBCCode res; + trace_usb_xhci_slot_address(slotid); assert(slotid >= 1 && slotid <= MAXSLOTS); - DPRINTF("xhci_address_slot(%d)\n", slotid); dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high); pci_dma_read(&xhci->pci_dev, dcbaap + 8*slotid, &poctx, sizeof(poctx)); @@ -1897,8 +1877,8 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid, int i; TRBCCode res; + trace_usb_xhci_slot_configure(slotid); assert(slotid >= 1 && slotid <= MAXSLOTS); - DPRINTF("xhci_configure_slot(%d)\n", slotid); ictx = xhci_mask64(pictx); octx = xhci->slots[slotid-1].ctx; @@ -1985,8 +1965,8 @@ static TRBCCode xhci_evaluate_slot(XHCIState *xhci, unsigned int slotid, uint32_t islot_ctx[4]; uint32_t slot_ctx[4]; + trace_usb_xhci_slot_evaluate(slotid); assert(slotid >= 1 && slotid <= MAXSLOTS); - DPRINTF("xhci_evaluate_slot(%d)\n", slotid); ictx = xhci_mask64(pictx); octx = xhci->slots[slotid-1].ctx; @@ -2048,8 +2028,8 @@ static TRBCCode xhci_reset_slot(XHCIState *xhci, unsigned int slotid) dma_addr_t octx; int i; + trace_usb_xhci_slot_reset(slotid); assert(slotid >= 1 && slotid <= MAXSLOTS); - DPRINTF("xhci_reset_slot(%d)\n", slotid); octx = xhci->slots[slotid-1].ctx; @@ -2296,12 +2276,12 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach) } } -static void xhci_reset(void *opaque) +static void xhci_reset(DeviceState *dev) { - XHCIState *xhci = opaque; + XHCIState *xhci = DO_UPCAST(XHCIState, pci_dev.qdev, dev); int i; - DPRINTF("xhci: full reset\n"); + trace_usb_xhci_reset(); if (!(xhci->usbsts & USBSTS_HCH)) { fprintf(stderr, "xhci: reset while running!\n"); } @@ -2342,77 +2322,98 @@ static void xhci_reset(void *opaque) static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) { - DPRINTF("xhci_cap_read(0x%x)\n", reg); + uint32_t ret; switch (reg) { case 0x00: /* HCIVERSION, CAPLENGTH */ - return 0x01000000 | LEN_CAP; + ret = 0x01000000 | LEN_CAP; + break; case 0x04: /* HCSPARAMS 1 */ - return (MAXPORTS<<24) | (MAXINTRS<<8) | MAXSLOTS; + ret = (MAXPORTS<<24) | (MAXINTRS<<8) | MAXSLOTS; + break; case 0x08: /* HCSPARAMS 2 */ - return 0x0000000f; + ret = 0x0000000f; + break; case 0x0c: /* HCSPARAMS 3 */ - return 0x00000000; + ret = 0x00000000; + break; case 0x10: /* HCCPARAMS */ -#if TARGET_PHYS_ADDR_BITS > 32 - return 0x00081001; -#else - return 0x00081000; -#endif + if (sizeof(dma_addr_t) == 4) { + ret = 0x00081000; + } else { + ret = 0x00081001; + } + break; case 0x14: /* DBOFF */ - return OFF_DOORBELL; + ret = OFF_DOORBELL; + break; case 0x18: /* RTSOFF */ - return OFF_RUNTIME; + ret = OFF_RUNTIME; + break; /* extended capabilities */ case 0x20: /* Supported Protocol:00 */ -#if USB3_PORTS > 0 - return 0x02000402; /* USB 2.0 */ -#else - return 0x02000002; /* USB 2.0 */ -#endif + ret = 0x02000402; /* USB 2.0 */ + break; case 0x24: /* Supported Protocol:04 */ - return 0x20425455; /* "USB " */ + ret = 0x20425455; /* "USB " */ + break; case 0x28: /* Supported Protocol:08 */ - return 0x00000001 | (USB2_PORTS<<8); + ret = 0x00000001 | (USB2_PORTS<<8); + break; case 0x2c: /* Supported Protocol:0c */ - return 0x00000000; /* reserved */ -#if USB3_PORTS > 0 + ret = 0x00000000; /* reserved */ + break; case 0x30: /* Supported Protocol:00 */ - return 0x03000002; /* USB 3.0 */ + ret = 0x03000002; /* USB 3.0 */ + break; case 0x34: /* Supported Protocol:04 */ - return 0x20425455; /* "USB " */ + ret = 0x20425455; /* "USB " */ + break; case 0x38: /* Supported Protocol:08 */ - return 0x00000000 | (USB2_PORTS+1) | (USB3_PORTS<<8); + ret = 0x00000000 | (USB2_PORTS+1) | (USB3_PORTS<<8); + break; case 0x3c: /* Supported Protocol:0c */ - return 0x00000000; /* reserved */ -#endif + ret = 0x00000000; /* reserved */ + break; default: fprintf(stderr, "xhci_cap_read: reg %d unimplemented\n", reg); + ret = 0; } - return 0; + + trace_usb_xhci_cap_read(reg, ret); + return ret; } static uint32_t xhci_port_read(XHCIState *xhci, uint32_t reg) { uint32_t port = reg >> 4; + uint32_t ret; + if (port >= MAXPORTS) { fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port); - return 0; + ret = 0; + goto out; } switch (reg & 0xf) { case 0x00: /* PORTSC */ - return xhci->ports[port].portsc; + ret = xhci->ports[port].portsc; + break; case 0x04: /* PORTPMSC */ case 0x08: /* PORTLI */ - return 0; + ret = 0; + break; case 0x0c: /* reserved */ default: fprintf(stderr, "xhci_port_read (port %d): reg 0x%x unimplemented\n", port, reg); - return 0; + ret = 0; } + +out: + trace_usb_xhci_port_read(port, reg & 0x0f, ret); + return ret; } static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val) @@ -2420,6 +2421,8 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val) uint32_t port = reg >> 4; uint32_t portsc; + trace_usb_xhci_port_write(port, reg & 0x0f, val); + if (port >= MAXPORTS) { fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port); return; @@ -2457,7 +2460,7 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val) static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg) { - DPRINTF("xhci_oper_read(0x%x)\n", reg); + uint32_t ret; if (reg >= 0x400) { return xhci_port_read(xhci, reg - 0x400); @@ -2465,38 +2468,50 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg) switch (reg) { case 0x00: /* USBCMD */ - return xhci->usbcmd; + ret = xhci->usbcmd; + break; case 0x04: /* USBSTS */ - return xhci->usbsts; + ret = xhci->usbsts; + break; case 0x08: /* PAGESIZE */ - return 1; /* 4KiB */ + ret = 1; /* 4KiB */ + break; case 0x14: /* DNCTRL */ - return xhci->dnctrl; + ret = xhci->dnctrl; + break; case 0x18: /* CRCR low */ - return xhci->crcr_low & ~0xe; + ret = xhci->crcr_low & ~0xe; + break; case 0x1c: /* CRCR high */ - return xhci->crcr_high; + ret = xhci->crcr_high; + break; case 0x30: /* DCBAAP low */ - return xhci->dcbaap_low; + ret = xhci->dcbaap_low; + break; case 0x34: /* DCBAAP high */ - return xhci->dcbaap_high; + ret = xhci->dcbaap_high; + break; case 0x38: /* CONFIG */ - return xhci->config; + ret = xhci->config; + break; default: fprintf(stderr, "xhci_oper_read: reg 0x%x unimplemented\n", reg); + ret = 0; } - return 0; + + trace_usb_xhci_oper_read(reg, ret); + return ret; } static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) { - DPRINTF("xhci_oper_write(0x%x, 0x%08x)\n", reg, val); - if (reg >= 0x400) { xhci_port_write(xhci, reg - 0x400, val); return; } + trace_usb_xhci_oper_write(reg, val); + switch (reg) { case 0x00: /* USBCMD */ if ((val & USBCMD_RS) && !(xhci->usbcmd & USBCMD_RS)) { @@ -2506,7 +2521,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) } xhci->usbcmd = val & 0xc0f; if (val & USBCMD_HCRST) { - xhci_reset(xhci); + xhci_reset(&xhci->pci_dev.qdev); } xhci_irq_update(xhci); break; @@ -2552,35 +2567,46 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) { - DPRINTF("xhci_runtime_read(0x%x)\n", reg); + uint32_t ret; switch (reg) { case 0x00: /* MFINDEX */ fprintf(stderr, "xhci_runtime_read: MFINDEX not yet implemented\n"); - return xhci->mfindex; + ret = xhci->mfindex; + break; case 0x20: /* IMAN */ - return xhci->iman; + ret = xhci->iman; + break; case 0x24: /* IMOD */ - return xhci->imod; + ret = xhci->imod; + break; case 0x28: /* ERSTSZ */ - return xhci->erstsz; + ret = xhci->erstsz; + break; case 0x30: /* ERSTBA low */ - return xhci->erstba_low; + ret = xhci->erstba_low; + break; case 0x34: /* ERSTBA high */ - return xhci->erstba_high; + ret = xhci->erstba_high; + break; case 0x38: /* ERDP low */ - return xhci->erdp_low; + ret = xhci->erdp_low; + break; case 0x3c: /* ERDP high */ - return xhci->erdp_high; + ret = xhci->erdp_high; + break; default: fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg); + ret = 0; } - return 0; + + trace_usb_xhci_runtime_read(reg, ret); + return ret; } static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) { - DPRINTF("xhci_runtime_write(0x%x, 0x%08x)\n", reg, val); + trace_usb_xhci_runtime_read(reg, val); switch (reg) { case 0x20: /* IMAN */ @@ -2623,14 +2649,14 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) static uint32_t xhci_doorbell_read(XHCIState *xhci, uint32_t reg) { - DPRINTF("xhci_doorbell_read(0x%x)\n", reg); /* doorbells always read as 0 */ + trace_usb_xhci_doorbell_read(reg, 0); return 0; } static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val) { - DPRINTF("xhci_doorbell_write(0x%x, 0x%08x)\n", reg, val); + trace_usb_xhci_doorbell_write(reg, val); if (!xhci_running(xhci)) { fprintf(stderr, "xhci: wrote doorbell while xHC stopped or paused\n"); @@ -2831,8 +2857,6 @@ static void usb_xhci_init(XHCIState *xhci, DeviceState *dev) for (i = 0; i < MAXSLOTS; i++) { xhci->slots[i].enabled = 0; } - - qemu_register_reset(xhci_reset, xhci); } static int usb_xhci_initfn(struct PCIDevice *dev) @@ -2895,6 +2919,7 @@ static void xhci_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_xhci; dc->props = xhci_properties; + dc->reset = xhci_reset; k->init = usb_xhci_initfn; k->vendor_id = PCI_VENDOR_ID_NEC; k->device_id = PCI_DEVICE_ID_NEC_UPD720200; diff --git a/hw/xtensa/Makefile.objs b/hw/xtensa/Makefile.objs new file mode 100644 index 0000000000..79698e903d --- /dev/null +++ b/hw/xtensa/Makefile.objs @@ -0,0 +1,5 @@ +obj-y += xtensa_pic.o +obj-y += xtensa_sim.o +obj-y += xtensa_lx60.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/libcacard/Makefile b/libcacard/Makefile index c6a896a739..fdc287370d 100644 --- a/libcacard/Makefile +++ b/libcacard/Makefile @@ -2,29 +2,23 @@ -include $(SRC_PATH)/Makefile.objs -include $(SRC_PATH)/rules.mak -libcacard_srcpath=$(SRC_PATH)/libcacard libcacard_includedir=$(includedir)/cacard -$(call set-vpath, $(SRC_PATH):$(libcacard_srcpath)) - -# objects linked against normal qemu binaries, not compiled with libtool -QEMU_OBJS=$(addprefix ../,$(oslib-obj-y) qemu-timer-common.o $(trace-obj-y)) +$(call set-vpath, $(SRC_PATH)) # objects linked into a shared library, built with libtool with -fPIC if required -QEMU_OBJS_LIB=$(addsuffix .lo,$(basename $(QEMU_OBJS))) +QEMU_OBJS=$(oslib-obj-y) qemu-timer-common.o $(trace-obj-y) +QEMU_OBJS_LIB=$(patsubst %.o,%.lo,$(QEMU_OBJS)) QEMU_CFLAGS+=-I../ -libcacard.lib-y=$(addsuffix .lo,$(basename $(libcacard-y))) - -vscclient: $(libcacard-y) $(QEMU_OBJS) vscclient.o - $(call quiet-command,$(CC) -o $@ $^ $(libcacard_libs) $(LIBS)," LINK $@") +libcacard.lib-y=$(patsubst %.o,%.lo,$(libcacard-y)) clean: rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~ vscclient *.lo .libs/* *.la *.pc rm -Rf .libs -all: vscclient +all: libcacard.la libcacard.pc # Dummy command so that make thinks it has done something @true @@ -41,6 +35,7 @@ else libcacard.la: $(libcacard.lib-y) $(QEMU_OBJS_LIB) $(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(libcacard_libs)," lt LINK $@") +libcacard_srcpath=$(SRC_PATH)/libcacard libcacard.pc: $(libcacard_srcpath)/libcacard.pc.in sed -e 's|@LIBDIR@|$(libdir)|' \ -e 's|@INCLUDEDIR@|$(libcacard_includedir)|' \ diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs new file mode 100644 index 0000000000..5899d72d3e --- /dev/null +++ b/linux-user/Makefile.objs @@ -0,0 +1,7 @@ +obj-y = main.o syscall.o strace.o mmap.o signal.o \ + elfload.o linuxload.o uaccess.o cpu-uname.o + +obj-$(TARGET_HAS_BFLT) += flatload.o +obj-$(TARGET_I386) += vm86.o +obj-$(TARGET_ARM) += arm/nwfpe/ +obj-$(TARGET_M68K) += m68k-sim.o diff --git a/linux-user/arm/nwfpe/Makefile.objs b/linux-user/arm/nwfpe/Makefile.objs new file mode 100644 index 0000000000..51b0c32c2a --- /dev/null +++ b/linux-user/arm/nwfpe/Makefile.objs @@ -0,0 +1,2 @@ +obj-y = fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o fpopcode.o +obj-y += single_cpdo.o double_cpdo.o extended_cpdo.o diff --git a/memory_mapping-stub.c b/memory_mapping-stub.c new file mode 100644 index 0000000000..104281d78e --- /dev/null +++ b/memory_mapping-stub.c @@ -0,0 +1,33 @@ +/* + * QEMU memory mapping + * + * Copyright Fujitsu, Corp. 2011, 2012 + * + * Authors: + * Wen Congyang <wency@cn.fujitsu.com> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "cpu.h" +#include "cpu-all.h" +#include "memory_mapping.h" + +int qemu_get_guest_memory_mapping(MemoryMappingList *list) +{ + return -2; +} + +int cpu_get_memory_mapping(MemoryMappingList *list, + CPUArchState *env) +{ + return -1; +} + +bool cpu_paging_enabled(CPUArchState *env) +{ + return true; +} + diff --git a/memory_mapping.c b/memory_mapping.c index 8810bb09e3..1125e3fccf 100644 --- a/memory_mapping.c +++ b/memory_mapping.c @@ -165,8 +165,6 @@ void memory_mapping_list_init(MemoryMappingList *list) QTAILQ_INIT(&list->head); } -#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING) - static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu) { CPUArchState *env; @@ -210,7 +208,6 @@ int qemu_get_guest_memory_mapping(MemoryMappingList *list) return 0; } -#endif void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list) { diff --git a/memory_mapping.h b/memory_mapping.h index a1aa64f4ca..3f003586d4 100644 --- a/memory_mapping.h +++ b/memory_mapping.h @@ -16,7 +16,6 @@ #include "qemu-queue.h" -#ifndef CONFIG_USER_ONLY /* The physical and virtual address in the memory mapping are contiguous. */ typedef struct MemoryMapping { target_phys_addr_t phys_addr; @@ -31,6 +30,9 @@ typedef struct MemoryMappingList { QTAILQ_HEAD(, MemoryMapping) head; } MemoryMappingList; +int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env); +bool cpu_paging_enabled(CPUArchState *env); + /* * add or merge the memory region [phys_addr, phys_addr + length) into the * memory mapping's list. The region's virtual address starts with virt_addr, @@ -51,14 +53,7 @@ void memory_mapping_list_init(MemoryMappingList *list); * -1: failed * -2: unsupported */ -#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING) int qemu_get_guest_memory_mapping(MemoryMappingList *list); -#else -static inline int qemu_get_guest_memory_mapping(MemoryMappingList *list) -{ - return -2; -} -#endif /* get guest's memory mapping without do paging(virtual address is 0). */ void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list); @@ -66,9 +61,4 @@ void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list); void memory_mapping_filter(MemoryMappingList *list, int64_t begin, int64_t length); -#else - -/* We use MemoryMappingList* in cpu-all.h */ -typedef struct MemoryMappingList MemoryMappingList; -#endif #endif diff --git a/net/Makefile.objs b/net/Makefile.objs new file mode 100644 index 0000000000..72f50bc903 --- /dev/null +++ b/net/Makefile.objs @@ -0,0 +1,12 @@ +common-obj-y = queue.o checksum.o util.o +common-obj-y += socket.o +common-obj-y += dump.o +common-obj-$(CONFIG_POSIX) += tap.o +common-obj-$(CONFIG_LINUX) += tap-linux.o +common-obj-$(CONFIG_WIN32) += tap-win32.o +common-obj-$(CONFIG_BSD) += tap-bsd.o +common-obj-$(CONFIG_SOLARIS) += tap-solaris.o +common-obj-$(CONFIG_AIX) += tap-aix.o +common-obj-$(CONFIG_HAIKU) += tap-haiku.o +common-obj-$(CONFIG_SLIRP) += slirp.o +common-obj-$(CONFIG_VDE) += vde.o diff --git a/net/tap-bsd.c b/net/tap-bsd.c index 4b6b3a41a0..937a94b11f 100644 --- a/net/tap-bsd.c +++ b/net/tap-bsd.c @@ -33,12 +33,6 @@ #include <net/if_tap.h> #endif -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -#include <libutil.h> -#else -#include <util.h> -#endif - int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required) { int fd; diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs new file mode 100644 index 0000000000..d0b0c16b90 --- /dev/null +++ b/qapi/Makefile.objs @@ -0,0 +1,3 @@ +qapi-obj-y = qapi-visit-core.o qapi-dealloc-visitor.o qmp-input-visitor.o +qapi-obj-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o +qapi-obj-y += string-input-visitor.o string-output-visitor.o diff --git a/qemu-char.c b/qemu-char.c index 0bd903f58c..c2aaaeeb8f 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -56,19 +56,19 @@ #include <sys/select.h> #ifdef CONFIG_BSD #include <sys/stat.h> -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include <libutil.h> -#include <dev/ppbus/ppi.h> -#include <dev/ppbus/ppbconf.h> #if defined(__GLIBC__) #include <pty.h> +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) +#include <libutil.h> +#else +#include <util.h> #endif +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#include <dev/ppbus/ppi.h> +#include <dev/ppbus/ppbconf.h> #elif defined(__DragonFly__) -#include <libutil.h> #include <dev/misc/ppi/ppi.h> #include <bus/ppbus/ppbconf.h> -#else -#include <util.h> #endif #else #ifdef __linux__ diff --git a/qga/Makefile.objs b/qga/Makefile.objs new file mode 100644 index 0000000000..6a4d843436 --- /dev/null +++ b/qga/Makefile.objs @@ -0,0 +1,3 @@ +qga-obj-y = commands.o guest-agent-command-state.o +qga-obj-$(CONFIG_POSIX) += commands-posix.o channel-posix.o +qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o diff --git a/qom/Makefile b/qom/Makefile deleted file mode 100644 index 34c6de558a..0000000000 --- a/qom/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -qom-y = object.o container.o qom-qobject.o -qom-twice-y = cpu.o diff --git a/qom/Makefile.objs b/qom/Makefile.objs new file mode 100644 index 0000000000..5ef060a401 --- /dev/null +++ b/qom/Makefile.objs @@ -0,0 +1,4 @@ +qom-obj-y = object.o container.o qom-qobject.o +qom-obj-twice-y = cpu.o +common-obj-y = $(qom-obj-twice-y) +user-obj-y = $(qom-obj-twice-y) @@ -73,3 +73,43 @@ TRACETOOL=$(PYTHON) $(SRC_PATH)/scripts/tracetool.py # will delete the target of a rule if commands exit with a nonzero exit status .DELETE_ON_ERROR: + +# magic to descend into other directories + +obj := . +old-nested-dirs := + +define push-var +$(eval save-$2-$1 = $(value $1)) +$(eval $1 :=) +endef + +define pop-var +$(eval subdir-$2-$1 := $(if $(filter $2,$(save-$2-$1)),$(addprefix $2,$($1)))) +$(eval $1 = $(value save-$2-$1) $$(subdir-$2-$1)) +$(eval save-$2-$1 :=) +endef + +define unnest-dir +$(foreach var,$(nested-vars),$(call push-var,$(var),$1/)) +$(eval obj := $(obj)/$1) +$(eval include $(SRC_PATH)/$1/Makefile.objs) +$(eval obj := $(patsubst %/$1,%,$(obj))) +$(foreach var,$(nested-vars),$(call pop-var,$(var),$1/)) +endef + +define unnest-vars-1 +$(eval nested-dirs := $(filter-out \ + $(old-nested-dirs), \ + $(sort $(foreach var,$(nested-vars), $(filter %/, $($(var))))))) +$(if $(nested-dirs), + $(foreach dir,$(nested-dirs),$(call unnest-dir,$(patsubst %/,%,$(dir)))) + $(eval old-nested-dirs := $(old-nested-dirs) $(nested-dirs)) + $(call unnest-vars-1)) +endef + +define unnest-vars +$(call unnest-vars-1) +$(foreach var,$(nested-vars),$(eval $(var) := $(filter-out %/, $($(var))))) +$(shell mkdir -p $(sort $(foreach var,$(nested-vars),$(dir $($(var)))))) +endef diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs new file mode 100644 index 0000000000..bb43d3c08c --- /dev/null +++ b/slirp/Makefile.objs @@ -0,0 +1,3 @@ +common-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o +common-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o +common-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o arp_table.o diff --git a/target-alpha/Makefile.objs b/target-alpha/Makefile.objs new file mode 100644 index 0000000000..590304cc61 --- /dev/null +++ b/target-alpha/Makefile.objs @@ -0,0 +1,3 @@ +obj-$(CONFIG_SOFTMMU) += machine.o +obj-y += translate.o helper.o cpu.o +obj-y += int_helper.o fpu_helper.o sys_helper.o mem_helper.o diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs new file mode 100644 index 0000000000..f447c4fdf2 --- /dev/null +++ b/target-arm/Makefile.objs @@ -0,0 +1,6 @@ +obj-y += arm-semi.o +obj-$(CONFIG_SOFTMMU) += machine.o +obj-y += translate.o op_helper.o helper.o cpu.o +obj-y += neon_helper.o iwmmxt_helper.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/arm-semi.c b/target-arm/arm-semi.c index 88ca9bb1b7..88ca9bb1b7 100644 --- a/arm-semi.c +++ b/target-arm/arm-semi.c diff --git a/target-cris/Makefile.objs b/target-cris/Makefile.objs new file mode 100644 index 0000000000..4b09e8c6b5 --- /dev/null +++ b/target-cris/Makefile.objs @@ -0,0 +1,4 @@ +obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += mmu.o machine.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs new file mode 100644 index 0000000000..f91375578c --- /dev/null +++ b/target-i386/Makefile.objs @@ -0,0 +1,7 @@ +obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o +obj-$(CONFIG_KVM) += kvm.o hyperv.o +obj-$(CONFIG_LINUX_USER) += ioport-user.o +obj-$(CONFIG_BSD_USER) += ioport-user.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c index 135d855c4a..7c2b514383 100644 --- a/target-i386/arch_dump.c +++ b/target-i386/arch_dump.c @@ -415,7 +415,7 @@ int cpu_get_dump_info(ArchDumpInfo *info) return 0; } -size_t cpu_get_note_size(int class, int machine, int nr_cpus) +ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) { int name_size = 5; /* "CORE" or "QEMU" */ size_t elf_note_size = 0; diff --git a/target-i386/arch_memory_mapping.c b/target-i386/arch_memory_mapping.c index bd50e1143a..efb0211fdc 100644 --- a/target-i386/arch_memory_mapping.c +++ b/target-i386/arch_memory_mapping.c @@ -13,6 +13,7 @@ #include "cpu.h" #include "cpu-all.h" +#include "memory_mapping.h" /* PAE Paging or IA-32e Paging */ static void walk_pte(MemoryMappingList *list, target_phys_addr_t pte_start_addr, diff --git a/ioport-user.c b/target-i386/ioport-user.c index 03fac22d22..03fac22d22 100644 --- a/ioport-user.c +++ b/target-i386/ioport-user.c diff --git a/target-lm32/Makefile.objs b/target-lm32/Makefile.objs new file mode 100644 index 0000000000..2e0e093e1f --- /dev/null +++ b/target-lm32/Makefile.objs @@ -0,0 +1,4 @@ +obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += machine.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-m68k/Makefile.objs b/target-m68k/Makefile.objs new file mode 100644 index 0000000000..cda60157f5 --- /dev/null +++ b/target-m68k/Makefile.objs @@ -0,0 +1,5 @@ +obj-y += m68k-semi.o +obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += machine.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/m68k-semi.c b/target-m68k/m68k-semi.c index 3bb30cd1f7..3bb30cd1f7 100644 --- a/m68k-semi.c +++ b/target-m68k/m68k-semi.c diff --git a/target-microblaze/Makefile.objs b/target-microblaze/Makefile.objs new file mode 100644 index 0000000000..4b09e8c6b5 --- /dev/null +++ b/target-microblaze/Makefile.objs @@ -0,0 +1,4 @@ +obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += mmu.o machine.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs new file mode 100644 index 0000000000..2e0e093e1f --- /dev/null +++ b/target-mips/Makefile.objs @@ -0,0 +1,4 @@ +obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += machine.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs new file mode 100644 index 0000000000..f78161004e --- /dev/null +++ b/target-ppc/Makefile.objs @@ -0,0 +1,6 @@ +obj-y += translate.o op_helper.o helper.o +obj-$(CONFIG_SOFTMMU) += machine.o +obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o +obj-y += op_helper.o helper.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs new file mode 100644 index 0000000000..262747f8a6 --- /dev/null +++ b/target-s390x/Makefile.objs @@ -0,0 +1,5 @@ +obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += machine.o +obj-$(CONFIG_KVM) += kvm.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-sh4/Makefile.objs b/target-sh4/Makefile.objs new file mode 100644 index 0000000000..2e0e093e1f --- /dev/null +++ b/target-sh4/Makefile.objs @@ -0,0 +1,4 @@ +obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += machine.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-sparc/Makefile.objs b/target-sparc/Makefile.objs new file mode 100644 index 0000000000..a93e07deb1 --- /dev/null +++ b/target-sparc/Makefile.objs @@ -0,0 +1,8 @@ +obj-$(CONFIG_SOFTMMU) += machine.o +obj-y += translate.o helper.o cpu.o +obj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o +obj-$(TARGET_SPARC) += int32_helper.o +obj-$(TARGET_SPARC64) += int64_helper.o +obj-$(TARGET_SPARC64) += vis_helper.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-unicore32/Makefile.objs b/target-unicore32/Makefile.objs new file mode 100644 index 0000000000..2e0e093e1f --- /dev/null +++ b/target-unicore32/Makefile.objs @@ -0,0 +1,4 @@ +obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += machine.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-xtensa/Makefile.objs b/target-xtensa/Makefile.objs new file mode 100644 index 0000000000..b30e5a8466 --- /dev/null +++ b/target-xtensa/Makefile.objs @@ -0,0 +1,6 @@ +obj-y += xtensa-semi.o +obj-y += core-dc232b.o +obj-y += core-dc233c.o +obj-y += core-fsf.o +obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += machine.o diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index 81f7833039..f7db116400 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -381,9 +381,12 @@ void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb, uint32_t *vpn, uint32_t wi, uint32_t *ei); int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb, uint32_t *pwi, uint32_t *pei, uint8_t *pring); +void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env, + xtensa_tlb_entry *entry, bool dtlb, + unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte); void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte); -int xtensa_get_physical_addr(CPUXtensaState *env, +int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb, uint32_t vaddr, int is_write, int mmu_idx, uint32_t *paddr, uint32_t *page_size, unsigned *access); void reset_mmu(CPUXtensaState *env); diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index 5e7e72e113..044ce18364 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -130,11 +130,11 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUXtensaState *env, target_ulong add uint32_t page_size; unsigned access; - if (xtensa_get_physical_addr(env, addr, 0, 0, + if (xtensa_get_physical_addr(env, false, addr, 0, 0, &paddr, &page_size, &access) == 0) { return paddr; } - if (xtensa_get_physical_addr(env, addr, 2, 0, + if (xtensa_get_physical_addr(env, false, addr, 2, 0, &paddr, &page_size, &access) == 0) { return paddr; } @@ -443,30 +443,48 @@ static bool is_access_granted(unsigned access, int is_write) } } -static int autorefill_mmu(CPUXtensaState *env, uint32_t vaddr, bool dtlb, - uint32_t *wi, uint32_t *ei, uint8_t *ring); +static int get_pte(CPUXtensaState *env, uint32_t vaddr, uint32_t *pte); -static int get_physical_addr_mmu(CPUXtensaState *env, +static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb, uint32_t vaddr, int is_write, int mmu_idx, - uint32_t *paddr, uint32_t *page_size, unsigned *access) + uint32_t *paddr, uint32_t *page_size, unsigned *access, + bool may_lookup_pt) { bool dtlb = is_write != 2; uint32_t wi; uint32_t ei; uint8_t ring; + uint32_t vpn; + uint32_t pte; + const xtensa_tlb_entry *entry = NULL; + xtensa_tlb_entry tmp_entry; int ret = xtensa_tlb_lookup(env, vaddr, dtlb, &wi, &ei, &ring); if ((ret == INST_TLB_MISS_CAUSE || ret == LOAD_STORE_TLB_MISS_CAUSE) && - (mmu_idx != 0 || ((vaddr ^ env->sregs[PTEVADDR]) & 0xffc00000)) && - autorefill_mmu(env, vaddr, dtlb, &wi, &ei, &ring) == 0) { + may_lookup_pt && get_pte(env, vaddr, &pte) == 0) { + ring = (pte >> 4) & 0x3; + wi = 0; + split_tlb_entry_spec_way(env, vaddr, dtlb, &vpn, wi, &ei); + + if (update_tlb) { + wi = ++env->autorefill_idx & 0x3; + xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte); + env->sregs[EXCVADDR] = vaddr; + qemu_log("%s: autorefill(%08x): %08x -> %08x\n", + __func__, vaddr, vpn, pte); + } else { + xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte); + entry = &tmp_entry; + } ret = 0; } if (ret != 0) { return ret; } - const xtensa_tlb_entry *entry = - xtensa_tlb_get_entry(env, dtlb, wi, ei); + if (entry == NULL) { + entry = xtensa_tlb_get_entry(env, dtlb, wi, ei); + } if (ring < mmu_idx) { return dtlb ? @@ -489,30 +507,21 @@ static int get_physical_addr_mmu(CPUXtensaState *env, return 0; } -static int autorefill_mmu(CPUXtensaState *env, uint32_t vaddr, bool dtlb, - uint32_t *wi, uint32_t *ei, uint8_t *ring) +static int get_pte(CPUXtensaState *env, uint32_t vaddr, uint32_t *pte) { uint32_t paddr; uint32_t page_size; unsigned access; uint32_t pt_vaddr = (env->sregs[PTEVADDR] | (vaddr >> 10)) & 0xfffffffc; - int ret = get_physical_addr_mmu(env, pt_vaddr, 0, 0, - &paddr, &page_size, &access); + int ret = get_physical_addr_mmu(env, false, pt_vaddr, 0, 0, + &paddr, &page_size, &access, false); qemu_log("%s: trying autorefill(%08x) -> %08x\n", __func__, vaddr, ret ? ~0 : paddr); if (ret == 0) { - uint32_t vpn; - uint32_t pte = ldl_phys(paddr); - - *ring = (pte >> 4) & 0x3; - *wi = (++env->autorefill_idx) & 0x3; - split_tlb_entry_spec_way(env, vaddr, dtlb, &vpn, *wi, ei); - xtensa_tlb_set_entry(env, dtlb, *wi, *ei, vpn, pte); - qemu_log("%s: autorefill(%08x): %08x -> %08x\n", - __func__, vaddr, vpn, pte); + *pte = ldl_phys(paddr); } return ret; } @@ -548,13 +557,13 @@ static int get_physical_addr_region(CPUXtensaState *env, * * \return 0 if ok, exception cause code otherwise */ -int xtensa_get_physical_addr(CPUXtensaState *env, +int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb, uint32_t vaddr, int is_write, int mmu_idx, uint32_t *paddr, uint32_t *page_size, unsigned *access) { if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { - return get_physical_addr_mmu(env, vaddr, is_write, mmu_idx, - paddr, page_size, access); + return get_physical_addr_mmu(env, update_tlb, + vaddr, is_write, mmu_idx, paddr, page_size, access, true); } else if (xtensa_option_bits_enabled(env->config, XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) | XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION))) { diff --git a/target-xtensa/helper.h b/target-xtensa/helper.h index 48a741e46d..152fec044d 100644 --- a/target-xtensa/helper.h +++ b/target-xtensa/helper.h @@ -1,39 +1,39 @@ #include "def-helper.h" -DEF_HELPER_1(exception, void, i32) -DEF_HELPER_2(exception_cause, void, i32, i32) -DEF_HELPER_3(exception_cause_vaddr, void, i32, i32, i32) -DEF_HELPER_2(debug_exception, void, i32, i32) +DEF_HELPER_2(exception, noreturn, env, i32) +DEF_HELPER_3(exception_cause, noreturn, env, i32, i32) +DEF_HELPER_4(exception_cause_vaddr, noreturn, env, i32, i32, i32) +DEF_HELPER_3(debug_exception, noreturn, env, i32, i32) -DEF_HELPER_1(nsa, i32, i32) -DEF_HELPER_1(nsau, i32, i32) -DEF_HELPER_1(wsr_windowbase, void, i32) -DEF_HELPER_3(entry, void, i32, i32, i32) -DEF_HELPER_1(retw, i32, i32) -DEF_HELPER_1(rotw, void, i32) -DEF_HELPER_2(window_check, void, i32, i32) -DEF_HELPER_0(restore_owb, void) -DEF_HELPER_1(movsp, void, i32) -DEF_HELPER_1(wsr_lbeg, void, i32) -DEF_HELPER_1(wsr_lend, void, i32) +DEF_HELPER_FLAGS_1(nsa, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32) +DEF_HELPER_FLAGS_1(nsau, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32) +DEF_HELPER_2(wsr_windowbase, void, env, i32) +DEF_HELPER_4(entry, void, env, i32, i32, i32) +DEF_HELPER_2(retw, i32, env, i32) +DEF_HELPER_2(rotw, void, env, i32) +DEF_HELPER_3(window_check, void, env, i32, i32) +DEF_HELPER_1(restore_owb, void, env) +DEF_HELPER_2(movsp, void, env, i32) +DEF_HELPER_2(wsr_lbeg, void, env, i32) +DEF_HELPER_2(wsr_lend, void, env, i32) DEF_HELPER_1(simcall, void, env) -DEF_HELPER_0(dump_state, void) +DEF_HELPER_1(dump_state, void, env) -DEF_HELPER_2(waiti, void, i32, i32) -DEF_HELPER_2(timer_irq, void, i32, i32) -DEF_HELPER_1(advance_ccount, void, i32) +DEF_HELPER_3(waiti, void, env, i32, i32) +DEF_HELPER_3(timer_irq, void, env, i32, i32) +DEF_HELPER_2(advance_ccount, void, env, i32) DEF_HELPER_1(check_interrupts, void, env) -DEF_HELPER_1(wsr_rasid, void, i32) -DEF_HELPER_2(rtlb0, i32, i32, i32) -DEF_HELPER_2(rtlb1, i32, i32, i32) -DEF_HELPER_2(itlb, void, i32, i32) -DEF_HELPER_2(ptlb, i32, i32, i32) -DEF_HELPER_3(wtlb, void, i32, i32, i32) +DEF_HELPER_2(wsr_rasid, void, env, i32) +DEF_HELPER_FLAGS_3(rtlb0, TCG_CALL_CONST | TCG_CALL_PURE, i32, env, i32, i32) +DEF_HELPER_FLAGS_3(rtlb1, TCG_CALL_CONST | TCG_CALL_PURE, i32, env, i32, i32) +DEF_HELPER_3(itlb, void, env, i32, i32) +DEF_HELPER_3(ptlb, i32, env, i32, i32) +DEF_HELPER_4(wtlb, void, env, i32, i32, i32) -DEF_HELPER_1(wsr_ibreakenable, void, i32) -DEF_HELPER_2(wsr_ibreaka, void, i32, i32) -DEF_HELPER_2(wsr_dbreaka, void, i32, i32) -DEF_HELPER_2(wsr_dbreakc, void, i32, i32) +DEF_HELPER_2(wsr_ibreakenable, void, env, i32) +DEF_HELPER_3(wsr_ibreaka, void, env, i32, i32) +DEF_HELPER_3(wsr_dbreaka, void, env, i32, i32) +DEF_HELPER_3(wsr_dbreakc, void, env, i32, i32) #include "def-helper.h" diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index 364dc19bc0..2659c0e00f 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -26,12 +26,11 @@ */ #include "cpu.h" -#include "dyngen-exec.h" #include "helper.h" #include "host-utils.h" -static void do_unaligned_access(target_ulong addr, int is_write, int is_user, - uintptr_t retaddr); +static void do_unaligned_access(CPUXtensaState *env, + target_ulong addr, int is_write, int is_user, uintptr_t retaddr); #define ALIGNED_ONLY #define MMUSUFFIX _mmu @@ -48,7 +47,7 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user, #define SHIFT 3 #include "softmmu_template.h" -static void do_restore_state(uintptr_t pc) +static void do_restore_state(CPUXtensaState *env, uintptr_t pc) { TranslationBlock *tb; @@ -58,44 +57,38 @@ static void do_restore_state(uintptr_t pc) } } -static void do_unaligned_access(target_ulong addr, int is_write, int is_user, - uintptr_t retaddr) +static void do_unaligned_access(CPUXtensaState *env, + target_ulong addr, int is_write, int is_user, uintptr_t retaddr) { if (xtensa_option_enabled(env->config, XTENSA_OPTION_UNALIGNED_EXCEPTION) && !xtensa_option_enabled(env->config, XTENSA_OPTION_HW_ALIGNMENT)) { - do_restore_state(retaddr); - HELPER(exception_cause_vaddr)( + do_restore_state(env, retaddr); + HELPER(exception_cause_vaddr)(env, env->pc, LOAD_STORE_ALIGNMENT_CAUSE, addr); } } -void tlb_fill(CPUXtensaState *env1, target_ulong vaddr, int is_write, int mmu_idx, - uintptr_t retaddr) +void tlb_fill(CPUXtensaState *env, + target_ulong vaddr, int is_write, int mmu_idx, uintptr_t retaddr) { - CPUXtensaState *saved_env = env; - - env = env1; - { - uint32_t paddr; - uint32_t page_size; - unsigned access; - int ret = xtensa_get_physical_addr(env, vaddr, is_write, mmu_idx, - &paddr, &page_size, &access); + uint32_t paddr; + uint32_t page_size; + unsigned access; + int ret = xtensa_get_physical_addr(env, true, vaddr, is_write, mmu_idx, + &paddr, &page_size, &access); - qemu_log("%s(%08x, %d, %d) -> %08x, ret = %d\n", __func__, - vaddr, is_write, mmu_idx, paddr, ret); + qemu_log("%s(%08x, %d, %d) -> %08x, ret = %d\n", __func__, + vaddr, is_write, mmu_idx, paddr, ret); - if (ret == 0) { - tlb_set_page(env, - vaddr & TARGET_PAGE_MASK, - paddr & TARGET_PAGE_MASK, - access, mmu_idx, page_size); - } else { - do_restore_state(retaddr); - HELPER(exception_cause_vaddr)(env->pc, ret, vaddr); - } + if (ret == 0) { + tlb_set_page(env, + vaddr & TARGET_PAGE_MASK, + paddr & TARGET_PAGE_MASK, + access, mmu_idx, page_size); + } else { + do_restore_state(env, retaddr); + HELPER(exception_cause_vaddr)(env, env->pc, ret, vaddr); } - env = saved_env; } static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr) @@ -103,20 +96,20 @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr) uint32_t paddr; uint32_t page_size; unsigned access; - int ret = xtensa_get_physical_addr(env, vaddr, 2, 0, + int ret = xtensa_get_physical_addr(env, false, vaddr, 2, 0, &paddr, &page_size, &access); if (ret == 0) { tb_invalidate_phys_addr(paddr); } } -void HELPER(exception)(uint32_t excp) +void HELPER(exception)(CPUXtensaState *env, uint32_t excp) { env->exception_index = excp; cpu_loop_exit(env); } -void HELPER(exception_cause)(uint32_t pc, uint32_t cause) +void HELPER(exception_cause)(CPUXtensaState *env, uint32_t pc, uint32_t cause) { uint32_t vector; @@ -136,24 +129,24 @@ void HELPER(exception_cause)(uint32_t pc, uint32_t cause) env->sregs[EXCCAUSE] = cause; env->sregs[PS] |= PS_EXCM; - HELPER(exception)(vector); + HELPER(exception)(env, vector); } -void HELPER(exception_cause_vaddr)(uint32_t pc, uint32_t cause, uint32_t vaddr) +void HELPER(exception_cause_vaddr)(CPUXtensaState *env, + uint32_t pc, uint32_t cause, uint32_t vaddr) { env->sregs[EXCVADDR] = vaddr; - HELPER(exception_cause)(pc, cause); + HELPER(exception_cause)(env, pc, cause); } -void debug_exception_env(CPUXtensaState *new_env, uint32_t cause) +void debug_exception_env(CPUXtensaState *env, uint32_t cause) { - if (xtensa_get_cintlevel(new_env) < new_env->config->debug_level) { - env = new_env; - HELPER(debug_exception)(env->pc, cause); + if (xtensa_get_cintlevel(env) < env->config->debug_level) { + HELPER(debug_exception)(env, env->pc, cause); } } -void HELPER(debug_exception)(uint32_t pc, uint32_t cause) +void HELPER(debug_exception)(CPUXtensaState *env, uint32_t pc, uint32_t cause) { unsigned level = env->config->debug_level; @@ -163,7 +156,7 @@ void HELPER(debug_exception)(uint32_t pc, uint32_t cause) env->sregs[EPS2 + level - 2] = env->sregs[PS]; env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) | PS_EXCM | (level << PS_INTLEVEL_SHIFT); - HELPER(exception)(EXC_DEBUG); + HELPER(exception)(env, EXC_DEBUG); } uint32_t HELPER(nsa)(uint32_t v) @@ -232,39 +225,39 @@ void xtensa_sync_phys_from_window(CPUXtensaState *env) copy_phys_from_window(env, env->sregs[WINDOW_BASE] * 4, 0, 16); } -static void rotate_window_abs(uint32_t position) +static void rotate_window_abs(CPUXtensaState *env, uint32_t position) { xtensa_sync_phys_from_window(env); env->sregs[WINDOW_BASE] = windowbase_bound(position, env); xtensa_sync_window_from_phys(env); } -static void rotate_window(uint32_t delta) +static void rotate_window(CPUXtensaState *env, uint32_t delta) { - rotate_window_abs(env->sregs[WINDOW_BASE] + delta); + rotate_window_abs(env, env->sregs[WINDOW_BASE] + delta); } -void HELPER(wsr_windowbase)(uint32_t v) +void HELPER(wsr_windowbase)(CPUXtensaState *env, uint32_t v) { - rotate_window_abs(v); + rotate_window_abs(env, v); } -void HELPER(entry)(uint32_t pc, uint32_t s, uint32_t imm) +void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm) { int callinc = (env->sregs[PS] & PS_CALLINC) >> PS_CALLINC_SHIFT; if (s > 3 || ((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) != 0) { qemu_log("Illegal entry instruction(pc = %08x), PS = %08x\n", pc, env->sregs[PS]); - HELPER(exception_cause)(pc, ILLEGAL_INSTRUCTION_CAUSE); + HELPER(exception_cause)(env, pc, ILLEGAL_INSTRUCTION_CAUSE); } else { env->regs[(callinc << 2) | (s & 3)] = env->regs[s] - (imm << 3); - rotate_window(callinc); + rotate_window(env, callinc); env->sregs[WINDOW_START] |= windowstart_bit(env->sregs[WINDOW_BASE], env); } } -void HELPER(window_check)(uint32_t pc, uint32_t w) +void HELPER(window_check)(CPUXtensaState *env, uint32_t pc, uint32_t w) { uint32_t windowbase = windowbase_bound(env->sregs[WINDOW_BASE], env); uint32_t windowstart = env->sregs[WINDOW_START]; @@ -284,21 +277,21 @@ void HELPER(window_check)(uint32_t pc, uint32_t w) } m = windowbase_bound(windowbase + n, env); - rotate_window(n); + rotate_window(env, n); env->sregs[PS] = (env->sregs[PS] & ~PS_OWB) | (windowbase << PS_OWB_SHIFT) | PS_EXCM; env->sregs[EPC1] = env->pc = pc; if (windowstart & windowstart_bit(m + 1, env)) { - HELPER(exception)(EXC_WINDOW_OVERFLOW4); + HELPER(exception)(env, EXC_WINDOW_OVERFLOW4); } else if (windowstart & windowstart_bit(m + 2, env)) { - HELPER(exception)(EXC_WINDOW_OVERFLOW8); + HELPER(exception)(env, EXC_WINDOW_OVERFLOW8); } else { - HELPER(exception)(EXC_WINDOW_OVERFLOW12); + HELPER(exception)(env, EXC_WINDOW_OVERFLOW12); } } -uint32_t HELPER(retw)(uint32_t pc) +uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc) { int n = (env->regs[0] >> 30) & 0x3; int m = 0; @@ -319,13 +312,13 @@ uint32_t HELPER(retw)(uint32_t pc) qemu_log("Illegal retw instruction(pc = %08x), " "PS = %08x, m = %d, n = %d\n", pc, env->sregs[PS], m, n); - HELPER(exception_cause)(pc, ILLEGAL_INSTRUCTION_CAUSE); + HELPER(exception_cause)(env, pc, ILLEGAL_INSTRUCTION_CAUSE); } else { int owb = windowbase; ret_pc = (pc & 0xc0000000) | (env->regs[0] & 0x3fffffff); - rotate_window(-n); + rotate_window(env, -n); if (windowstart & windowstart_bit(env->sregs[WINDOW_BASE], env)) { env->sregs[WINDOW_START] &= ~windowstart_bit(owb, env); } else { @@ -335,38 +328,38 @@ uint32_t HELPER(retw)(uint32_t pc) env->sregs[EPC1] = env->pc = pc; if (n == 1) { - HELPER(exception)(EXC_WINDOW_UNDERFLOW4); + HELPER(exception)(env, EXC_WINDOW_UNDERFLOW4); } else if (n == 2) { - HELPER(exception)(EXC_WINDOW_UNDERFLOW8); + HELPER(exception)(env, EXC_WINDOW_UNDERFLOW8); } else if (n == 3) { - HELPER(exception)(EXC_WINDOW_UNDERFLOW12); + HELPER(exception)(env, EXC_WINDOW_UNDERFLOW12); } } } return ret_pc; } -void HELPER(rotw)(uint32_t imm4) +void HELPER(rotw)(CPUXtensaState *env, uint32_t imm4) { - rotate_window(imm4); + rotate_window(env, imm4); } -void HELPER(restore_owb)(void) +void HELPER(restore_owb)(CPUXtensaState *env) { - rotate_window_abs((env->sregs[PS] & PS_OWB) >> PS_OWB_SHIFT); + rotate_window_abs(env, (env->sregs[PS] & PS_OWB) >> PS_OWB_SHIFT); } -void HELPER(movsp)(uint32_t pc) +void HELPER(movsp)(CPUXtensaState *env, uint32_t pc) { if ((env->sregs[WINDOW_START] & (windowstart_bit(env->sregs[WINDOW_BASE] - 3, env) | windowstart_bit(env->sregs[WINDOW_BASE] - 2, env) | windowstart_bit(env->sregs[WINDOW_BASE] - 1, env))) == 0) { - HELPER(exception_cause)(pc, ALLOCA_CAUSE); + HELPER(exception_cause)(env, pc, ALLOCA_CAUSE); } } -void HELPER(wsr_lbeg)(uint32_t v) +void HELPER(wsr_lbeg)(CPUXtensaState *env, uint32_t v) { if (env->sregs[LBEG] != v) { tb_invalidate_virtual_addr(env, env->sregs[LEND] - 1); @@ -374,7 +367,7 @@ void HELPER(wsr_lbeg)(uint32_t v) } } -void HELPER(wsr_lend)(uint32_t v) +void HELPER(wsr_lend)(CPUXtensaState *env, uint32_t v) { if (env->sregs[LEND] != v) { tb_invalidate_virtual_addr(env, env->sregs[LEND] - 1); @@ -383,12 +376,12 @@ void HELPER(wsr_lend)(uint32_t v) } } -void HELPER(dump_state)(void) +void HELPER(dump_state)(CPUXtensaState *env) { cpu_dump_state(env, stderr, fprintf, 0); } -void HELPER(waiti)(uint32_t pc, uint32_t intlevel) +void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel) { env->pc = pc; env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) | @@ -404,15 +397,15 @@ void HELPER(waiti)(uint32_t pc, uint32_t intlevel) if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) { xtensa_rearm_ccompare_timer(env); } - HELPER(exception)(EXCP_HLT); + HELPER(exception)(env, EXCP_HLT); } -void HELPER(timer_irq)(uint32_t id, uint32_t active) +void HELPER(timer_irq)(CPUXtensaState *env, uint32_t id, uint32_t active) { xtensa_timer_irq(env, id, active); } -void HELPER(advance_ccount)(uint32_t d) +void HELPER(advance_ccount)(CPUXtensaState *env, uint32_t d) { xtensa_advance_ccount(env, d); } @@ -422,7 +415,7 @@ void HELPER(check_interrupts)(CPUXtensaState *env) check_interrupts(env); } -void HELPER(wsr_rasid)(uint32_t v) +void HELPER(wsr_rasid)(CPUXtensaState *env, uint32_t v) { v = (v & 0xffffff00) | 0x1; if (v != env->sregs[RASID]) { @@ -574,7 +567,7 @@ void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb, * Split TLB address into TLB way, entry index and VPN (with index). * See ISA, 4.6.5.5 - 4.6.5.8 for the TLB addressing format */ -static void split_tlb_entry_spec(uint32_t v, bool dtlb, +static void split_tlb_entry_spec(CPUXtensaState *env, uint32_t v, bool dtlb, uint32_t *vpn, uint32_t *wi, uint32_t *ei) { if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { @@ -587,41 +580,42 @@ static void split_tlb_entry_spec(uint32_t v, bool dtlb, } } -static xtensa_tlb_entry *get_tlb_entry(uint32_t v, bool dtlb, uint32_t *pwi) +static xtensa_tlb_entry *get_tlb_entry(CPUXtensaState *env, + uint32_t v, bool dtlb, uint32_t *pwi) { uint32_t vpn; uint32_t wi; uint32_t ei; - split_tlb_entry_spec(v, dtlb, &vpn, &wi, &ei); + split_tlb_entry_spec(env, v, dtlb, &vpn, &wi, &ei); if (pwi) { *pwi = wi; } return xtensa_tlb_get_entry(env, dtlb, wi, ei); } -uint32_t HELPER(rtlb0)(uint32_t v, uint32_t dtlb) +uint32_t HELPER(rtlb0)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) { if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { uint32_t wi; - const xtensa_tlb_entry *entry = get_tlb_entry(v, dtlb, &wi); + const xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi); return (entry->vaddr & get_vpn_mask(env, dtlb, wi)) | entry->asid; } else { return v & REGION_PAGE_MASK; } } -uint32_t HELPER(rtlb1)(uint32_t v, uint32_t dtlb) +uint32_t HELPER(rtlb1)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) { - const xtensa_tlb_entry *entry = get_tlb_entry(v, dtlb, NULL); + const xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, NULL); return entry->paddr | entry->attr; } -void HELPER(itlb)(uint32_t v, uint32_t dtlb) +void HELPER(itlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) { if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { uint32_t wi; - xtensa_tlb_entry *entry = get_tlb_entry(v, dtlb, &wi); + xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi); if (entry->variable && entry->asid) { tlb_flush_page(env, entry->vaddr); entry->asid = 0; @@ -629,7 +623,7 @@ void HELPER(itlb)(uint32_t v, uint32_t dtlb) } } -uint32_t HELPER(ptlb)(uint32_t v, uint32_t dtlb) +uint32_t HELPER(ptlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) { if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { uint32_t wi; @@ -646,7 +640,7 @@ uint32_t HELPER(ptlb)(uint32_t v, uint32_t dtlb) case INST_TLB_MULTI_HIT_CAUSE: case LOAD_STORE_TLB_MULTI_HIT_CAUSE: - HELPER(exception_cause_vaddr)(env->pc, res, v); + HELPER(exception_cause_vaddr)(env, env->pc, res, v); break; } return 0; @@ -655,6 +649,16 @@ uint32_t HELPER(ptlb)(uint32_t v, uint32_t dtlb) } } +void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env, + xtensa_tlb_entry *entry, bool dtlb, + unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte) +{ + entry->vaddr = vpn; + entry->paddr = pte & xtensa_tlb_get_addr_mask(env, dtlb, wi); + entry->asid = (env->sregs[RASID] >> ((pte >> 1) & 0x18)) & 0xff; + entry->attr = pte & 0xf; +} + void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte) { @@ -665,10 +669,8 @@ void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, if (entry->asid) { tlb_flush_page(env, entry->vaddr); } - entry->vaddr = vpn; - entry->paddr = pte & xtensa_tlb_get_addr_mask(env, dtlb, wi); - entry->asid = (env->sregs[RASID] >> ((pte >> 1) & 0x18)) & 0xff; - entry->attr = pte & 0xf; + xtensa_tlb_set_entry_mmu(env, entry, dtlb, wi, ei, vpn, pte); + tlb_flush_page(env, entry->vaddr); } else { qemu_log("%s %d, %d, %d trying to set immutable entry\n", __func__, dtlb, wi, ei); @@ -683,17 +685,17 @@ void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, } } -void HELPER(wtlb)(uint32_t p, uint32_t v, uint32_t dtlb) +void HELPER(wtlb)(CPUXtensaState *env, uint32_t p, uint32_t v, uint32_t dtlb) { uint32_t vpn; uint32_t wi; uint32_t ei; - split_tlb_entry_spec(v, dtlb, &vpn, &wi, &ei); + split_tlb_entry_spec(env, v, dtlb, &vpn, &wi, &ei); xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, p); } -void HELPER(wsr_ibreakenable)(uint32_t v) +void HELPER(wsr_ibreakenable)(CPUXtensaState *env, uint32_t v) { uint32_t change = v ^ env->sregs[IBREAKENABLE]; unsigned i; @@ -706,7 +708,7 @@ void HELPER(wsr_ibreakenable)(uint32_t v) env->sregs[IBREAKENABLE] = v & ((1 << env->config->nibreak) - 1); } -void HELPER(wsr_ibreaka)(uint32_t i, uint32_t v) +void HELPER(wsr_ibreaka)(CPUXtensaState *env, uint32_t i, uint32_t v) { if (env->sregs[IBREAKENABLE] & (1 << i) && env->sregs[IBREAKA + i] != v) { tb_invalidate_virtual_addr(env, env->sregs[IBREAKA + i]); @@ -715,7 +717,8 @@ void HELPER(wsr_ibreaka)(uint32_t i, uint32_t v) env->sregs[IBREAKA + i] = v; } -static void set_dbreak(unsigned i, uint32_t dbreaka, uint32_t dbreakc) +static void set_dbreak(CPUXtensaState *env, unsigned i, uint32_t dbreaka, + uint32_t dbreakc) { int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; uint32_t mask = dbreakc | ~DBREAKC_MASK; @@ -743,22 +746,22 @@ static void set_dbreak(unsigned i, uint32_t dbreaka, uint32_t dbreakc) } } -void HELPER(wsr_dbreaka)(uint32_t i, uint32_t v) +void HELPER(wsr_dbreaka)(CPUXtensaState *env, uint32_t i, uint32_t v) { uint32_t dbreakc = env->sregs[DBREAKC + i]; if ((dbreakc & DBREAKC_SB_LB) && env->sregs[DBREAKA + i] != v) { - set_dbreak(i, v, dbreakc); + set_dbreak(env, i, v, dbreakc); } env->sregs[DBREAKA + i] = v; } -void HELPER(wsr_dbreakc)(uint32_t i, uint32_t v) +void HELPER(wsr_dbreakc)(CPUXtensaState *env, uint32_t i, uint32_t v) { if ((env->sregs[DBREAKC + i] ^ v) & (DBREAKC_SB_LB | DBREAKC_MASK)) { if (v & DBREAKC_SB_LB) { - set_dbreak(i, env->sregs[DBREAKA + i], v); + set_dbreak(env, i, env->sregs[DBREAKA + i], v); } else { if (env->cpu_watchpoint[i]) { cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[i]); diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 521c0e6226..b883e6bb72 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -254,7 +254,7 @@ static void gen_advance_ccount(DisasContext *dc) if (dc->ccount_delta > 0) { TCGv_i32 tmp = tcg_const_i32(dc->ccount_delta); dc->ccount_delta = 0; - gen_helper_advance_ccount(tmp); + gen_helper_advance_ccount(cpu_env, tmp); tcg_temp_free(tmp); } } @@ -268,7 +268,7 @@ static void gen_exception(DisasContext *dc, int excp) { TCGv_i32 tmp = tcg_const_i32(excp); gen_advance_ccount(dc); - gen_helper_exception(tmp); + gen_helper_exception(cpu_env, tmp); tcg_temp_free(tmp); } @@ -277,7 +277,7 @@ static void gen_exception_cause(DisasContext *dc, uint32_t cause) TCGv_i32 tpc = tcg_const_i32(dc->pc); TCGv_i32 tcause = tcg_const_i32(cause); gen_advance_ccount(dc); - gen_helper_exception_cause(tpc, tcause); + gen_helper_exception_cause(cpu_env, tpc, tcause); tcg_temp_free(tpc); tcg_temp_free(tcause); if (cause == ILLEGAL_INSTRUCTION_CAUSE || @@ -292,7 +292,7 @@ static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause, TCGv_i32 tpc = tcg_const_i32(dc->pc); TCGv_i32 tcause = tcg_const_i32(cause); gen_advance_ccount(dc); - gen_helper_exception_cause_vaddr(tpc, tcause, vaddr); + gen_helper_exception_cause_vaddr(cpu_env, tpc, tcause, vaddr); tcg_temp_free(tpc); tcg_temp_free(tcause); } @@ -302,7 +302,7 @@ static void gen_debug_exception(DisasContext *dc, uint32_t cause) TCGv_i32 tpc = tcg_const_i32(dc->pc); TCGv_i32 tcause = tcg_const_i32(cause); gen_advance_ccount(dc); - gen_helper_debug_exception(tpc, tcause); + gen_helper_debug_exception(cpu_env, tpc, tcause); tcg_temp_free(tpc); tcg_temp_free(tcause); if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) { @@ -388,6 +388,7 @@ static bool gen_check_loop_end(DisasContext *dc, int slot) dc->next_pc == dc->lend) { int label = gen_new_label(); + gen_advance_ccount(dc); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label); tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1); gen_jumpi(dc, dc->lbeg, slot); @@ -410,6 +411,7 @@ static void gen_brcond(DisasContext *dc, TCGCond cond, { int label = gen_new_label(); + gen_advance_ccount(dc); tcg_gen_brcond_i32(cond, t0, t1, label); gen_jumpi_check_loop_end(dc, 0); gen_set_label(label); @@ -458,13 +460,13 @@ static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr) static void gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s) { - gen_helper_wsr_lbeg(s); + gen_helper_wsr_lbeg(cpu_env, s); gen_jumpi_check_loop_end(dc, 0); } static void gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s) { - gen_helper_wsr_lend(s); + gen_helper_wsr_lend(cpu_env, s); gen_jumpi_check_loop_end(dc, 0); } @@ -497,7 +499,7 @@ static void gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s) static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v) { - gen_helper_wsr_windowbase(v); + gen_helper_wsr_windowbase(cpu_env, v); reset_used_window(dc); } @@ -514,7 +516,7 @@ static void gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v) static void gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v) { - gen_helper_wsr_rasid(v); + gen_helper_wsr_rasid(cpu_env, v); /* This can change tb->flags, so exit tb */ gen_jumpi_check_loop_end(dc, -1); } @@ -526,7 +528,7 @@ static void gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v) static void gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v) { - gen_helper_wsr_ibreakenable(v); + gen_helper_wsr_ibreakenable(cpu_env, v); gen_jumpi_check_loop_end(dc, 0); } @@ -536,7 +538,7 @@ static void gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v) if (id < dc->config->nibreak) { TCGv_i32 tmp = tcg_const_i32(id); - gen_helper_wsr_ibreaka(tmp, v); + gen_helper_wsr_ibreaka(cpu_env, tmp, v); tcg_temp_free(tmp); gen_jumpi_check_loop_end(dc, 0); } @@ -548,7 +550,7 @@ static void gen_wsr_dbreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v) if (id < dc->config->ndbreak) { TCGv_i32 tmp = tcg_const_i32(id); - gen_helper_wsr_dbreaka(tmp, v); + gen_helper_wsr_dbreaka(cpu_env, tmp, v); tcg_temp_free(tmp); } } @@ -559,7 +561,7 @@ static void gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v) if (id < dc->config->ndbreak) { TCGv_i32 tmp = tcg_const_i32(id); - gen_helper_wsr_dbreakc(tmp, v); + gen_helper_wsr_dbreakc(cpu_env, tmp, v); tcg_temp_free(tmp); } } @@ -712,7 +714,7 @@ static void gen_waiti(DisasContext *dc, uint32_t imm4) TCGv_i32 pc = tcg_const_i32(dc->next_pc); TCGv_i32 intlevel = tcg_const_i32(imm4); gen_advance_ccount(dc); - gen_helper_waiti(pc, intlevel); + gen_helper_waiti(cpu_env, pc, intlevel); tcg_temp_free(pc); tcg_temp_free(intlevel); } @@ -729,7 +731,7 @@ static void gen_window_check1(DisasContext *dc, unsigned r1) dc->used_window = r1 / 4; gen_advance_ccount(dc); - gen_helper_window_check(pc, w); + gen_helper_window_check(cpu_env, pc, w); tcg_temp_free(w); tcg_temp_free(pc); @@ -849,8 +851,8 @@ static void disas_xtensa_insn(DisasContext *dc) #define RSR_SR (b1) - uint8_t b0 = ldub_code(dc->pc); - uint8_t b1 = ldub_code(dc->pc + 1); + uint8_t b0 = cpu_ldub_code(cpu_single_env, dc->pc); + uint8_t b1 = cpu_ldub_code(cpu_single_env, dc->pc + 1); uint8_t b2 = 0; static const uint32_t B4CONST[] = { @@ -866,7 +868,7 @@ static void disas_xtensa_insn(DisasContext *dc) HAS_OPTION(XTENSA_OPTION_CODE_DENSITY); } else { dc->next_pc = dc->pc + 3; - b2 = ldub_code(dc->pc + 2); + b2 = cpu_ldub_code(cpu_single_env, dc->pc + 2); } switch (OP0) { @@ -903,7 +905,7 @@ static void disas_xtensa_insn(DisasContext *dc) { TCGv_i32 tmp = tcg_const_i32(dc->pc); gen_advance_ccount(dc); - gen_helper_retw(tmp, tmp); + gen_helper_retw(tmp, cpu_env, tmp); gen_jump(dc, tmp); tcg_temp_free(tmp); } @@ -951,7 +953,7 @@ static void disas_xtensa_insn(DisasContext *dc) { TCGv_i32 pc = tcg_const_i32(dc->pc); gen_advance_ccount(dc); - gen_helper_movsp(pc); + gen_helper_movsp(cpu_env, pc); tcg_gen_mov_i32(cpu_R[RRR_T], cpu_R[RRR_S]); tcg_temp_free(pc); } @@ -1031,7 +1033,7 @@ static void disas_xtensa_insn(DisasContext *dc) cpu_SR[WINDOW_START], tmp); } - gen_helper_restore_owb(); + gen_helper_restore_owb(cpu_env); gen_helper_check_interrupts(cpu_env); gen_jump(dc, cpu_SR[EPC1]); @@ -1219,7 +1221,7 @@ static void disas_xtensa_insn(DisasContext *dc) { TCGv_i32 tmp = tcg_const_i32( RRR_T | ((RRR_T & 8) ? 0xfffffff0 : 0)); - gen_helper_rotw(tmp); + gen_helper_rotw(cpu_env, tmp); tcg_temp_free(tmp); reset_used_window(dc); } @@ -1255,28 +1257,32 @@ static void disas_xtensa_insn(DisasContext *dc) switch (RRR_R & 7) { case 3: /*RITLB0*/ /*RDTLB0*/ - gen_helper_rtlb0(cpu_R[RRR_T], cpu_R[RRR_S], dtlb); + gen_helper_rtlb0(cpu_R[RRR_T], + cpu_env, cpu_R[RRR_S], dtlb); break; case 4: /*IITLB*/ /*IDTLB*/ - gen_helper_itlb(cpu_R[RRR_S], dtlb); + gen_helper_itlb(cpu_env, cpu_R[RRR_S], dtlb); /* This could change memory mapping, so exit tb */ gen_jumpi_check_loop_end(dc, -1); break; case 5: /*PITLB*/ /*PDTLB*/ tcg_gen_movi_i32(cpu_pc, dc->pc); - gen_helper_ptlb(cpu_R[RRR_T], cpu_R[RRR_S], dtlb); + gen_helper_ptlb(cpu_R[RRR_T], + cpu_env, cpu_R[RRR_S], dtlb); break; case 6: /*WITLB*/ /*WDTLB*/ - gen_helper_wtlb(cpu_R[RRR_T], cpu_R[RRR_S], dtlb); + gen_helper_wtlb( + cpu_env, cpu_R[RRR_T], cpu_R[RRR_S], dtlb); /* This could change memory mapping, so exit tb */ gen_jumpi_check_loop_end(dc, -1); break; case 7: /*RITLB1*/ /*RDTLB1*/ - gen_helper_rtlb1(cpu_R[RRR_T], cpu_R[RRR_S], dtlb); + gen_helper_rtlb1(cpu_R[RRR_T], + cpu_env, cpu_R[RRR_S], dtlb); break; default: @@ -2244,7 +2250,7 @@ static void disas_xtensa_insn(DisasContext *dc) TCGv_i32 s = tcg_const_i32(BRI12_S); TCGv_i32 imm = tcg_const_i32(BRI12_IMM12); gen_advance_ccount(dc); - gen_helper_entry(pc, s, imm); + gen_helper_entry(cpu_env, pc, s, imm); tcg_temp_free(imm); tcg_temp_free(s); tcg_temp_free(pc); @@ -2278,7 +2284,7 @@ static void disas_xtensa_insn(DisasContext *dc) tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[RRI8_S], 1); tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc); - gen_helper_wsr_lend(tmp); + gen_helper_wsr_lend(cpu_env, tmp); tcg_temp_free(tmp); if (BRI8_R > 8) { @@ -2447,7 +2453,7 @@ static void disas_xtensa_insn(DisasContext *dc) { TCGv_i32 tmp = tcg_const_i32(dc->pc); gen_advance_ccount(dc); - gen_helper_retw(tmp, tmp); + gen_helper_retw(tmp, cpu_env, tmp); gen_jump(dc, tmp); tcg_temp_free(tmp); } diff --git a/xtensa-semi.c b/target-xtensa/xtensa-semi.c index b7c8c34564..1c8a19ed56 100644 --- a/xtensa-semi.c +++ b/target-xtensa/xtensa-semi.c @@ -30,7 +30,6 @@ #include <string.h> #include <stddef.h> #include "cpu.h" -#include "dyngen-exec.h" #include "helper.h" #include "qemu-log.h" diff --git a/tests/Makefile b/tests/Makefile index ab7f667009..2e754c381e 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -37,7 +37,6 @@ test-qapi-obj-y = $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) test-qapi-obj-y += tests/test-qapi-visit.o tests/test-qapi-types.o test-qapi-obj-y += module.o -$(test-obj-y): $(GENERATED_HEADERS) $(test-obj-y): QEMU_INCLUDES += -Itests tests/check-qint$(EXESUF): tests/check-qint.o qint.o $(tools-obj-y) diff --git a/tests/tcg/xtensa/test_mmu.S b/tests/tcg/xtensa/test_mmu.S index 52d5774212..5d87fbb703 100644 --- a/tests/tcg/xtensa/test_mmu.S +++ b/tests/tcg/xtensa/test_mmu.S @@ -293,26 +293,219 @@ test store_prohibited assert eq, a2, a3 test_end -test dtlb_autoload - set_vector kernel, 0 - - movi a2, 0xd4000000 +/* Set up page table entry vaddr->paddr, ring=pte_ring, attr=pte_attr + * and DTLB way 7 to cover this PTE, ring=pt_ring, attr=pt_attr + */ +.macro pt_setup pt_ring, pt_attr, pte_ring, vaddr, paddr, pte_attr + movi a2, 0x80000000 wsr a2, ptevaddr - movi a3, 0x00001013 - s32i a3, a2, 4 + + movi a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */ + movi a4, 0x04000003 | ((\pt_ring) << 4) /* PADDR 64M */ + wdtlb a4, a3 + isync + + movi a3, ((\paddr) & 0xfffff000) | ((\pte_ring) << 4) | (\pte_attr) + movi a1, ((\vaddr) >> 12) << 2 + add a2, a1, a2 + s32i a3, a2, 0 + + movi a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */ + movi a4, 0x04000000 | ((\pt_ring) << 4) | (\pt_attr) /* PADDR 64M */ + wdtlb a4, a3 + isync + + movi a3, (\vaddr) +.endm + +/* out: PS.RING=ring, PS.EXCM=excm, a3=vaddr */ +.macro go_ring ring, excm, vaddr + movi a3, 10f + pitlb a3, a3 + ritlb1 a2, a3 + movi a1, 0x10 + or a2, a2, a1 + movi a1, 0x000ff000 + and a3, a3, a1 + movi a1, 4 + or a3, a3, a1 + witlb a2, a3 + movi a3, 10f + movi a1, 0x000fffff + and a1, a3, a1 + + movi a2, 0 + wsr a2, excvaddr + + movi a3, \vaddr + movi a2, 0x4000f | ((\ring) << 6) | ((\excm) << 4) + jx a1 +10: + wsr a2, ps + isync +.endm + +/* in: a3 -- virtual address to test */ +.macro assert_auto_tlb + movi a2, 0x4000f + wsr a2, ps + isync + pdtlb a2, a3 + movi a1, 0xfffff01f + and a2, a2, a1 + movi a1, 0xfffff000 + and a1, a1, a3 + xor a1, a1, a2 + assert gei, a1, 0x10 + movi a2, 0x14 + assert lt, a1, a2 +.endm + +/* in: a3 -- virtual address to test */ +.macro assert_no_auto_tlb + movi a2, 0x4000f + wsr a2, ps + isync pdtlb a2, a3 movi a1, 0x10 and a1, a1, a2 assert eqi, a1, 0 - l8ui a1, a3, 0 - pdtlb a2, a3 - movi a1, 0xfffff010 - and a1, a1, a2 - movi a3, 0x00001010 - assert eq, a1, a3 - movi a1, 0xf +.endm + +.macro assert_sr sr, v + rsr a2, \sr + movi a1, (\v) + assert eq, a1, a2 +.endm + +.macro assert_epc1_1m vaddr + movi a2, (\vaddr) + movi a1, 0xfffff and a1, a1, a2 - assert lti, a1, 4 + rsr a2, epc1 + assert eq, a1, a2 +.endm + +test dtlb_autoload + set_vector kernel, 0 + + pt_setup 0, 3, 1, 0x1000, 0x1000, 3 + assert_no_auto_tlb + + l8ui a1, a3, 0 + + rsr a2, excvaddr + assert eq, a2, a3 + + assert_auto_tlb +test_end + +test autoload_load_store_privilege + set_vector kernel, 0 + set_vector double, 2f + + pt_setup 0, 3, 0, 0x2000, 0x2000, 3 + movi a3, 0x2004 + assert_no_auto_tlb + + movi a2, 0x4005f /* ring 1 + excm => cring == 0 */ + wsr a2, ps + isync +1: + l32e a2, a3, -4 /* ring used */ + test_fail +2: + rsr a2, excvaddr + addi a1, a3, -4 + assert eq, a1, a2 + + assert_auto_tlb + assert_sr depc, 1b + assert_sr exccause, 26 +test_end + +test autoload_pte_load_prohibited + set_vector kernel, 2f + + pt_setup 0, 3, 0, 0x3000, 0, 0xc + assert_no_auto_tlb +1: + l32i a2, a3, 0 + test_fail +2: + rsr a2, excvaddr + assert eq, a2, a3 + + assert_auto_tlb + assert_sr epc1, 1b + assert_sr exccause, 28 +test_end + +test autoload_pt_load_prohibited + set_vector kernel, 2f + + pt_setup 0, 0xc, 0, 0x4000, 0x4000, 3 + assert_no_auto_tlb +1: + l32i a2, a3, 0 + test_fail +2: + rsr a2, excvaddr + assert eq, a2, a3 + + assert_no_auto_tlb + assert_sr epc1, 1b + assert_sr exccause, 24 +test_end + +test autoload_pt_privilege + set_vector kernel, 2f + pt_setup 0, 3, 1, 0x5000, 0, 3 + go_ring 1, 0, 0x5001 + + l8ui a2, a3, 0 +1: + syscall +2: + rsr a2, excvaddr + assert eq, a2, a3 + + assert_auto_tlb + assert_epc1_1m 1b + assert_sr exccause, 1 +test_end + +test autoload_pte_privilege + set_vector kernel, 2f + pt_setup 0, 3, 0, 0x6000, 0, 3 + go_ring 1, 0, 0x6001 +1: + l8ui a2, a3, 0 + syscall +2: + rsr a2, excvaddr + assert eq, a2, a3 + + assert_auto_tlb + assert_epc1_1m 1b + assert_sr exccause, 26 +test_end + +test autoload_3_level_pt + set_vector kernel, 2f + pt_setup 1, 3, 1, 0x00400000, 0, 3 + pt_setup 1, 3, 1, 0x80001000, 0x2000000, 3 + go_ring 1, 0, 0x00400001 +1: + l8ui a2, a3, 0 + syscall +2: + rsr a2, excvaddr + assert eq, a2, a3 + + assert_no_auto_tlb + assert_epc1_1m 1b + assert_sr exccause, 24 test_end test_suite_end diff --git a/trace-events b/trace-events index 45c6bc1271..f70523c47e 100644 --- a/trace-events +++ b/trace-events @@ -257,19 +257,20 @@ usb_ehci_port_detach(uint32_t port) "detach port #%d" usb_ehci_port_reset(uint32_t port, int enable) "reset port #%d - %d" usb_ehci_data(int rw, uint32_t cpage, uint32_t offset, uint32_t addr, uint32_t len, uint32_t bufpos) "write %d, cpage %d, offset 0x%03x, addr 0x%08x, len %d, bufpos %d" usb_ehci_queue_action(void *q, const char *action) "q %p: %s" +usb_ehci_packet_action(void *q, void *p, const char *action) "q %p p %p: %s" # hw/usb/hcd-uhci.c usb_uhci_reset(void) "=== RESET ===" usb_uhci_schedule_start(void) "" usb_uhci_schedule_stop(void) "" usb_uhci_frame_start(uint32_t num) "nr %d" +usb_uhci_frame_stop_bandwidth(void) "" usb_uhci_frame_loop_stop_idle(void) "" -usb_uhci_frame_loop_stop_bandwidth(void) "" usb_uhci_frame_loop_continue(void) "" -usb_uhci_mmio_readw(uint32_t addr, uint32_t val) "addr %04x, ret 0x04%x" -usb_uhci_mmio_writew(uint32_t addr, uint32_t val) "addr %04x, val 0x04%x" -usb_uhci_mmio_readl(uint32_t addr, uint32_t val) "addr %04x, ret 0x08%x" -usb_uhci_mmio_writel(uint32_t addr, uint32_t val) "addr %04x, val 0x08%x" +usb_uhci_mmio_readw(uint32_t addr, uint32_t val) "addr 0x%04x, ret 0x%04x" +usb_uhci_mmio_writew(uint32_t addr, uint32_t val) "addr 0x%04x, val 0x%04x" +usb_uhci_mmio_readl(uint32_t addr, uint32_t val) "addr 0x%04x, ret 0x%08x" +usb_uhci_mmio_writel(uint32_t addr, uint32_t val) "addr 0x%04x, val 0x%08x" usb_uhci_queue_add(uint32_t token) "token 0x%x" usb_uhci_queue_del(uint32_t token) "token 0x%x" usb_uhci_packet_add(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x" @@ -289,6 +290,41 @@ usb_uhci_td_nextqh(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x" usb_uhci_td_async(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x" usb_uhci_td_complete(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x" +# hw/usb/hcd-xhci.c +usb_xhci_reset(void) "=== RESET ===" +usb_xhci_run(void) "" +usb_xhci_stop(void) "" +usb_xhci_cap_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x" +usb_xhci_oper_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x" +usb_xhci_port_read(uint32_t port, uint32_t off, uint32_t val) "port %d, off 0x%04x, ret 0x%08x" +usb_xhci_runtime_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x" +usb_xhci_doorbell_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x" +usb_xhci_oper_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" +usb_xhci_port_write(uint32_t port, uint32_t off, uint32_t val) "port %d, off 0x%04x, val 0x%08x" +usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" +usb_xhci_doorbell_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" +usb_xhci_irq_intx(uint32_t level) "level %d" +usb_xhci_irq_msi(uint32_t nr) "nr %d" +usb_xhci_queue_event(uint32_t idx, const char *name, uint64_t param, uint32_t status, uint32_t control) "idx %d, %s, p %016" PRIx64 ", s %08x, c 0x%08x" +usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x" +usb_xhci_slot_enable(uint32_t slotid) "slotid %d" +usb_xhci_slot_disable(uint32_t slotid) "slotid %d" +usb_xhci_slot_address(uint32_t slotid) "slotid %d" +usb_xhci_slot_configure(uint32_t slotid) "slotid %d" +usb_xhci_slot_evaluate(uint32_t slotid) "slotid %d" +usb_xhci_slot_reset(uint32_t slotid) "slotid %d" +usb_xhci_ep_enable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" +usb_xhci_ep_disable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" +usb_xhci_ep_kick(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" +usb_xhci_ep_stop(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" +usb_xhci_ep_reset(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" +usb_xhci_xfer_start(void *xfer, uint32_t slotid, uint32_t epid, uint32_t length) "%p: slotid %d, epid %d, length %d" +usb_xhci_xfer_async(void *xfer) "%p" +usb_xhci_xfer_nak(void *xfer) "%p" +usb_xhci_xfer_retry(void *xfer) "%p" +usb_xhci_xfer_success(void *xfer, uint32_t bytes) "%p: len %d" +usb_xhci_xfer_error(void *xfer, uint32_t ret) "%p: ret %d" + # hw/usb/desc.c usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d" usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d" diff --git a/ui/Makefile.objs b/ui/Makefile.objs new file mode 100644 index 0000000000..3687c8a518 --- /dev/null +++ b/ui/Makefile.objs @@ -0,0 +1,18 @@ +vnc-obj-y += vnc.o d3des.o +vnc-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o +vnc-obj-y += vnc-enc-tight.o vnc-palette.o +vnc-obj-y += vnc-enc-zrle.o +vnc-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o +vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o +ifdef CONFIG_VNC_THREAD +vnc-obj-y += vnc-jobs-async.o +else +vnc-obj-y += vnc-jobs-sync.o +endif + +common-obj-y += keymaps.o +common-obj-$(CONFIG_SPICE) += spice-core.o spice-input.o spice-display.o +common-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o +common-obj-$(CONFIG_COCOA) += cocoa.o +common-obj-$(CONFIG_CURSES) += curses.o +common-obj-$(CONFIG_VNC) += $(vnc-obj-y) @@ -51,14 +51,12 @@ #ifdef CONFIG_BSD #include <sys/stat.h> #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -#include <libutil.h> #include <sys/sysctl.h> #else #include <util.h> #endif #else #ifdef __linux__ -#include <pty.h> #include <malloc.h> #include <linux/ppdev.h> @@ -81,10 +79,6 @@ #endif #endif -#if defined(__OpenBSD__) -#include <util.h> -#endif - #if defined(CONFIG_VDE) #include <libvdeplug.h> #endif |