aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile63
-rw-r--r--Makefile.objs34
-rw-r--r--accel/tcg/meson.build2
-rw-r--r--chardev/meson.build4
-rwxr-xr-xconfigure305
-rw-r--r--disas/meson.build4
-rw-r--r--docs/devel/build-system.rst115
-rw-r--r--docs/devel/qapi-code-gen.txt2
-rw-r--r--exec.c1
-rw-r--r--hw/arm/meson.build2
-rw-r--r--hw/core/cpu.c2
-rw-r--r--hw/display/artist.c43
-rw-r--r--hw/hppa/hppa_hardware.h3
-rw-r--r--hw/hppa/machine.c56
-rw-r--r--hw/input/adb.c1
-rw-r--r--hw/intc/spapr_xive.c33
-rw-r--r--hw/intc/spapr_xive_kvm.c102
-rw-r--r--hw/microblaze/petalogix_ml605_mmu.c6
-rw-r--r--hw/mips/cps.c15
-rw-r--r--hw/mips/meson.build2
-rw-r--r--hw/ppc/e500.c13
-rw-r--r--hw/ppc/meson.build3
-rw-r--r--hw/ppc/pnv_bmc.c29
-rw-r--r--hw/ppc/pnv_lpc.c3
-rw-r--r--hw/ppc/ppc4xx_pci.c8
-rw-r--r--hw/ppc/spapr.c109
-rw-r--r--hw/ppc/spapr_cpu_core.c10
-rw-r--r--hw/ppc/spapr_hcall.c40
-rw-r--r--hw/ppc/spapr_irq.c2
-rw-r--r--hw/ppc/spapr_numa.c242
-rw-r--r--hw/ppc/spapr_nvdimm.c68
-rw-r--r--hw/ppc/spapr_pci.c9
-rw-r--r--hw/ppc/spapr_pci_nvlink2.c20
-rw-r--r--hw/riscv/meson.build2
-rw-r--r--hw/scsi/spapr_vscsi.c3
-rw-r--r--hw/sparc/sun4m.c26
-rw-r--r--include/hw/core/cpu.h4
-rw-r--r--include/hw/ipmi/ipmi.h1
-rw-r--r--include/hw/ppc/spapr.h17
-rw-r--r--include/hw/ppc/spapr_drc.h43
-rw-r--r--include/hw/ppc/spapr_numa.h35
-rw-r--r--include/hw/ppc/spapr_nvdimm.h7
-rw-r--r--include/hw/ppc/spapr_xive.h2
-rw-r--r--meson.build127
-rw-r--r--monitor/meson.build2
-rw-r--r--pc-bios/hppa-firmware.imgbin783192 -> 785696 bytes
-rw-r--r--qapi/audio.json12
-rw-r--r--qapi/block-core.json14
-rw-r--r--qapi/control.json4
-rw-r--r--qapi/machine.json6
-rw-r--r--qapi/migration.json68
-rw-r--r--qapi/misc.json4
-rw-r--r--qapi/net.json2
m---------roms/seabios-hppa0
-rw-r--r--rules.mak158
-rwxr-xr-xscripts/grepy.sh3
-rw-r--r--scripts/mtest2make.py100
-rwxr-xr-xscripts/ninjatool.py8
-rwxr-xr-xscripts/oss-fuzz/build.sh2
-rw-r--r--scripts/qapi/parser.py24
-rw-r--r--scripts/test-driver.py35
-rw-r--r--scripts/undefsym.py49
-rwxr-xr-xscripts/undefsym.sh20
-rw-r--r--target/arm/cpu.c4
-rw-r--r--target/arm/cpu.h3
-rw-r--r--target/arm/kvm32.c2
-rw-r--r--target/arm/kvm64.c2
-rw-r--r--target/hppa/cpu.h5
-rw-r--r--target/hppa/insns.decode10
-rw-r--r--target/microblaze/cpu.c115
-rw-r--r--target/microblaze/cpu.h78
-rw-r--r--target/microblaze/gdbstub.c6
-rw-r--r--target/microblaze/helper.c247
-rw-r--r--target/microblaze/machine.c106
-rw-r--r--target/microblaze/meson.build5
-rw-r--r--target/microblaze/mmu.c39
-rw-r--r--target/microblaze/mmu.h20
-rw-r--r--target/microblaze/op_helper.c2
-rw-r--r--target/microblaze/translate.c194
-rw-r--r--target/s390x/cpu.c2
-rw-r--r--tests/Makefile.include416
-rw-r--r--tests/benchmark-crypto-cipher.c8
-rw-r--r--tests/benchmark-crypto-hash.c2
-rw-r--r--tests/benchmark-crypto-hmac.c8
-rw-r--r--tests/docker/Makefile.include4
-rw-r--r--tests/include/meson.build16
-rw-r--r--tests/meson.build253
-rwxr-xr-xtests/migration/initrd-stress.sh10
-rw-r--r--tests/migration/meson.build14
-rw-r--r--tests/migration/stress.c15
-rw-r--r--tests/qapi-schema/doc-bad-section.err1
-rw-r--r--tests/qapi-schema/doc-bad-section.json3
-rw-r--r--tests/qapi-schema/doc-bad-section.out24
-rw-r--r--tests/qapi-schema/doc-good.out3
-rw-r--r--tests/qemu-iotests/meson.build4
-rw-r--r--tests/qtest/fuzz/meson.build7
-rw-r--r--tests/qtest/libqos/meson.build9
-rw-r--r--tests/tcg/Makefile.qemu2
-rw-r--r--tests/test-crypto-secret.c10
-rw-r--r--tests/test-qga.c2
-rw-r--r--ui/meson.build3
102 files changed, 1868 insertions, 1917 deletions
diff --git a/.gitignore b/.gitignore
index 4ccb9ed975..b6fdd34ddf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,8 +2,6 @@
/build/
/.doctrees
/config-devices.*
-/config-all-devices.*
-/config-all-disas.*
/config-host.*
/config-target.*
/config.status
diff --git a/Makefile b/Makefile
index ed354c43b0..d6c5c9fdef 100644
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,20 @@ BUILD_DIR=$(CURDIR)
# Before including a proper config-host.mak, assume we are in the source tree
SRC_PATH=.
+# Don't use implicit rules or variables
+# we have explicit rules for everything
+MAKEFLAGS += -rR
+
+# Usage: $(call quiet-command,command and args,"NAME","args to print")
+# This will run "command and args", and either:
+# if V=1 just print the whole command and args
+# otherwise print the 'quiet' output in the format " NAME args to print"
+# NAME should be a short name of the command, 7 letters or fewer.
+# If called with only a single argument, will print nothing in quiet mode.
+quiet-command-run = $(if $(V),,$(if $2,printf " %-7s %s\n" $2 $3 && ))$1
+quiet-@ = $(if $(V),,@)
+quiet-command = $(quiet-@)$(call quiet-command-run,$1,$2,$3)
+
UNCHECKED_GOALS := %clean TAGS cscope ctags dist \
help check-help print-% \
docker docker-% vm-help vm-test vm-build-%
@@ -64,10 +78,11 @@ ${ninja-targets-c_COMPILER} ${ninja-targets-cpp_COMPILER}: .var.command += -MP
# reread (and MESON won't be empty anymore).
ifneq ($(MESON),)
Makefile.mtest: build.ninja scripts/mtest2make.py
- $(MESON) introspect --tests | $(PYTHON) scripts/mtest2make.py > $@
+ $(MESON) introspect --tests --benchmarks | $(PYTHON) scripts/mtest2make.py > $@
-include Makefile.mtest
endif
+Makefile: .git-submodule-status
.git-submodule-status: git-submodule-update config-host.mak
# Check that we're not trying to do an out-of-tree build from
@@ -80,13 +95,6 @@ seems to have been used for an in-tree build. You can fix this by running \
endif
endif
-CONFIG_SOFTMMU := $(if $(filter %-softmmu,$(TARGET_DIRS)),y)
-CONFIG_USER_ONLY := $(if $(filter %-user,$(TARGET_DIRS)),y)
-CONFIG_XEN := $(CONFIG_XEN_BACKEND)
-CONFIG_ALL=y
--include config-all-devices.mak
--include config-all-disas.mak
-
config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/pc-bios $(SRC_PATH)/VERSION
@echo $@ is out-of-date, running configure
@if test -f meson-private/coredata.dat; then \
@@ -115,13 +123,6 @@ ninja-clean::
ninja-distclean::
build.ninja: config-host.mak
-include $(SRC_PATH)/rules.mak
-
-# lor is defined in rules.mak
-CONFIG_BLOCK := $(call lor,$(CONFIG_SOFTMMU),$(CONFIG_TOOLS))
-
-generated-files-y += .git-submodule-status
-
# Don't try to regenerate Makefile or configure
# We don't generate any of them
Makefile: ;
@@ -130,15 +131,7 @@ configure: ;
.PHONY: all clean cscope distclean install \
recurse-all dist msi FORCE
-$(call set-vpath, $(SRC_PATH))
-
-LIBS+=-lz $(LIBS_TOOLS)
-
-SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory --quiet) BUILD_DIR=$(BUILD_DIR)
-
-ifneq ($(wildcard config-host.mak),)
-include $(SRC_PATH)/Makefile.objs
-endif
+SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory --quiet)
include $(SRC_PATH)/tests/Makefile.include
@@ -162,7 +155,7 @@ dtc/%: .git-submodule-status
# Therefore we replicate some of the logic in the sub-makefile.
# Remove all the extra -Warning flags that QEMU uses that Capstone doesn't;
# no need to annoy QEMU developers with such things.
-CAP_CFLAGS = $(patsubst -W%,,$(CFLAGS) $(QEMU_CFLAGS))
+CAP_CFLAGS = $(patsubst -W%,,$(CFLAGS) $(QEMU_CFLAGS)) $(CAPSTONE_CFLAGS)
CAP_CFLAGS += -DCAPSTONE_USE_SYS_DYN_MEM
CAP_CFLAGS += -DCAPSTONE_HAS_ARM
CAP_CFLAGS += -DCAPSTONE_HAS_ARM64
@@ -205,7 +198,6 @@ clean: recurse-clean ninja-clean clean-ctlist
-exec rm {} +
rm -f TAGS cscope.* *.pod *~ */*~
rm -f fsdev/*.pod scsi/*.pod
- rm -f $(foreach f,$(generated-files-y),$(f) $(f)-timestamp)
VERSION = $(shell cat $(SRC_PATH)/VERSION)
@@ -248,18 +240,6 @@ cscope:
# Needed by "meson install"
export DESTDIR
-# Add a dependency on the generated files, so that they are always
-# rebuilt before other object files
-ifneq ($(wildcard config-host.mak),)
-ifneq ($(filter-out $(UNCHECKED_GOALS),$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),,fail))
-Makefile: $(generated-files-y)
-endif
-endif
-
-# Include automatically generated dependency files
-# Dependencies in Makefile.objs files come from our recursive subdir rules
--include $(wildcard *.d tests/*.d)
-
include $(SRC_PATH)/tests/docker/Makefile.include
include $(SRC_PATH)/tests/vm/Makefile.include
@@ -283,6 +263,7 @@ help:
@echo ''
@echo 'Test targets:'
$(call print-help,check,Run all tests (check-help for details))
+ $(call print-help,bench,Run all benchmarks)
$(call print-help,docker,Help about targets running tests inside containers)
$(call print-help,vm-help,Help about targets running tests inside VM)
@echo ''
@@ -299,3 +280,9 @@ endif
endif
$(call print-help,$(MAKE) [targets],(quiet build, default))
$(call print-help,$(MAKE) V=1 [targets],(verbose build))
+
+# will delete the target of a rule if commands exit with a nonzero exit status
+.DELETE_ON_ERROR:
+
+print-%:
+ @echo '$*=$($*)'
diff --git a/Makefile.objs b/Makefile.objs
deleted file mode 100644
index c351b59641..0000000000
--- a/Makefile.objs
+++ /dev/null
@@ -1,34 +0,0 @@
-#######################################################################
-# Common libraries for tools and emulators
-qom-obj-y = qom/libqom.fa
-
-#######################################################################
-# code used by both qemu system emulation and qemu-img
-
-ifeq ($(call lor,$(CONFIG_SOFTMMU),$(CONFIG_TOOLS)),y)
-
-authz-obj-y = authz/libauthz.fa
-authz/libauthz.fa-libs = $(if $(CONFIG_AUTH_PAM),-lpam)
-
-block-obj-y += libblock.fa
-
-libblock.fa-libs = $(ZSTD_LIBS)
-libblock.fa-libs += $(LIBNFS_LIBS)
-libblock.fa-libs += $(LIBISCSI_LIBS)
-libblock.fa-libs += $(CURL_LIBS)
-libblock.fa-libs += $(RBD_LIBS)
-libblock.fa-libs += $(GLUSTERFS_LIBS)
-libblock.fa-libs += $(VXHS_LIBS)
-libblock.fa-libs += $(LIBSSH_LIBS)
-libblock.fa-libs += $(BZIP2_LIBS)
-libblock.fa-libs += $(LZFSE_LIBS)
-libblock.fa-libs += $(if $(CONFIG_LINUX_AIO),-laio)
-libblock.fa-libs += $(LIBXML2_LIBS)
-
-chardev-obj-y = chardev/libchardev.fa
-
-crypto-obj-y = crypto/libcrypto.fa
-
-io-obj-y = io/libio.fa
-
-endif # CONFIG_SOFTMMU or CONFIG_TOOLS
diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build
index 2a335b50f2..96a76ed23d 100644
--- a/accel/tcg/meson.build
+++ b/accel/tcg/meson.build
@@ -9,7 +9,7 @@ tcg_ss.add(files(
))
tcg_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-exec.c'))
tcg_ss.add(when: 'CONFIG_SOFTMMU', if_false: files('user-exec-stub.c'))
-tcg_ss.add(when: 'CONFIG_PLUGIN', if_true: files('plugin-gen.c'))
+tcg_ss.add(when: 'CONFIG_PLUGIN', if_true: [files('plugin-gen.c'), libdl])
specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: files('tcg-all.c', 'cputlb.c'))
diff --git a/chardev/meson.build b/chardev/meson.build
index 27a9a28f4c..54e88d0310 100644
--- a/chardev/meson.build
+++ b/chardev/meson.build
@@ -36,9 +36,9 @@ softmmu_ss.add(when: ['CONFIG_SPICE', spice], if_true: files('spice.c'))
chardev_modules = {}
-if config_host.has_key('CONFIG_BRLAPI') and sdl.found()
+if config_host.has_key('CONFIG_BRLAPI')
module_ss = ss.source_set()
- module_ss.add(when: [sdl, brlapi], if_true: [files('baum.c'), pixman])
+ module_ss.add(when: [brlapi], if_true: [files('baum.c'), pixman])
chardev_modules += { 'baum': module_ss }
endif
diff --git a/configure b/configure
index 166193cef9..4231d56bcc 100755
--- a/configure
+++ b/configure
@@ -192,36 +192,6 @@ has() {
type "$1" >/dev/null 2>&1
}
-# search for an executable in PATH
-path_of() {
- local_command="$1"
- local_ifs="$IFS"
- local_dir=""
-
- # pathname has a dir component?
- if [ "${local_command#*/}" != "$local_command" ]; then
- if [ -x "$local_command" ] && [ ! -d "$local_command" ]; then
- echo "$local_command"
- return 0
- fi
- fi
- if [ -z "$local_command" ]; then
- return 1
- fi
-
- IFS=:
- for local_dir in $PATH; do
- if [ -x "$local_dir/$local_command" ] && [ ! -d "$local_dir/$local_command" ]; then
- echo "$local_dir/$local_command"
- IFS="${local_ifs:-$(printf ' \t\n')}"
- return 0
- fi
- done
- # not found
- IFS="${local_ifs:-$(printf ' \t\n')}"
- return 1
-}
-
version_ge () {
local_ver1=`echo $1 | tr . ' '`
local_ver2=`echo $2 | tr . ' '`
@@ -361,7 +331,6 @@ audio_drv_list=""
block_drv_rw_whitelist=""
block_drv_ro_whitelist=""
host_cc="cc"
-libs_tools=""
audio_win_int=""
libs_qga=""
debug_info="yes"
@@ -469,7 +438,6 @@ mingw32="no"
gcov="no"
EXESUF=""
HOST_DSOSUF=".so"
-LDFLAGS_SHARED="-shared"
modules="no"
module_upgrades="no"
prefix="/usr/local"
@@ -665,14 +633,6 @@ QEMU_INCLUDES="$QEMU_INCLUDES -iquote ${source_path}/disas/libvixl"
CFLAGS="-std=gnu99 -Wall"
-# running configure in the source tree?
-# we know that's the case if configure is there.
-if test -f "./configure"; then
- pwd_is_source_path="y"
-else
- pwd_is_source_path="n"
-fi
-
check_define() {
cat > $TMPC <<EOF
#if !defined($1)
@@ -871,7 +831,6 @@ FreeBSD)
audio_drv_list="oss try-sdl"
audio_possible_drivers="oss sdl pa"
# needed for kinfo_getvmmap(3) in libutil.h
- LIBS="-lutil $LIBS"
netmap="" # enable netmap autodetect
HOST_VARIANT_DIR="freebsd"
;;
@@ -903,7 +862,6 @@ Darwin)
darwin="yes"
hax="yes"
hvf="yes"
- LDFLAGS_SHARED="-bundle -undefined dynamic_lookup"
if [ "$cpu" = "x86_64" ] ; then
QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
QEMU_LDFLAGS="-arch x86_64 $QEMU_LDFLAGS"
@@ -920,7 +878,6 @@ Darwin)
SunOS)
solaris="yes"
make="${MAKE-gmake}"
- install="${INSTALL-ginstall}"
smbd="${SMBD-/usr/sfw/sbin/smbd}"
if test -f /usr/include/sys/soundcard.h ; then
audio_drv_list="oss try-sdl"
@@ -930,13 +887,10 @@ SunOS)
QEMU_CFLAGS="-D_XOPEN_SOURCE=600 $QEMU_CFLAGS"
# needed for TIOCWIN* defines in termios.h
QEMU_CFLAGS="-D__EXTENSIONS__ $QEMU_CFLAGS"
- solarisnetlibs="-lsocket -lnsl -lresolv"
- LIBS="$solarisnetlibs $LIBS"
;;
Haiku)
haiku="yes"
QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS -DBSD_SOURCE $QEMU_CFLAGS"
- LIBS="-lposix_error_mapper -lnetwork -lbsd $LIBS"
;;
Linux)
audio_drv_list="try-pa oss"
@@ -944,7 +898,7 @@ Linux)
linux="yes"
linux_user="yes"
kvm="yes"
- QEMU_INCLUDES="-isystem ${source_path}/linux-headers -I$PWD/linux-headers $QEMU_INCLUDES"
+ QEMU_INCLUDES="-isystem ${source_path}/linux-headers -Ilinux-headers $QEMU_INCLUDES"
libudev="yes"
;;
esac
@@ -956,7 +910,7 @@ if [ "$bsd" = "yes" ] ; then
fi
: ${make=${MAKE-make}}
-: ${install=${INSTALL-install}}
+
# We prefer python 3.x. A bare 'python' is traditionally
# python 2.x, but some distros have it as python 3.x, so
# we check that too
@@ -1006,11 +960,7 @@ if test "$mingw32" = "yes" ; then
HOST_DSOSUF=".dll"
# MinGW needs -mthreads for TLS and macro _MT.
CFLAGS="-mthreads $CFLAGS"
- LIBS="-lwinmm -lws2_32 $LIBS"
write_c_skeleton;
- if compile_prog "" "-liberty" ; then
- LIBS="-liberty $LIBS"
- fi
prefix="c:/Program Files/QEMU"
qemu_suffix=""
libs_qga="-lws2_32 -lwinmm -lpowrprof -lwtsapi32 -lwininet -liphlpapi -lnetapi32 $libs_qga"
@@ -1043,7 +993,7 @@ for opt do
;;
--make=*) make="$optarg"
;;
- --install=*) install="$optarg"
+ --install=*)
;;
--python=*) python="$optarg" ; explicit_python=yes
;;
@@ -1824,7 +1774,6 @@ Advanced options (experts only):
--cross-cc-ARCH=CC use compiler when building ARCH guest test cases
--cross-cc-flags-ARCH= use compiler flags when building ARCH guest tests
--make=MAKE use specified make [$make]
- --install=INSTALL use specified install [$install]
--python=PYTHON use specified python [$python]
--sphinx-build=SPHINX use specified sphinx-build [$sphinx_build]
--meson=MESON use specified meson [$meson]
@@ -2054,9 +2003,6 @@ fi
if test "$meson" = git; then
git_submodules="${git_submodules} meson"
fi
-if test "$git_update" = yes; then
- (cd "${source_path}" && GIT="$git" "./scripts/git-submodule.sh" update "$git_submodules")
-fi
case "$meson" in
git | internal)
@@ -2342,18 +2288,6 @@ fi
# Solaris specific configure tool chain decisions
if test "$solaris" = "yes" ; then
- if has $install; then
- :
- else
- error_exit "Solaris install program not found. Use --install=/usr/ucb/install or" \
- "install fileutils from www.blastwave.org using pkg-get -i fileutils" \
- "to get ginstall which is used by default (which lives in /opt/csw/bin)"
- fi
- if test "$(path_of $install)" = "/usr/sbin/install" ; then
- error_exit "Solaris /usr/sbin/install is not an appropriate install program." \
- "try ginstall from the GNU fileutils available from www.blastwave.org" \
- "using pkg-get -i fileutils, or use --install=/usr/ucb/install"
- fi
if has ar; then
:
else
@@ -2744,7 +2678,6 @@ if test "$xen" != "no" ; then
if $pkg_config --exists xentoolcore; then
xen_pc="$xen_pc xentoolcore"
fi
- QEMU_CFLAGS="$QEMU_CFLAGS $($pkg_config --cflags $xen_pc)"
xen_cflags="$($pkg_config --cflags $xen_pc)"
xen_libs="$($pkg_config --libs $xen_pc)"
else
@@ -3129,8 +3062,6 @@ if test "$gnutls" != "no"; then
# At least ubuntu 18.04 ships only shared libraries.
write_c_skeleton
if compile_prog "" "$gnutls_libs" ; then
- LIBS="$gnutls_libs $LIBS"
- QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
pass="yes"
fi
fi
@@ -3200,8 +3131,6 @@ if test "$nettle" != "no"; then
# Link test to make sure the given libraries work (e.g for static).
write_c_skeleton
if compile_prog "" "$nettle_libs" ; then
- LIBS="$nettle_libs $LIBS"
- QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
if test -z "$gcrypt"; then
gcrypt="no"
fi
@@ -3244,8 +3173,6 @@ if test "$gcrypt" != "no"; then
# Link test to make sure the given libraries work (e.g for static).
write_c_skeleton
if compile_prog "" "$gcrypt_libs" ; then
- LIBS="$gcrypt_libs $LIBS"
- QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
pass="yes"
fi
fi
@@ -3813,24 +3740,22 @@ if test "$plugins" = yes; then
glib_modules="$glib_modules gmodule-2.0"
fi
-# This workaround is required due to a bug in pkg-config file for glib as it
-# doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
-
-if test "$static" = yes && test "$mingw32" = yes; then
- QEMU_CFLAGS="-DGLIB_STATIC_COMPILATION $QEMU_CFLAGS"
-fi
-
for i in $glib_modules; do
if $pkg_config --atleast-version=$glib_req_ver $i; then
glib_cflags=$($pkg_config --cflags $i)
glib_libs=$($pkg_config --libs $i)
- QEMU_CFLAGS="$glib_cflags $QEMU_CFLAGS"
- LIBS="$glib_libs $LIBS"
else
error_exit "glib-$glib_req_ver $i is required to compile QEMU"
fi
done
+# This workaround is required due to a bug in pkg-config file for glib as it
+# doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
+
+if test "$static" = yes && test "$mingw32" = yes; then
+ glib_cflags="-DGLIB_STATIC_COMPILATION $glib_cflags"
+fi
+
if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then
gio=yes
gio_cflags=$($pkg_config --cflags gio-2.0)
@@ -3865,7 +3790,7 @@ int main(void) {
}
EOF
-if ! compile_prog "$CFLAGS" "$LIBS" ; then
+if ! compile_prog "$glib_cflags" "$glib_libs" ; then
error_exit "sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T."\
"You probably need to set PKG_CONFIG_LIBDIR"\
"to point to the right pkg-config files for your"\
@@ -3880,7 +3805,7 @@ EOF
if ! compile_prog "$glib_cflags -Werror" "$glib_libs" ; then
if cc_has_warning_flag "-Wno-unknown-attributes"; then
glib_cflags="-Wno-unknown-attributes $glib_cflags"
- QEMU_CFLAGS="-Wno-unknown-attributes $CFLAGS"
+ CFLAGS="-Wno-unknown-attributes $CFLAGS"
fi
fi
@@ -4128,11 +4053,6 @@ if test "$linux_io_uring" != "no" ; then
linux_io_uring_cflags=$($pkg_config --cflags liburing)
linux_io_uring_libs=$($pkg_config --libs liburing)
linux_io_uring=yes
-
- # io_uring is used in libqemuutil.a where per-file -libs variables are not
- # seen by programs linking the archive. It's not ideal, but just add the
- # library dependency globally.
- LIBS="$linux_io_uring_libs $LIBS"
else
if test "$linux_io_uring" = "yes" ; then
feature_not_found "linux io_uring" "Install liburing devel"
@@ -4177,7 +4097,6 @@ EOF
elif compile_prog "-DCONFIG_LIBATTR" "-lattr" ; then
attr=yes
libattr_libs="-lattr"
- LIBS="$libattr_libs $LIBS"
libattr=yes
else
if test "$attr" = "yes" ; then
@@ -4262,11 +4181,8 @@ EOF
if test -d "${source_path}/dtc/libfdt" || test -e "${source_path}/.git" ; then
fdt=git
mkdir -p dtc
- if [ "$pwd_is_source_path" != "y" ] ; then
- symlink "$source_path/dtc/Makefile" "dtc/Makefile"
- fi
fdt_cflags="-I${source_path}/dtc/libfdt"
- fdt_ldflags="-L$PWD/dtc/libfdt"
+ fdt_ldflags="-Ldtc/libfdt"
fdt_libs="$fdt_libs"
elif test "$fdt" = "yes" ; then
# Not a git build & no libfdt found, prompt for system install
@@ -4299,7 +4215,6 @@ if test "$opengl" != "no" ; then
if test "$gtk" = "yes" && $pkg_config --exists "$gtkpackage >= 3.16"; then
gtk_gl="yes"
fi
- QEMU_CFLAGS="$QEMU_CFLAGS $opengl_cflags"
else
if test "$opengl" = "yes" ; then
feature_not_found "opengl" "Please install opengl (mesa) devel pkgs: $opengl_pkgs"
@@ -5004,20 +4919,6 @@ if test "$libiscsi" != "no" ; then
fi
##########################################
-# Do we need libm
-cat > $TMPC << EOF
-#include <math.h>
-int main(int argc, char **argv) { return isnan(sin((double)argc)); }
-EOF
-if compile_prog "" "" ; then
- :
-elif compile_prog "" "-lm" ; then
- LIBS="-lm $LIBS"
-else
- error_exit "libm check failed"
-fi
-
-##########################################
# Do we need librt
# uClibc provides 2 versions of clock_gettime(), one with realtime
# support and one without. This means that the clock_gettime() don't
@@ -5039,7 +4940,7 @@ elif compile_prog "" "$pthread_lib -lrt" ; then
LIBS="$LIBS -lrt"
fi
-# Check whether we need to link libutil for openpty()
+# Check whether we have openpty() in either libc or libutil
cat > $TMPC << EOF
extern int openpty(int *am, int *as, char *name, void *termp, void *winp);
int main(void) { return openpty(0, 0, 0, 0, 0); }
@@ -5050,7 +4951,6 @@ if compile_prog "" "" ; then
have_openpty="yes"
else
if compile_prog "" "-lutil" ; then
- libs_tools="-lutil $libs_tools"
have_openpty="yes"
fi
fi
@@ -5068,7 +4968,6 @@ EOF
$pkg_config --atleast-version=0.12.3 spice-protocol && \
compile_prog "$spice_cflags" "$spice_libs" ; then
spice="yes"
- QEMU_CFLAGS="$QEMU_CFLAGS $spice_cflags"
else
if test "$spice" = "yes" ; then
feature_not_found "spice" \
@@ -5251,20 +5150,18 @@ case "$capstone" in
git_submodules="${git_submodules} capstone"
fi
mkdir -p capstone
- QEMU_CFLAGS="$QEMU_CFLAGS -I${source_path}/capstone/include"
if test "$mingw32" = "yes"; then
LIBCAPSTONE=capstone.lib
else
LIBCAPSTONE=libcapstone.a
fi
- capstone_libs="-L$PWD/capstone -lcapstone"
+ capstone_libs="-Lcapstone -lcapstone"
capstone_cflags="-I${source_path}/capstone/include"
;;
system)
capstone_libs="$($pkg_config --libs capstone)"
capstone_cflags="$($pkg_config --cflags capstone)"
- QEMU_CFLAGS="$QEMU_CFLAGS $($pkg_config --cflags capstone)"
;;
no)
@@ -5413,8 +5310,6 @@ EOF
else
urcu_bp_libs="-lurcu-bp"
fi
-
- LIBS="$lttng_ust_libs $urcu_bp_libs $LIBS"
else
error_exit "Trace backend 'ust' missing lttng-ust header files"
fi
@@ -6153,7 +6048,7 @@ fi
##########################################
# checks for fuzzer
-if test "$fuzzing" = "yes" ; then
+if test "$fuzzing" = "yes" && test -z "${LIB_FUZZING_ENGINE+xxx}"; then
write_c_fuzzer_skeleton
if compile_prog "$CPU_CFLAGS -Werror -fsanitize=fuzzer" ""; then
have_fuzzer=yes
@@ -6195,7 +6090,6 @@ if test "$libpmem" != "no"; then
libpmem="yes"
libpmem_libs=$($pkg_config --libs libpmem)
libpmem_cflags=$($pkg_config --cflags libpmem)
- QEMU_CFLAGS="$QEMU_CFLAGS $libpmem_cflags"
else
if test "$libpmem" = "yes" ; then
feature_not_found "libpmem" "Install nvml or pmdk"
@@ -6212,7 +6106,6 @@ if test "$libdaxctl" != "no"; then
libdaxctl="yes"
libdaxctl_libs=$($pkg_config --libs libdaxctl)
libdaxctl_cflags=$($pkg_config --cflags libdaxctl)
- QEMU_CFLAGS="$QEMU_CFLAGS $libdaxctl_cflags"
else
if test "$libdaxctl" = "yes" ; then
feature_not_found "libdaxctl" "Install libdaxctl"
@@ -6257,8 +6150,8 @@ case "$slirp" in
git_submodules="${git_submodules} slirp"
fi
mkdir -p slirp
- slirp_cflags="-I${source_path}/slirp/src -I$PWD/slirp/src"
- slirp_libs="-L$PWD/slirp -lslirp"
+ slirp_cflags="-I${source_path}/slirp/src -Islirp/src"
+ slirp_libs="-Lslirp -lslirp"
if test "$mingw32" = "yes" ; then
slirp_libs="$slirp_libs -lws2_32 -liphlpapi"
fi
@@ -6313,28 +6206,6 @@ but not implemented on your system"
fi
##########################################
-# check for usable keyutils.h
-
-if test "$linux" = "yes" ; then
-
- have_keyutils=no
- cat > $TMPC << EOF
-#include <errno.h>
-#include <asm/unistd.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <keyutils.h>
-int main(void) {
- return request_key("user", NULL, NULL, 0);
-}
-EOF
- if compile_prog "" "-lkeyutils"; then
- have_keyutils=yes
- fi
-fi
-
-
-##########################################
# End of CC checks
# After here, no more $cc or $ld runs
@@ -6417,11 +6288,6 @@ if test "$libudev" != "no" ; then
fi
fi
-# Now we've finished running tests it's OK to add -Werror to the compiler flags
-if test "$werror" = "yes"; then
- QEMU_CFLAGS="-Werror $QEMU_CFLAGS"
-fi
-
# Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
if test "$solaris" = "no" && test "$tsan" = "no"; then
if $ld --version 2>/dev/null | grep "GNU ld" >/dev/null 2>/dev/null ; then
@@ -6632,20 +6498,15 @@ else
cxx=
fi
-echo_version() {
- if test "$1" = "yes" ; then
- echo "($2)"
- fi
-}
-
-# prepend ftd flags after all config tests are done
-QEMU_CFLAGS="$fdt_cflags $QEMU_CFLAGS"
-QEMU_LDFLAGS="$fdt_ldflags $QEMU_LDFLAGS"
+if test $git_update = 'yes' ; then
+ (cd "${source_path}" && GIT="$git" "./scripts/git-submodule.sh" update "$git_submodules")
+fi
+if test "$fdt" = "git" ; then
+ symlink "$source_path/dtc/Makefile" "dtc/Makefile"
+fi
config_host_mak="config-host.mak"
-echo "# Automatically generated by configure - do not modify" >config-all-disas.mak
-
echo "# Automatically generated by configure - do not modify" > $config_host_mak
echo >> $config_host_mak
@@ -7147,6 +7008,7 @@ fi
if test "$opengl" = "yes" ; then
echo "CONFIG_OPENGL=y" >> $config_host_mak
+ echo "OPENGL_CFLAGS=$opengl_cflags" >> $config_host_mak
echo "OPENGL_LIBS=$opengl_libs" >> $config_host_mak
if test "$opengl_dmabuf" = "yes" ; then
echo "CONFIG_OPENGL_DMABUF=y" >> $config_host_mak
@@ -7492,12 +7354,18 @@ if test "$have_mlockall" = "yes" ; then
echo "HAVE_MLOCKALL=y" >> $config_host_mak
fi
if test "$fuzzing" = "yes" ; then
- QEMU_CFLAGS="$QEMU_CFLAGS -fsanitize=fuzzer-no-link"
+ # If LIB_FUZZING_ENGINE is set, assume we are running on OSS-Fuzz, and the
+ # needed CFLAGS have already been provided
+ if test -z "${LIB_FUZZING_ENGINE+xxx}" ; then
+ QEMU_CFLAGS="$QEMU_CFLAGS -fsanitize=fuzzer-no-link"
+ FUZZ_EXE_LDFLAGS="-fsanitize=fuzzer"
+ else
+ FUZZ_EXE_LDFLAGS="$LIB_FUZZING_ENGINE"
+ fi
fi
if test "$plugins" = "yes" ; then
echo "CONFIG_PLUGIN=y" >> $config_host_mak
- LIBS="-ldl $LIBS"
# Copy the export object list to the build dir
if test "$ld_dynamic_list" = "yes" ; then
echo "CONFIG_HAS_LD_DYNAMIC_LIST=yes" >> $config_host_mak
@@ -7522,9 +7390,6 @@ fi
if test "$secret_keyring" = "yes" ; then
echo "CONFIG_SECRET_KEYRING=y" >> $config_host_mak
- if test "$have_keyutils" = "yes" ; then
- echo "CONFIG_TEST_SECRET_KEYRING=y" >> $config_host_mak
- fi
fi
if test "$tcg_interpreter" = "yes"; then
@@ -7545,11 +7410,6 @@ fi
echo "ROMS=$roms" >> $config_host_mak
echo "MAKE=$make" >> $config_host_mak
-echo "INSTALL=$install" >> $config_host_mak
-echo "INSTALL_DIR=$install -d -m 0755" >> $config_host_mak
-echo "INSTALL_DATA=$install -c -m 0644" >> $config_host_mak
-echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak
-echo "INSTALL_LIB=$install -c -m 0644" >> $config_host_mak
echo "PYTHON=$python" >> $config_host_mak
echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak
echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
@@ -7572,7 +7432,6 @@ echo "NM=$nm" >> $config_host_mak
echo "PKG_CONFIG=$pkg_config_exe" >> $config_host_mak
echo "WINDRES=$windres" >> $config_host_mak
echo "CFLAGS=$CFLAGS" >> $config_host_mak
-echo "CXXFLAGS=$CXXFLAGS" >> $config_host_mak
echo "CFLAGS_NOPIE=$CFLAGS_NOPIE" >> $config_host_mak
echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
echo "QEMU_CXXFLAGS=$QEMU_CXXFLAGS" >> $config_host_mak
@@ -7584,14 +7443,10 @@ if test "$sparse" = "yes" ; then
fi
echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
-echo "LD_REL_FLAGS=$LD_REL_FLAGS" >> $config_host_mak
echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak
-echo "LIBS+=$LIBS" >> $config_host_mak
-echo "LIBS_TOOLS+=$libs_tools" >> $config_host_mak
echo "PTHREAD_LIB=$PTHREAD_LIB" >> $config_host_mak
echo "EXESUF=$EXESUF" >> $config_host_mak
echo "HOST_DSOSUF=$HOST_DSOSUF" >> $config_host_mak
-echo "LDFLAGS_SHARED=$LDFLAGS_SHARED" >> $config_host_mak
echo "LIBS_QGA=$libs_qga" >> $config_host_mak
echo "TASN1_LIBS=$tasn1_libs" >> $config_host_mak
echo "TASN1_CFLAGS=$tasn1_cflags" >> $config_host_mak
@@ -7607,6 +7462,7 @@ fi
if test "$fuzzing" != "no"; then
echo "CONFIG_FUZZ=y" >> $config_host_mak
fi
+echo "FUZZ_EXE_LDFLAGS=$FUZZ_EXE_LDFLAGS" >> $config_host_mak
if test "$edk2_blobs" = "yes" ; then
echo "DECOMPRESS_EDK2_BLOBS=y" >> $config_host_mak
@@ -7752,7 +7608,6 @@ case "$target_name" in
TARGET_SYSTBL_ABI=common
mttcg="yes"
bflt="yes"
- echo "TARGET_ABI32=y" >> $config_target_mak
;;
mips|mipsel)
mttcg="yes"
@@ -7954,93 +7809,6 @@ if test "$target_bsd_user" = "yes" ; then
echo "CONFIG_BSD_USER=y" >> $config_target_mak
fi
-
-# generate QEMU_CFLAGS/QEMU_LDFLAGS for targets
-
-disas_config() {
- echo "CONFIG_${1}_DIS=y" >> $config_target_mak
- echo "CONFIG_${1}_DIS=y" >> config-all-disas.mak
-}
-
-for i in $ARCH $TARGET_BASE_ARCH ; do
- case "$i" in
- alpha)
- disas_config "ALPHA"
- ;;
- aarch64)
- if test -n "${cxx}"; then
- disas_config "ARM_A64"
- fi
- ;;
- arm)
- disas_config "ARM"
- if test -n "${cxx}"; then
- disas_config "ARM_A64"
- fi
- ;;
- avr)
- disas_config "AVR"
- ;;
- cris)
- disas_config "CRIS"
- ;;
- hppa)
- disas_config "HPPA"
- ;;
- i386|x86_64|x32)
- disas_config "I386"
- ;;
- lm32)
- disas_config "LM32"
- ;;
- m68k)
- disas_config "M68K"
- ;;
- microblaze*)
- disas_config "MICROBLAZE"
- ;;
- mips*)
- disas_config "MIPS"
- if test -n "${cxx}"; then
- disas_config "NANOMIPS"
- fi
- ;;
- moxie*)
- disas_config "MOXIE"
- ;;
- nios2)
- disas_config "NIOS2"
- ;;
- or1k)
- disas_config "OPENRISC"
- ;;
- ppc*)
- disas_config "PPC"
- ;;
- riscv*)
- disas_config "RISCV"
- ;;
- rx)
- disas_config "RX"
- ;;
- s390*)
- disas_config "S390"
- ;;
- sh4)
- disas_config "SH4"
- ;;
- sparc*)
- disas_config "SPARC"
- ;;
- xtensa*)
- disas_config "XTENSA"
- ;;
- esac
-done
-if test "$tcg_interpreter" = "yes" ; then
- disas_config "TCI"
-fi
-
done # for target in $targets
if [ "$fdt" = "git" ]; then
@@ -8113,7 +7881,7 @@ do
done
mkdir -p $DIRS
for f in $LINKS ; do
- if [ -e "$source_path/$f" ] && [ "$pwd_is_source_path" != "y" ]; then
+ if [ -e "$source_path/$f" ]; then
symlink "$source_path/$f" "$f"
fi
done
@@ -8168,6 +7936,9 @@ echo "ar = $(meson_quote $ar)" >> $cross
echo "nm = $(meson_quote $nm)" >> $cross
echo "pkgconfig = $(meson_quote $pkg_config_exe)" >> $cross
echo "ranlib = $(meson_quote $ranlib)" >> $cross
+if has $sdl2_config; then
+ echo "sdl2-config = $(meson_quote $sdl2_config)" >> $cross
+fi
echo "strip = $(meson_quote $strip)" >> $cross
echo "windres = $(meson_quote $windres)" >> $cross
if test -n "$cross_prefix"; then
diff --git a/disas/meson.build b/disas/meson.build
index 0527d69128..bde8280c73 100644
--- a/disas/meson.build
+++ b/disas/meson.build
@@ -22,6 +22,4 @@ common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
common_ss.add(when: 'CONFIG_SPARC_DIS', if_true: files('sparc.c'))
common_ss.add(when: 'CONFIG_XTENSA_DIS', if_true: files('xtensa.c'))
-# TODO: As long as the TCG interpreter and its generated code depend
-# on the QEMU target, we cannot compile the disassembler here.
-#common_ss.add(when: 'CONFIG_TCI_DIS', if_true: files('tci.c'))
+specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('tci.c'))
diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst
index 0c09fb9a54..08e85c69e1 100644
--- a/docs/devel/build-system.rst
+++ b/docs/devel/build-system.rst
@@ -125,27 +125,27 @@ developers in checking for system features:
`compile_object $CFLAGS`
Attempt to compile a test program with the system C compiler using
$CFLAGS. The test program must have been previously written to a file
- called $TMPC.
+ called $TMPC. The replacement in Meson is the compiler object `cc`,
+ which has methods such as `cc.compiles()`,
+ `cc.check_header()`, `cc.has_function()`.
`compile_prog $CFLAGS $LDFLAGS`
Attempt to compile a test program with the system C compiler using
$CFLAGS and link it with the system linker using $LDFLAGS. The test
program must have been previously written to a file called $TMPC.
+ The replacement in Meson is `cc.find_library()` and `cc.links()`.
`has $COMMAND`
Determine if $COMMAND exists in the current environment, either as a
- shell builtin, or executable binary, returning 0 on success.
-
-`path_of $COMMAND`
- Return the fully qualified path of $COMMAND, printing it to stdout,
- and returning 0 on success.
+ shell builtin, or executable binary, returning 0 on success. The
+ replacement in Meson is `find_program()`.
`check_define $NAME`
Determine if the macro $NAME is defined by the system C compiler
`check_include $NAME`
Determine if the include $NAME file is available to the system C
- compiler
+ compiler. The replacement in Meson is `cc.has_header()`.
`write_c_skeleton`
Write a minimal C program main() function to the temporary file
@@ -179,7 +179,7 @@ process for:
- Userspace emulators - qemu-$ARCH
- - Some (but not all) unit tests
+ - Unit tests
2) documentation
@@ -204,8 +204,9 @@ are then turned into static libraries as follows::
chardev = declare_dependency(link_whole: libchardev)
-The special `.fa` suffix is needed as long as unit tests are built with
-the older Makefile infrastructure, and will go away later.
+As of Meson 0.55.1, the special `.fa` suffix should be used for everything
+that is used with `link_whole`, to ensure that the link flags are placed
+correctly in the command line.
Files linked into emulator targets there can be split into two distinct groups
of files, those which are independent of the QEMU emulation target and
@@ -221,7 +222,8 @@ only in system emulators, `user_ss` only in user-mode emulators.
In the target-dependent set lives CPU emulation, device emulation and
much glue code. This sometimes also has to be compiled multiple times,
-once for each target being built.
+once for each target being built. Target-dependent files are included
+in the `specific_ss` sourceset.
All binaries link with a static library `libqemuutil.a`, which is then
linked to all the binaries. `libqemuutil.a` is built from several
@@ -300,84 +302,9 @@ The resulting build system is largely non-recursive in nature, in
contrast to common practices seen with automake.
Tests are also ran by the Makefile with the traditional `make check`
-phony target. Meson test suites such as `unit` can be ran with `make
-check-unit` too. It is also possible to run tests defined in meson.build
-with `meson test`.
-
-The following text is only relevant for unit tests which still have to
-be converted to Meson.
-
-All binaries should link to `libqemuutil.a`, e.g.:
-
- qemu-img$(EXESUF): qemu-img.o ..snip.. libqemuutil.a
-
-On Windows, all binaries have the suffix `.exe`, so all Makefile rules
-which create binaries must include the $(EXESUF) variable on the binary
-name. e.g.
-
- qemu-img$(EXESUF): qemu-img.o ..snip..
-
-This expands to `.exe` on Windows, or an empty string on other platforms.
-
-Variable naming
----------------
-
-The QEMU convention is to define variables to list different groups of
-object files. These are named with the convention $PREFIX-obj-y. The
-Meson `chardev` variable in the previous example corresponds to a
-variable 'chardev-obj-y'.
-
-Likewise, tests that are executed by `make check-unit` are grouped into
-a variable check-unit-y, like this:
-
- check-unit-y += tests/test-visitor-serialization$(EXESUF)
- check-unit-y += tests/test-iov$(EXESUF)
- check-unit-y += tests/test-bitmap$(EXESUF)
-
-When a test or object file which needs to be conditionally built based
-on some characteristic of the host system, the configure script will
-define a variable for the conditional. For example, on Windows it will
-define $(CONFIG_POSIX) with a value of 'n' and $(CONFIG_WIN32) with a
-value of 'y'. It is now possible to use the config variables when
-listing object files. For example,
-
- check-unit-$(CONFIG_POSIX) += tests/test-vmstate$(EXESUF)
-
-On Windows this expands to
-
- check-unit-n += tests/vmstate.exe
-
-Since the `check-unit` target only runs tests included in `$(check-unit-y)`,
-POSIX specific tests listed in `$(util-obj-n)` are ignored on the Windows
-platform builds.
-
-
-CFLAGS / LDFLAGS / LIBS handling
---------------------------------
-
-There are many different binaries being built with differing purposes,
-and some of them might even be 3rd party libraries pulled in via git
-submodules. As such the use of the global CFLAGS variable is generally
-avoided in QEMU, since it would apply to too many build targets.
-
-Flags that are needed by any QEMU code (i.e. everything *except* GIT
-submodule projects) are put in $(QEMU_CFLAGS) variable. For linker
-flags the $(LIBS) variable is sometimes used, but a couple of more
-targeted variables are preferred.
-
-In addition to these variables, it is possible to provide cflags and
-libs against individual source code files, by defining variables of the
-form $FILENAME-cflags and $FILENAME-libs. For example, the test
-test-crypto-tlscredsx509 needs to link to the libtasn1 library,
-so tests/Makefile.include defines some variables:
-
- tests/crypto-tls-x509-helpers.o-cflags := $(TASN1_CFLAGS)
- tests/crypto-tls-x509-helpers.o-libs := $(TASN1_LIBS)
-
-The scope is a little different between the two variables. The libs get
-used when linking any target binary that includes the curl.o object
-file, while the cflags get used when compiling the curl.c file only.
-
+phony target, while benchmarks are run with `make bench`. Meson test
+suites such as `unit` can be ran with `make check-unit` too. It is also
+possible to run tests defined in meson.build with `meson test`.
Important files for the build system
====================================
@@ -401,15 +328,9 @@ number of dynamically created files listed later.
executables. Build rules for various subdirectories are included in
other meson.build files spread throughout the QEMU source tree.
-`rules.mak`
- This file provides the generic helper rules for invoking build tools, in
- particular the compiler and linker.
-
`tests/Makefile.include`
- Rules for building the unit tests. This file is included directly by the
- top level Makefile, so anything defined in this file will influence the
- entire build system. Care needs to be taken when writing rules for tests
- to ensure they only apply to the unit test execution / build.
+ Rules for external test harnesses. These include the TCG tests,
+ `qemu-iotests` and the Avocado-based acceptance tests.
`tests/docker/Makefile.include`
Rules for Docker tests. Like tests/Makefile, this file is included
diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index f3e7ced212..9eede44350 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -835,6 +835,8 @@ Double the '=' for a subsection title:
# == Subsection title
+Both are only permitted in free-form documentation.
+
'|' denotes examples:
# | Text of the example, may span
diff --git a/exec.c b/exec.c
index 7683afb6a8..e34b602bdf 100644
--- a/exec.c
+++ b/exec.c
@@ -899,6 +899,7 @@ Property cpu_common_props[] = {
DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION,
MemoryRegion *),
#endif
+ DEFINE_PROP_BOOL("start-powered-off", CPUState, start_powered_off, false),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 1ae5e17eeb..8480b7f37d 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -1,5 +1,5 @@
arm_ss = ss.source_set()
-arm_ss.add(files('boot.c'))
+arm_ss.add(files('boot.c'), fdt)
arm_ss.add(when: 'CONFIG_PLATFORM_BUS', if_true: files('sysbus-fdt.c'))
arm_ss.add(when: 'CONFIG_ARM_VIRT', if_true: files('virt.c'))
arm_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
diff --git a/hw/core/cpu.c b/hw/core/cpu.c
index 22bc3f974a..8f65383ffb 100644
--- a/hw/core/cpu.c
+++ b/hw/core/cpu.c
@@ -258,7 +258,7 @@ static void cpu_common_reset(DeviceState *dev)
}
cpu->interrupt_request = 0;
- cpu->halted = 0;
+ cpu->halted = cpu->start_powered_off;
cpu->mem_io_pc = 0;
cpu->icount_extra = 0;
atomic_set(&cpu->icount_decr_ptr->u32, 0);
diff --git a/hw/display/artist.c b/hw/display/artist.c
index 71982559c6..955296d3d8 100644
--- a/hw/display/artist.c
+++ b/hw/display/artist.c
@@ -192,6 +192,10 @@ static const char *artist_reg_name(uint64_t addr)
}
#undef REG_NAME
+/* artist has a fixed line length of 2048 bytes. */
+#define ADDR_TO_Y(addr) extract32(addr, 11, 11)
+#define ADDR_TO_X(addr) extract32(addr, 0, 11)
+
static int16_t artist_get_x(uint32_t reg)
{
return reg >> 16;
@@ -348,13 +352,13 @@ static void artist_invalidate_cursor(ARTISTState *s)
y, s->cursor_height);
}
-static void vram_bit_write(ARTISTState *s, int posx, int posy, bool incr_x,
+static void vram_bit_write(ARTISTState *s, int posy, bool incr_x,
int size, uint32_t data)
{
struct vram_buffer *buf;
uint32_t vram_bitmask = s->vram_bitmask;
int mask, i, pix_count, pix_length;
- unsigned int offset, width;
+ unsigned int posx, offset, width;
uint8_t *data8, *p;
pix_count = vram_write_pix_per_transfer(s);
@@ -366,6 +370,8 @@ static void vram_bit_write(ARTISTState *s, int posx, int posy, bool incr_x,
if (s->cmap_bm_access) {
offset = s->vram_pos;
} else {
+ posx = ADDR_TO_X(s->vram_pos >> 2);
+ posy += ADDR_TO_Y(s->vram_pos >> 2);
offset = posy * width + posx;
}
@@ -858,7 +864,6 @@ static void artist_reg_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
ARTISTState *s = opaque;
- int posx, posy;
int width, height;
trace_artist_reg_write(size, addr, artist_reg_name(addr & ~3ULL), val);
@@ -881,16 +886,12 @@ static void artist_reg_write(void *opaque, hwaddr addr, uint64_t val,
break;
case VRAM_WRITE_INCR_Y:
- posx = (s->vram_pos >> 2) & 0x7ff;
- posy = (s->vram_pos >> 13) & 0x3ff;
- vram_bit_write(s, posx, posy + s->vram_char_y++, false, size, val);
+ vram_bit_write(s, s->vram_char_y++, false, size, val);
break;
case VRAM_WRITE_INCR_X:
case VRAM_WRITE_INCR_X2:
- posx = (s->vram_pos >> 2) & 0x7ff;
- posy = (s->vram_pos >> 13) & 0x3ff;
- vram_bit_write(s, posx, posy + s->vram_char_y, true, size, val);
+ vram_bit_write(s, s->vram_char_y, true, size, val);
break;
case VRAM_IDX:
@@ -1156,8 +1157,7 @@ static void artist_vram_write(void *opaque, hwaddr addr, uint64_t val,
{
ARTISTState *s = opaque;
struct vram_buffer *buf;
- int posy = (addr >> 11) & 0x3ff;
- int posx = addr & 0x7ff;
+ unsigned int posy, posx;
unsigned int offset;
trace_artist_vram_write(size, addr, val);
@@ -1170,6 +1170,9 @@ static void artist_vram_write(void *opaque, hwaddr addr, uint64_t val,
}
buf = vram_write_buffer(s);
+ posy = ADDR_TO_Y(addr);
+ posx = ADDR_TO_X(addr);
+
if (!buf->size) {
return;
}
@@ -1212,7 +1215,7 @@ static uint64_t artist_vram_read(void *opaque, hwaddr addr, unsigned size)
ARTISTState *s = opaque;
struct vram_buffer *buf;
uint64_t val;
- int posy, posx;
+ unsigned int posy, posx;
if (s->cmap_bm_access) {
buf = &s->vram_buffer[ARTIST_BUFFER_CMAP];
@@ -1229,8 +1232,8 @@ static uint64_t artist_vram_read(void *opaque, hwaddr addr, unsigned size)
return 0;
}
- posy = (addr >> 13) & 0x3ff;
- posx = (addr >> 2) & 0x7ff;
+ posy = ADDR_TO_Y(addr);
+ posx = ADDR_TO_X(addr);
if (posy > buf->height || posx > buf->width) {
return 0;
@@ -1374,6 +1377,18 @@ static void artist_realizefn(DeviceState *dev, Error **errp)
struct vram_buffer *buf;
hwaddr offset = 0;
+ if (s->width > 2048 || s->height > 2048) {
+ error_report("artist: screen size can not exceed 2048 x 2048 pixel.");
+ s->width = MIN(s->width, 2048);
+ s->height = MIN(s->height, 2048);
+ }
+
+ if (s->width < 640 || s->height < 480) {
+ error_report("artist: minimum screen size is 640 x 480 pixel.");
+ s->width = MAX(s->width, 640);
+ s->height = MAX(s->height, 480);
+ }
+
memory_region_init(&s->mem_as_root, OBJECT(dev), "artist", ~0ull);
address_space_init(&s->as, &s->mem_as_root, "artist");
diff --git a/hw/hppa/hppa_hardware.h b/hw/hppa/hppa_hardware.h
index cdb7fa6240..bc258895c9 100644
--- a/hw/hppa/hppa_hardware.h
+++ b/hw/hppa/hppa_hardware.h
@@ -38,8 +38,7 @@
#define PORT_PCI_CMD (PCI_HPA + DINO_PCI_ADDR)
#define PORT_PCI_DATA (PCI_HPA + DINO_CONFIG_DATA)
-/* QEMU fw_cfg interface port */
-#define QEMU_FW_CFG_IO_BASE (MEMORY_HPA + 0x80)
+#define FW_CFG_IO_BASE 0xfffa0000
#define PORT_SERIAL1 (DINO_UART_HPA + 0x800)
#define PORT_SERIAL2 (LASI_UART_HPA + 0x800)
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 90aeefe2a4..d5164457ee 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -12,6 +12,7 @@
#include "qemu/error-report.h"
#include "sysemu/reset.h"
#include "sysemu/sysemu.h"
+#include "sysemu/runstate.h"
#include "hw/rtc/mc146818rtc.h"
#include "hw/timer/i8254.h"
#include "hw/char/serial.h"
@@ -27,6 +28,30 @@
#define MIN_SEABIOS_HPPA_VERSION 1 /* require at least this fw version */
+#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)
+
+static void hppa_powerdown_req(Notifier *n, void *opaque)
+{
+ hwaddr soft_power_reg = HPA_POWER_BUTTON;
+ uint32_t val;
+
+ val = ldl_be_phys(&address_space_memory, soft_power_reg);
+ if ((val >> 8) == 0) {
+ /* immediately shut down when under hardware control */
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+ return;
+ }
+
+ /* clear bit 31 to indicate that the power switch was pressed. */
+ val &= ~1;
+ stl_be_phys(&address_space_memory, soft_power_reg, val);
+}
+
+static Notifier hppa_system_powerdown_notifier = {
+ .notify = hppa_powerdown_req
+};
+
+
static ISABus *hppa_isa_bus(void)
{
ISABus *isa_bus;
@@ -58,12 +83,18 @@ static uint64_t cpu_hppa_to_phys(void *opaque, uint64_t addr)
static HPPACPU *cpu[HPPA_MAX_CPUS];
static uint64_t firmware_entry;
+static void fw_cfg_boot_set(void *opaque, const char *boot_device,
+ Error **errp)
+{
+ fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
+}
+
static FWCfgState *create_fw_cfg(MachineState *ms)
{
FWCfgState *fw_cfg;
uint64_t val;
- fw_cfg = fw_cfg_init_mem(QEMU_FW_CFG_IO_BASE, QEMU_FW_CFG_IO_BASE + 4);
+ fw_cfg = fw_cfg_init_mem(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4);
fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus);
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, HPPA_MAX_CPUS);
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ram_size);
@@ -72,6 +103,21 @@ static FWCfgState *create_fw_cfg(MachineState *ms)
fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version",
g_memdup(&val, sizeof(val)), sizeof(val));
+ val = cpu_to_le64(HPPA_TLB_ENTRIES);
+ fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries",
+ g_memdup(&val, sizeof(val)), sizeof(val));
+
+ val = cpu_to_le64(HPPA_BTLB_ENTRIES);
+ fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries",
+ g_memdup(&val, sizeof(val)), sizeof(val));
+
+ val = cpu_to_le64(HPA_POWER_BUTTON);
+ fw_cfg_add_file(fw_cfg, "/etc/power-button-addr",
+ g_memdup(&val, sizeof(val)), sizeof(val));
+
+ fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_order[0]);
+ qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
+
return fw_cfg;
}
@@ -160,6 +206,9 @@ static void machine_hppa_init(MachineState *machine)
}
}
+ /* register power switch emulation */
+ qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier);
+
/* Load firmware. Given that this is not "real" firmware,
but one explicitly written for the emulation, we might as
well load it directly from an ELF image. */
@@ -273,6 +322,9 @@ static void machine_hppa_init(MachineState *machine)
/* tell firmware how many SMP CPUs to present in inventory table */
cpu[0]->env.gr[21] = smp_cpus;
+
+ /* tell firmware fw_cfg port */
+ cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
}
static void hppa_machine_reset(MachineState *ms)
@@ -300,6 +352,8 @@ static void hppa_machine_reset(MachineState *ms)
cpu[0]->env.gr[24] = 'c';
/* gr22/gr23 unused, no initrd while reboot. */
cpu[0]->env.gr[21] = smp_cpus;
+ /* tell firmware fw_cfg port */
+ cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
}
diff --git a/hw/input/adb.c b/hw/input/adb.c
index 013fcc9c54..84331b9fce 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -309,6 +309,7 @@ static void adb_device_class_init(ObjectClass *oc, void *data)
static const TypeInfo adb_device_type_info = {
.name = TYPE_ADB_DEVICE,
.parent = TYPE_DEVICE,
+ .class_size = sizeof(ADBDeviceClass),
.instance_size = sizeof(ADBDevice),
.abstract = true,
.class_init = adb_device_class_init,
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 4bd0d606ba..1fa09f287a 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -595,6 +595,7 @@ static Property spapr_xive_properties[] = {
DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
DEFINE_PROP_UINT64("vc-base", SpaprXive, vc_base, SPAPR_XIVE_VC_BASE),
DEFINE_PROP_UINT64("tm-base", SpaprXive, tm_base, SPAPR_XIVE_TM_BASE),
+ DEFINE_PROP_UINT8("hv-prio", SpaprXive, hv_prio, 7),
DEFINE_PROP_END_OF_LIST(),
};
@@ -692,12 +693,13 @@ static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
cpu_to_be32(16), /* 64K */
};
/*
- * The following array is in sync with the reserved priorities
- * defined by the 'spapr_xive_priority_is_reserved' routine.
+ * QEMU/KVM only needs to define a single range to reserve the
+ * escalation priority. A priority bitmask would have been more
+ * appropriate.
*/
uint32_t plat_res_int_priorities[] = {
- cpu_to_be32(7), /* start */
- cpu_to_be32(0xf8), /* count */
+ cpu_to_be32(xive->hv_prio), /* start */
+ cpu_to_be32(0xff - xive->hv_prio), /* count */
};
/* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
@@ -844,19 +846,12 @@ type_init(spapr_xive_register_types)
*/
/*
- * Linux hosts under OPAL reserve priority 7 for their own escalation
- * interrupts (DD2.X POWER9). So we only allow the guest to use
- * priorities [0..6].
+ * On POWER9, the KVM XIVE device uses priority 7 for the escalation
+ * interrupts. So we only allow the guest to use priorities [0..6].
*/
-static bool spapr_xive_priority_is_reserved(uint8_t priority)
+static bool spapr_xive_priority_is_reserved(SpaprXive *xive, uint8_t priority)
{
- switch (priority) {
- case 0 ... 6:
- return false;
- case 7: /* OPAL escalation queue */
- default:
- return true;
- }
+ return priority >= xive->hv_prio;
}
/*
@@ -1053,7 +1048,7 @@ static target_ulong h_int_set_source_config(PowerPCCPU *cpu,
new_eas.w = eas.w & cpu_to_be64(~EAS_MASKED);
}
- if (spapr_xive_priority_is_reserved(priority)) {
+ if (spapr_xive_priority_is_reserved(xive, priority)) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
" is reserved\n", priority);
return H_P4;
@@ -1212,7 +1207,7 @@ static target_ulong h_int_get_queue_info(PowerPCCPU *cpu,
* This is not needed when running the emulation under QEMU
*/
- if (spapr_xive_priority_is_reserved(priority)) {
+ if (spapr_xive_priority_is_reserved(xive, priority)) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
" is reserved\n", priority);
return H_P3;
@@ -1299,7 +1294,7 @@ static target_ulong h_int_set_queue_config(PowerPCCPU *cpu,
* This is not needed when running the emulation under QEMU
*/
- if (spapr_xive_priority_is_reserved(priority)) {
+ if (spapr_xive_priority_is_reserved(xive, priority)) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
" is reserved\n", priority);
return H_P3;
@@ -1466,7 +1461,7 @@ static target_ulong h_int_get_queue_config(PowerPCCPU *cpu,
* This is not needed when running the emulation under QEMU
*/
- if (spapr_xive_priority_is_reserved(priority)) {
+ if (spapr_xive_priority_is_reserved(xive, priority)) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
" is reserved\n", priority);
return H_P3;
diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index e8667ce5f6..66bf4c06fe 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -36,10 +36,9 @@ typedef struct KVMEnabledCPU {
static QLIST_HEAD(, KVMEnabledCPU)
kvm_enabled_cpus = QLIST_HEAD_INITIALIZER(&kvm_enabled_cpus);
-static bool kvm_cpu_is_enabled(CPUState *cs)
+static bool kvm_cpu_is_enabled(unsigned long vcpu_id)
{
KVMEnabledCPU *enabled_cpu;
- unsigned long vcpu_id = kvm_arch_vcpu_id(cs);
QLIST_FOREACH(enabled_cpu, &kvm_enabled_cpus, node) {
if (enabled_cpu->vcpu_id == vcpu_id) {
@@ -147,6 +146,45 @@ int kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp)
return s.ret;
}
+/*
+ * Allocate the vCPU IPIs from the vCPU context. This will allocate
+ * the XIVE IPI interrupt on the chip on which the vCPU is running.
+ * This gives a better distribution of IPIs when the guest has a lot
+ * of vCPUs. When the vCPUs are pinned, this will make the IPI local
+ * to the chip of the vCPU. It will reduce rerouting between interrupt
+ * controllers and gives better performance.
+ */
+typedef struct {
+ SpaprXive *xive;
+ Error *err;
+ int rc;
+} XiveInitIPI;
+
+static void kvmppc_xive_reset_ipi_on_cpu(CPUState *cs, run_on_cpu_data arg)
+{
+ unsigned long ipi = kvm_arch_vcpu_id(cs);
+ XiveInitIPI *s = arg.host_ptr;
+ uint64_t state = 0;
+
+ s->rc = kvm_device_access(s->xive->fd, KVM_DEV_XIVE_GRP_SOURCE, ipi,
+ &state, true, &s->err);
+}
+
+static int kvmppc_xive_reset_ipi(SpaprXive *xive, CPUState *cs, Error **errp)
+{
+ XiveInitIPI s = {
+ .xive = xive,
+ .err = NULL,
+ .rc = 0,
+ };
+
+ run_on_cpu(cs, kvmppc_xive_reset_ipi_on_cpu, RUN_ON_CPU_HOST_PTR(&s));
+ if (s.err) {
+ error_propagate(errp, s.err);
+ }
+ return s.rc;
+}
+
int kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp)
{
ERRP_GUARD();
@@ -157,7 +195,7 @@ int kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp)
assert(xive->fd != -1);
/* Check if CPU was hot unplugged and replugged. */
- if (kvm_cpu_is_enabled(tctx->cs)) {
+ if (kvm_cpu_is_enabled(kvm_arch_vcpu_id(tctx->cs))) {
return 0;
}
@@ -176,6 +214,12 @@ int kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp)
return ret;
}
+ /* Create/reset the vCPU IPI */
+ ret = kvmppc_xive_reset_ipi(xive, tctx->cs, errp);
+ if (ret < 0) {
+ return ret;
+ }
+
kvm_cpu_enable(tctx->cs);
return 0;
}
@@ -235,6 +279,12 @@ int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
assert(xive->fd != -1);
+ /*
+ * The vCPU IPIs are now allocated in kvmppc_xive_cpu_connect()
+ * and not with all sources in kvmppc_xive_source_reset()
+ */
+ assert(srcno >= SPAPR_XIRQ_BASE);
+
if (xive_source_irq_is_lsi(xsrc, srcno)) {
state |= KVM_XIVE_LEVEL_SENSITIVE;
if (xsrc->status[srcno] & XIVE_STATUS_ASSERTED) {
@@ -246,12 +296,28 @@ int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
true, errp);
}
+/*
+ * To be valid, a source must have been claimed by the machine (valid
+ * entry in the EAS table) and if it is a vCPU IPI, the vCPU should
+ * have been enabled, which means the IPI has been allocated in
+ * kvmppc_xive_cpu_connect().
+ */
+static bool xive_source_is_valid(SpaprXive *xive, int i)
+{
+ return xive_eas_is_valid(&xive->eat[i]) &&
+ (i >= SPAPR_XIRQ_BASE || kvm_cpu_is_enabled(i));
+}
+
static int kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp)
{
SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
int i;
- for (i = 0; i < xsrc->nr_irqs; i++) {
+ /*
+ * Skip the vCPU IPIs. These are created/reset when the vCPUs are
+ * connected in kvmppc_xive_cpu_connect()
+ */
+ for (i = SPAPR_XIRQ_BASE; i < xsrc->nr_irqs; i++) {
int ret;
if (!xive_eas_is_valid(&xive->eat[i])) {
@@ -333,7 +399,7 @@ static void kvmppc_xive_source_get_state(XiveSource *xsrc)
for (i = 0; i < xsrc->nr_irqs; i++) {
uint8_t pq;
- if (!xive_eas_is_valid(&xive->eat[i])) {
+ if (!xive_source_is_valid(xive, i)) {
continue;
}
@@ -516,7 +582,7 @@ static void kvmppc_xive_change_state_handler(void *opaque, int running,
uint8_t pq;
uint8_t old_pq;
- if (!xive_eas_is_valid(&xive->eat[i])) {
+ if (!xive_source_is_valid(xive, i)) {
continue;
}
@@ -544,7 +610,7 @@ static void kvmppc_xive_change_state_handler(void *opaque, int running,
for (i = 0; i < xsrc->nr_irqs; i++) {
uint8_t pq;
- if (!xive_eas_is_valid(&xive->eat[i])) {
+ if (!xive_source_is_valid(xive, i)) {
continue;
}
@@ -647,22 +713,22 @@ int kvmppc_xive_post_load(SpaprXive *xive, int version_id)
}
}
+ /*
+ * We can only restore the source config if the source has been
+ * previously set in KVM. Since we don't do that at reset time
+ * when restoring a VM, let's do it now.
+ */
+ ret = kvmppc_xive_source_reset(&xive->source, &local_err);
+ if (ret < 0) {
+ goto fail;
+ }
+
/* Restore the EAT */
for (i = 0; i < xive->nr_irqs; i++) {
- if (!xive_eas_is_valid(&xive->eat[i])) {
+ if (!xive_source_is_valid(xive, i)) {
continue;
}
- /*
- * We can only restore the source config if the source has been
- * previously set in KVM. Since we don't do that for all interrupts
- * at reset time anymore, let's do it now.
- */
- ret = kvmppc_xive_source_reset_one(&xive->source, i, &local_err);
- if (ret < 0) {
- goto fail;
- }
-
ret = kvmppc_xive_set_source_config(xive, i, &xive->eat[i], &local_err);
if (ret < 0) {
goto fail;
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index e49fc86eb8..159db6cbe2 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -200,9 +200,9 @@ petalogix_ml605_init(MachineState *machine)
}
/* setup PVR to match kernel settings */
- cpu->env.pvr.regs[4] = 0xc56b8000;
- cpu->env.pvr.regs[5] = 0xc56be000;
- cpu->env.pvr.regs[10] = 0x0e000000; /* virtex 6 */
+ cpu->cfg.pvr_regs[4] = 0xc56b8000;
+ cpu->cfg.pvr_regs[5] = 0xc56be000;
+ cpu->cfg.pvr_regs[10] = 0x0e000000; /* virtex 6 */
microblaze_load_kernel(cpu, MEMORY_BASEADDR, ram_size,
machine->initrd_filename,
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 615e1a1ad2..23c0f87e41 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -52,9 +52,6 @@ static void main_cpu_reset(void *opaque)
CPUState *cs = CPU(cpu);
cpu_reset(cs);
-
- /* All VPs are halted on reset. Leave powering up to CPC. */
- cs->halted = 1;
}
static bool cpu_mips_itu_supported(CPUMIPSState *env)
@@ -76,7 +73,17 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
bool saar_present = false;
for (i = 0; i < s->num_vp; i++) {
- cpu = MIPS_CPU(cpu_create(s->cpu_type));
+ cpu = MIPS_CPU(object_new(s->cpu_type));
+
+ /* All VPs are halted on reset. Leave powering up to CPC. */
+ if (!object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
+ errp)) {
+ return;
+ }
+
+ if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
+ return;
+ }
/* Init internal devices */
cpu_mips_irq_init_cpu(cpu);
diff --git a/hw/mips/meson.build b/hw/mips/meson.build
index 6ac9dc4cff..46294b7382 100644
--- a/hw/mips/meson.build
+++ b/hw/mips/meson.build
@@ -4,7 +4,7 @@ mips_ss.add(when: 'CONFIG_FULOONG', if_true: files('fuloong2e.c'))
mips_ss.add(when: 'CONFIG_JAZZ', if_true: files('jazz.c'))
mips_ss.add(when: 'CONFIG_MALTA', if_true: files('gt64xxx_pci.c', 'malta.c'))
mips_ss.add(when: 'CONFIG_MIPSSIM', if_true: files('mipssim.c'))
-mips_ss.add(when: 'CONFIG_MIPS_BOSTON', if_true: files('boston.c'))
+mips_ss.add(when: 'CONFIG_MIPS_BOSTON', if_true: [files('boston.c'), fdt])
mips_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('cps.c'))
mips_ss.add(when: 'CONFIG_R4K', if_true: files('r4k.c'))
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index ab9884e315..ae39b9358e 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -704,9 +704,6 @@ static void ppce500_cpu_reset_sec(void *opaque)
cpu_reset(cs);
- /* Secondary CPU starts in halted state for now. Needs to change when
- implementing non-kernel boot. */
- cs->halted = 1;
cs->exception_index = EXCP_HLT;
}
@@ -865,7 +862,7 @@ void ppce500_init(MachineState *machine)
CPUState *cs;
qemu_irq *input;
- cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
+ cpu = POWERPC_CPU(object_new(machine->cpu_type));
env = &cpu->env;
cs = CPU(cpu);
@@ -875,6 +872,14 @@ void ppce500_init(MachineState *machine)
exit(1);
}
+ /*
+ * Secondary CPU starts in halted state for now. Needs to change
+ * when implementing non-kernel boot.
+ */
+ object_property_set_bool(OBJECT(cs), "start-powered-off", i != 0,
+ &error_fatal);
+ qdev_realize_and_unref(DEVICE(cs), NULL, &error_fatal);
+
if (!firstenv) {
firstenv = env;
}
diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 918969b320..ffa2ec37fa 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -25,7 +25,8 @@ ppc_ss.add(when: 'CONFIG_PSERIES', if_true: files(
'spapr_irq.c',
'spapr_tpm_proxy.c',
'spapr_nvdimm.c',
- 'spapr_rtas_ddw.c'
+ 'spapr_rtas_ddw.c',
+ 'spapr_numa.c',
))
ppc_ss.add(when: 'CONFIG_SPAPR_RNG', if_true: files('spapr_rng.c'))
ppc_ss.add(when: ['CONFIG_PSERIES', 'CONFIG_LINUX'], if_true: files(
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index 2e1a03daa4..67ebb16c4d 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -140,6 +140,27 @@ static uint16_t bytes_to_blocks(uint32_t bytes)
return bytes >> BLOCK_SHIFT;
}
+static uint32_t blocks_to_bytes(uint16_t blocks)
+{
+ return blocks << BLOCK_SHIFT;
+}
+
+static int hiomap_erase(PnvPnor *pnor, uint32_t offset, uint32_t size)
+{
+ MemTxResult result;
+ int i;
+
+ for (i = 0; i < size / 4; i++) {
+ result = memory_region_dispatch_write(&pnor->mmio, offset + i * 4,
+ 0xFFFFFFFF, MO_32,
+ MEMTXATTRS_UNSPECIFIED);
+ if (result != MEMTX_OK) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
static void hiomap_cmd(IPMIBmcSim *ibs, uint8_t *cmd, unsigned int cmd_len,
RspBuffer *rsp)
{
@@ -155,10 +176,16 @@ static void hiomap_cmd(IPMIBmcSim *ibs, uint8_t *cmd, unsigned int cmd_len,
switch (cmd[2]) {
case HIOMAP_C_MARK_DIRTY:
case HIOMAP_C_FLUSH:
- case HIOMAP_C_ERASE:
case HIOMAP_C_ACK:
break;
+ case HIOMAP_C_ERASE:
+ if (hiomap_erase(pnor, blocks_to_bytes(cmd[5] << 8 | cmd[4]),
+ blocks_to_bytes(cmd[7] << 8 | cmd[6]))) {
+ rsp_buffer_set_error(rsp, IPMI_CC_UNSPECIFIED);
+ }
+ break;
+
case HIOMAP_C_GET_INFO:
rsp_buffer_push(rsp, 2); /* Version 2 */
rsp_buffer_push(rsp, BLOCK_SHIFT); /* block size */
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index b5ffa48dac..23f1e09492 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -646,7 +646,6 @@ static void pnv_lpc_power8_class_init(ObjectClass *klass, void *data)
static const TypeInfo pnv_lpc_power8_info = {
.name = TYPE_PNV8_LPC,
.parent = TYPE_PNV_LPC,
- .instance_size = sizeof(PnvLpcController),
.class_init = pnv_lpc_power8_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_PNV_XSCOM_INTERFACE },
@@ -687,7 +686,6 @@ static void pnv_lpc_power9_class_init(ObjectClass *klass, void *data)
static const TypeInfo pnv_lpc_power9_info = {
.name = TYPE_PNV9_LPC,
.parent = TYPE_PNV_LPC,
- .instance_size = sizeof(PnvLpcController),
.class_init = pnv_lpc_power9_class_init,
};
@@ -768,6 +766,7 @@ static void pnv_lpc_class_init(ObjectClass *klass, void *data)
static const TypeInfo pnv_lpc_info = {
.name = TYPE_PNV_LPC,
.parent = TYPE_DEVICE,
+ .instance_size = sizeof(PnvLpcController),
.class_init = pnv_lpc_class_init,
.class_size = sizeof(PnvLpcClass),
.abstract = true,
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index 3ea47df71f..503ef46b39 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -256,10 +256,7 @@ static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level)
qemu_irq *pci_irqs = opaque;
trace_ppc4xx_pci_set_irq(irq_num);
- if (irq_num < 0) {
- fprintf(stderr, "%s: PCI irq %d\n", __func__, irq_num);
- return;
- }
+ assert(irq_num >= 0);
qemu_set_irq(pci_irqs[irq_num], level);
}
@@ -320,7 +317,8 @@ static void ppc4xx_pcihost_realize(DeviceState *dev, Error **errp)
b = pci_register_root_bus(dev, NULL, ppc4xx_pci_set_irq,
ppc4xx_pci_map_irq, s->irq, get_system_memory(),
- get_system_io(), 0, 4, TYPE_PCI_BUS);
+ get_system_io(), 0, ARRAY_SIZE(s->irq),
+ TYPE_PCI_BUS);
h->bus = b;
pci_create_simple(b, 0, "ppc4xx-host-bridge");
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index dd2fa4826b..9bce1892b5 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -81,6 +81,7 @@
#include "hw/mem/memory-device.h"
#include "hw/ppc/spapr_tpm_proxy.h"
#include "hw/ppc/spapr_nvdimm.h"
+#include "hw/ppc/spapr_numa.h"
#include "monitor/monitor.h"
@@ -201,21 +202,6 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
return ret;
}
-static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
-{
- int index = spapr_get_vcpu_id(cpu);
- uint32_t associativity[] = {cpu_to_be32(0x5),
- cpu_to_be32(0x0),
- cpu_to_be32(0x0),
- cpu_to_be32(0x0),
- cpu_to_be32(cpu->node_id),
- cpu_to_be32(index)};
-
- /* Advertise NUMA via ibm,associativity */
- return fdt_setprop(fdt, offset, "ibm,associativity", associativity,
- sizeof(associativity));
-}
-
static void spapr_dt_pa_features(SpaprMachineState *spapr,
PowerPCCPU *cpu,
void *fdt, int offset)
@@ -313,14 +299,9 @@ static void add_str(GString *s, const gchar *s1)
g_string_append_len(s, s1, strlen(s1) + 1);
}
-static int spapr_dt_memory_node(void *fdt, int nodeid, hwaddr start,
- hwaddr size)
+static int spapr_dt_memory_node(SpaprMachineState *spapr, void *fdt, int nodeid,
+ hwaddr start, hwaddr size)
{
- uint32_t associativity[] = {
- cpu_to_be32(0x4), /* length */
- cpu_to_be32(0x0), cpu_to_be32(0x0),
- cpu_to_be32(0x0), cpu_to_be32(nodeid)
- };
char mem_name[32];
uint64_t mem_reg_property[2];
int off;
@@ -334,8 +315,7 @@ static int spapr_dt_memory_node(void *fdt, int nodeid, hwaddr start,
_FDT((fdt_setprop_string(fdt, off, "device_type", "memory")));
_FDT((fdt_setprop(fdt, off, "reg", mem_reg_property,
sizeof(mem_reg_property))));
- _FDT((fdt_setprop(fdt, off, "ibm,associativity", associativity,
- sizeof(associativity))));
+ spapr_numa_write_associativity_dt(spapr, fdt, off, nodeid);
return off;
}
@@ -555,13 +535,10 @@ static int spapr_dt_dynamic_reconfiguration_memory(SpaprMachineState *spapr,
void *fdt)
{
MachineState *machine = MACHINE(spapr);
- int nb_numa_nodes = machine->numa_state->num_nodes;
- int ret, i, offset;
+ int ret, offset;
uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE;
uint32_t prop_lmb_size[] = {cpu_to_be32(lmb_size >> 32),
cpu_to_be32(lmb_size & 0xffffffff)};
- uint32_t *int_buf, *cur_index, buf_len;
- int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1;
MemoryDeviceInfoList *dimms = NULL;
/*
@@ -602,25 +579,7 @@ static int spapr_dt_dynamic_reconfiguration_memory(SpaprMachineState *spapr,
return ret;
}
- /* ibm,associativity-lookup-arrays */
- buf_len = (nr_nodes * 4 + 2) * sizeof(uint32_t);
- cur_index = int_buf = g_malloc0(buf_len);
- int_buf[0] = cpu_to_be32(nr_nodes);
- int_buf[1] = cpu_to_be32(4); /* Number of entries per associativity list */
- cur_index += 2;
- for (i = 0; i < nr_nodes; i++) {
- uint32_t associativity[] = {
- cpu_to_be32(0x0),
- cpu_to_be32(0x0),
- cpu_to_be32(0x0),
- cpu_to_be32(i)
- };
- memcpy(cur_index, associativity, sizeof(associativity));
- cur_index += 4;
- }
- ret = fdt_setprop(fdt, offset, "ibm,associativity-lookup-arrays", int_buf,
- (cur_index - int_buf) * sizeof(uint32_t));
- g_free(int_buf);
+ ret = spapr_numa_write_assoc_lookup_arrays(spapr, fdt, offset);
return ret;
}
@@ -648,7 +607,7 @@ static int spapr_dt_memory(SpaprMachineState *spapr, void *fdt)
if (!mem_start) {
/* spapr_machine_init() checks for rma_size <= node0_size
* already */
- spapr_dt_memory_node(fdt, i, 0, spapr->rma_size);
+ spapr_dt_memory_node(spapr, fdt, i, 0, spapr->rma_size);
mem_start += spapr->rma_size;
node_size -= spapr->rma_size;
}
@@ -660,7 +619,7 @@ static int spapr_dt_memory(SpaprMachineState *spapr, void *fdt)
sizetmp = 1ULL << ctzl(mem_start);
}
- spapr_dt_memory_node(fdt, i, mem_start, sizetmp);
+ spapr_dt_memory_node(spapr, fdt, i, mem_start, sizetmp);
node_size -= sizetmp;
mem_start += sizetmp;
}
@@ -790,7 +749,7 @@ static void spapr_dt_cpu(CPUState *cs, void *fdt, int offset,
pft_size_prop, sizeof(pft_size_prop))));
if (ms->numa_state->num_nodes > 1) {
- _FDT(spapr_fixup_cpu_numa_dt(fdt, offset, cpu));
+ _FDT(spapr_numa_fixup_cpu_dt(spapr, fdt, offset, cpu));
}
_FDT(spapr_fixup_cpu_smt_dt(fdt, offset, cpu, compat_smt));
@@ -891,16 +850,9 @@ static int spapr_dt_rng(void *fdt)
static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
{
MachineState *ms = MACHINE(spapr);
- SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms);
int rtas;
GString *hypertas = g_string_sized_new(256);
GString *qemu_hypertas = g_string_sized_new(256);
- uint32_t refpoints[] = {
- cpu_to_be32(0x4),
- cpu_to_be32(0x4),
- cpu_to_be32(0x2),
- };
- uint32_t nr_refpoints = ARRAY_SIZE(refpoints);
uint64_t max_device_addr = MACHINE(spapr)->device_memory->base +
memory_region_size(&MACHINE(spapr)->device_memory->mr);
uint32_t lrdr_capacity[] = {
@@ -910,14 +862,6 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE & 0xffffffff),
cpu_to_be32(ms->smp.max_cpus / ms->smp.threads),
};
- uint32_t maxdomain = cpu_to_be32(spapr->gpu_numa_id > 1 ? 1 : 0);
- uint32_t maxdomains[] = {
- cpu_to_be32(4),
- maxdomain,
- maxdomain,
- maxdomain,
- cpu_to_be32(spapr->gpu_numa_id),
- };
_FDT(rtas = fdt_add_subnode(fdt, 0, "rtas"));
@@ -953,15 +897,7 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
qemu_hypertas->str, qemu_hypertas->len));
g_string_free(qemu_hypertas, TRUE);
- if (smc->pre_5_1_assoc_refpoints) {
- nr_refpoints = 2;
- }
-
- _FDT(fdt_setprop(fdt, rtas, "ibm,associativity-reference-points",
- refpoints, nr_refpoints * sizeof(refpoints[0])));
-
- _FDT(fdt_setprop(fdt, rtas, "ibm,max-associativity-domains",
- maxdomains, sizeof(maxdomains)));
+ spapr_numa_write_rtas_dt(spapr, fdt, rtas);
/*
* FWNMI reserves RTAS_ERROR_LOG_MAX for the machine check error log,
@@ -1297,7 +1233,7 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space)
/* NVDIMM devices */
if (mc->nvdimm_supported) {
- spapr_dt_persistent_memory(fdt);
+ spapr_dt_persistent_memory(spapr, fdt);
}
return fdt;
@@ -2832,6 +2768,9 @@ static void spapr_machine_init(MachineState *machine)
*/
spapr->gpu_numa_id = MAX(1, machine->numa_state->num_nodes);
+ /* Init numa_assoc_array */
+ spapr_numa_associativity_init(spapr, machine);
+
if ((!kvm_enabled() || kvmppc_has_cap_mmu_radix()) &&
ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, 0,
spapr->max_compat_pvr)) {
@@ -3416,7 +3355,7 @@ int spapr_lmb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
addr = spapr_drc_index(drc) * SPAPR_MEMORY_BLOCK_SIZE;
node = object_property_get_uint(OBJECT(drc->dev), PC_DIMM_NODE_PROP,
&error_abort);
- *fdt_start_offset = spapr_dt_memory_node(fdt, node, addr,
+ *fdt_start_offset = spapr_dt_memory_node(spapr, fdt, node, addr,
SPAPR_MEMORY_BLOCK_SIZE);
return 0;
}
@@ -3520,7 +3459,6 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
{
const SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev);
SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
- const MachineClass *mc = MACHINE_CLASS(smc);
bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
PCDIMMDevice *dimm = PC_DIMM(dev);
Error *local_err = NULL;
@@ -3533,27 +3471,22 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
- if (is_nvdimm && !mc->nvdimm_supported) {
- error_setg(errp, "NVDIMM hotplug not supported for this machine");
- return;
- }
-
size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
- if (!is_nvdimm && size % SPAPR_MEMORY_BLOCK_SIZE) {
- error_setg(errp, "Hotplugged memory size must be a multiple of "
- "%" PRIu64 " MB", SPAPR_MEMORY_BLOCK_SIZE / MiB);
- return;
- } else if (is_nvdimm) {
- spapr_nvdimm_validate_opts(NVDIMM(dev), size, &local_err);
+ if (is_nvdimm) {
+ spapr_nvdimm_validate(hotplug_dev, NVDIMM(dev), size, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
+ } else if (size % SPAPR_MEMORY_BLOCK_SIZE) {
+ error_setg(errp, "Hotplugged memory size must be a multiple of "
+ "%" PRIu64 " MB", SPAPR_MEMORY_BLOCK_SIZE / MiB);
+ return;
}
memdev = object_property_get_link(OBJECT(dimm), PC_DIMM_MEMDEV_PROP,
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index c4f47dcc04..2125fdac34 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -36,11 +36,6 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
cpu_reset(cs);
- /* All CPUs start halted. CPU0 is unhalted from the machine level
- * reset code and the rest are explicitly started up by the guest
- * using an RTAS call */
- cs->halted = 1;
-
env->spr[SPR_HIOR] = 0;
lpcr = env->spr[SPR_LPCR];
@@ -274,6 +269,11 @@ static PowerPCCPU *spapr_create_vcpu(SpaprCpuCore *sc, int i, Error **errp)
cs = CPU(obj);
cpu = POWERPC_CPU(obj);
+ /*
+ * All CPUs start halted. CPU0 is unhalted from the machine level reset code
+ * and the rest are explicitly started up by the guest using an RTAS call.
+ */
+ cs->start_powered_off = true;
cs->cpu_index = cc->core_id + i;
spapr_set_vcpu_id(cpu, cs->cpu_index, &local_err);
if (local_err) {
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index c1d01228c6..c2776b6a7d 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1873,42 +1873,6 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
return ret;
}
-static target_ulong h_home_node_associativity(PowerPCCPU *cpu,
- SpaprMachineState *spapr,
- target_ulong opcode,
- target_ulong *args)
-{
- target_ulong flags = args[0];
- target_ulong procno = args[1];
- PowerPCCPU *tcpu;
- int idx;
-
- /* only support procno from H_REGISTER_VPA */
- if (flags != 0x1) {
- return H_FUNCTION;
- }
-
- tcpu = spapr_find_cpu(procno);
- if (tcpu == NULL) {
- return H_P2;
- }
-
- /* sequence is the same as in the "ibm,associativity" property */
-
- idx = 0;
-#define ASSOCIATIVITY(a, b) (((uint64_t)(a) << 32) | \
- ((uint64_t)(b) & 0xffffffff))
- args[idx++] = ASSOCIATIVITY(0, 0);
- args[idx++] = ASSOCIATIVITY(0, tcpu->node_id);
- args[idx++] = ASSOCIATIVITY(procno, -1);
- for ( ; idx < 6; idx++) {
- args[idx] = -1;
- }
-#undef ASSOCIATIVITY
-
- return H_SUCCESS;
-}
-
static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
SpaprMachineState *spapr,
target_ulong opcode,
@@ -2139,10 +2103,6 @@ static void hypercall_register_types(void)
spapr_register_hypercall(KVMPPC_H_CAS, h_client_architecture_support);
spapr_register_hypercall(KVMPPC_H_UPDATE_DT, h_update_dt);
-
- /* Virtual Processor Home Node */
- spapr_register_hypercall(H_HOME_NODE_ASSOCIATIVITY,
- h_home_node_associativity);
}
type_init(hypercall_register_types)
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 72bb938375..f59960339e 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -172,7 +172,7 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
* To cover both and not confuse the OS, add an early failure in
* QEMU.
*/
- if (spapr->irq == &spapr_irq_xive) {
+ if (!spapr->irq->xics) {
error_setg(errp, "XIVE-only machines require a POWER9 CPU");
return -1;
}
diff --git a/hw/ppc/spapr_numa.c b/hw/ppc/spapr_numa.c
new file mode 100644
index 0000000000..64fe567f5d
--- /dev/null
+++ b/hw/ppc/spapr_numa.c
@@ -0,0 +1,242 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition NUMA associativity handling
+ *
+ * Copyright IBM Corp. 2020
+ *
+ * Authors:
+ * Daniel Henrique Barboza <danielhb413@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/ppc/spapr_numa.h"
+#include "hw/pci-host/spapr.h"
+#include "hw/ppc/fdt.h"
+
+/* Moved from hw/ppc/spapr_pci_nvlink2.c */
+#define SPAPR_GPU_NUMA_ID (cpu_to_be32(1))
+
+void spapr_numa_associativity_init(SpaprMachineState *spapr,
+ MachineState *machine)
+{
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ int nb_numa_nodes = machine->numa_state->num_nodes;
+ int i, j, max_nodes_with_gpus;
+
+ /*
+ * For all associativity arrays: first position is the size,
+ * position MAX_DISTANCE_REF_POINTS is always the numa_id,
+ * represented by the index 'i'.
+ *
+ * This will break on sparse NUMA setups, when/if QEMU starts
+ * to support it, because there will be no more guarantee that
+ * 'i' will be a valid node_id set by the user.
+ */
+ for (i = 0; i < nb_numa_nodes; i++) {
+ spapr->numa_assoc_array[i][0] = cpu_to_be32(MAX_DISTANCE_REF_POINTS);
+ spapr->numa_assoc_array[i][MAX_DISTANCE_REF_POINTS] = cpu_to_be32(i);
+ }
+
+ /*
+ * Initialize NVLink GPU associativity arrays. We know that
+ * the first GPU will take the first available NUMA id, and
+ * we'll have a maximum of NVGPU_MAX_NUM GPUs in the machine.
+ * At this point we're not sure if there are GPUs or not, but
+ * let's initialize the associativity arrays and allow NVLink
+ * GPUs to be handled like regular NUMA nodes later on.
+ */
+ max_nodes_with_gpus = nb_numa_nodes + NVGPU_MAX_NUM;
+
+ for (i = nb_numa_nodes; i < max_nodes_with_gpus; i++) {
+ spapr->numa_assoc_array[i][0] = cpu_to_be32(MAX_DISTANCE_REF_POINTS);
+
+ for (j = 1; j < MAX_DISTANCE_REF_POINTS; j++) {
+ uint32_t gpu_assoc = smc->pre_5_1_assoc_refpoints ?
+ SPAPR_GPU_NUMA_ID : cpu_to_be32(i);
+ spapr->numa_assoc_array[i][j] = gpu_assoc;
+ }
+
+ spapr->numa_assoc_array[i][MAX_DISTANCE_REF_POINTS] = cpu_to_be32(i);
+ }
+}
+
+void spapr_numa_write_associativity_dt(SpaprMachineState *spapr, void *fdt,
+ int offset, int nodeid)
+{
+ _FDT((fdt_setprop(fdt, offset, "ibm,associativity",
+ spapr->numa_assoc_array[nodeid],
+ sizeof(spapr->numa_assoc_array[nodeid]))));
+}
+
+static uint32_t *spapr_numa_get_vcpu_assoc(SpaprMachineState *spapr,
+ PowerPCCPU *cpu)
+{
+ uint32_t *vcpu_assoc = g_new(uint32_t, VCPU_ASSOC_SIZE);
+ int index = spapr_get_vcpu_id(cpu);
+
+ /*
+ * VCPUs have an extra 'cpu_id' value in ibm,associativity
+ * compared to other resources. Increment the size at index
+ * 0, put cpu_id last, then copy the remaining associativity
+ * domains.
+ */
+ vcpu_assoc[0] = cpu_to_be32(MAX_DISTANCE_REF_POINTS + 1);
+ vcpu_assoc[VCPU_ASSOC_SIZE - 1] = cpu_to_be32(index);
+ memcpy(vcpu_assoc + 1, spapr->numa_assoc_array[cpu->node_id] + 1,
+ (VCPU_ASSOC_SIZE - 2) * sizeof(uint32_t));
+
+ return vcpu_assoc;
+}
+
+int spapr_numa_fixup_cpu_dt(SpaprMachineState *spapr, void *fdt,
+ int offset, PowerPCCPU *cpu)
+{
+ g_autofree uint32_t *vcpu_assoc = NULL;
+
+ vcpu_assoc = spapr_numa_get_vcpu_assoc(spapr, cpu);
+
+ /* Advertise NUMA via ibm,associativity */
+ return fdt_setprop(fdt, offset, "ibm,associativity", vcpu_assoc,
+ VCPU_ASSOC_SIZE * sizeof(uint32_t));
+}
+
+
+int spapr_numa_write_assoc_lookup_arrays(SpaprMachineState *spapr, void *fdt,
+ int offset)
+{
+ MachineState *machine = MACHINE(spapr);
+ int nb_numa_nodes = machine->numa_state->num_nodes;
+ int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1;
+ uint32_t *int_buf, *cur_index, buf_len;
+ int ret, i;
+
+ /* ibm,associativity-lookup-arrays */
+ buf_len = (nr_nodes * MAX_DISTANCE_REF_POINTS + 2) * sizeof(uint32_t);
+ cur_index = int_buf = g_malloc0(buf_len);
+ int_buf[0] = cpu_to_be32(nr_nodes);
+ /* Number of entries per associativity list */
+ int_buf[1] = cpu_to_be32(MAX_DISTANCE_REF_POINTS);
+ cur_index += 2;
+ for (i = 0; i < nr_nodes; i++) {
+ /*
+ * For the lookup-array we use the ibm,associativity array,
+ * from numa_assoc_array. without the first element (size).
+ */
+ uint32_t *associativity = spapr->numa_assoc_array[i];
+ memcpy(cur_index, ++associativity,
+ sizeof(uint32_t) * MAX_DISTANCE_REF_POINTS);
+ cur_index += MAX_DISTANCE_REF_POINTS;
+ }
+ ret = fdt_setprop(fdt, offset, "ibm,associativity-lookup-arrays", int_buf,
+ (cur_index - int_buf) * sizeof(uint32_t));
+ g_free(int_buf);
+
+ return ret;
+}
+
+/*
+ * Helper that writes ibm,associativity-reference-points and
+ * max-associativity-domains in the RTAS pointed by @rtas
+ * in the DT @fdt.
+ */
+void spapr_numa_write_rtas_dt(SpaprMachineState *spapr, void *fdt, int rtas)
+{
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ uint32_t refpoints[] = {
+ cpu_to_be32(0x4),
+ cpu_to_be32(0x4),
+ cpu_to_be32(0x2),
+ };
+ uint32_t nr_refpoints = ARRAY_SIZE(refpoints);
+ uint32_t maxdomain = cpu_to_be32(spapr->gpu_numa_id > 1 ? 1 : 0);
+ uint32_t maxdomains[] = {
+ cpu_to_be32(4),
+ maxdomain,
+ maxdomain,
+ maxdomain,
+ cpu_to_be32(spapr->gpu_numa_id),
+ };
+
+ if (smc->pre_5_1_assoc_refpoints) {
+ nr_refpoints = 2;
+ }
+
+ _FDT(fdt_setprop(fdt, rtas, "ibm,associativity-reference-points",
+ refpoints, nr_refpoints * sizeof(refpoints[0])));
+
+ _FDT(fdt_setprop(fdt, rtas, "ibm,max-associativity-domains",
+ maxdomains, sizeof(maxdomains)));
+}
+
+static target_ulong h_home_node_associativity(PowerPCCPU *cpu,
+ SpaprMachineState *spapr,
+ target_ulong opcode,
+ target_ulong *args)
+{
+ g_autofree uint32_t *vcpu_assoc = NULL;
+ target_ulong flags = args[0];
+ target_ulong procno = args[1];
+ PowerPCCPU *tcpu;
+ int idx, assoc_idx;
+
+ /* only support procno from H_REGISTER_VPA */
+ if (flags != 0x1) {
+ return H_FUNCTION;
+ }
+
+ tcpu = spapr_find_cpu(procno);
+ if (tcpu == NULL) {
+ return H_P2;
+ }
+
+ /*
+ * Given that we want to be flexible with the sizes and indexes,
+ * we must consider that there is a hard limit of how many
+ * associativities domain we can fit in R4 up to R9, which would be
+ * 12 associativity domains for vcpus. Assert and bail if that's
+ * not the case.
+ */
+ G_STATIC_ASSERT((VCPU_ASSOC_SIZE - 1) <= 12);
+
+ vcpu_assoc = spapr_numa_get_vcpu_assoc(spapr, tcpu);
+ /* assoc_idx starts at 1 to skip associativity size */
+ assoc_idx = 1;
+
+#define ASSOCIATIVITY(a, b) (((uint64_t)(a) << 32) | \
+ ((uint64_t)(b) & 0xffffffff))
+
+ for (idx = 0; idx < 6; idx++) {
+ int32_t a, b;
+
+ /*
+ * vcpu_assoc[] will contain the associativity domains for tcpu,
+ * including tcpu->node_id and procno, meaning that we don't
+ * need to use these variables here.
+ *
+ * We'll read 2 values at a time to fill up the ASSOCIATIVITY()
+ * macro. The ternary will fill the remaining registers with -1
+ * after we went through vcpu_assoc[].
+ */
+ a = assoc_idx < VCPU_ASSOC_SIZE ?
+ be32_to_cpu(vcpu_assoc[assoc_idx++]) : -1;
+ b = assoc_idx < VCPU_ASSOC_SIZE ?
+ be32_to_cpu(vcpu_assoc[assoc_idx++]) : -1;
+
+ args[idx] = ASSOCIATIVITY(a, b);
+ }
+#undef ASSOCIATIVITY
+
+ return H_SUCCESS;
+}
+
+static void spapr_numa_register_types(void)
+{
+ /* Virtual Processor Home Node */
+ spapr_register_hypercall(H_HOME_NODE_ASSOCIATIVITY,
+ h_home_node_associativity);
+}
+
+type_init(spapr_numa_register_types)
diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index 81410aa63f..63872054f3 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -27,16 +27,41 @@
#include "hw/ppc/spapr_nvdimm.h"
#include "hw/mem/nvdimm.h"
#include "qemu/nvdimm-utils.h"
+#include "qemu/option.h"
#include "hw/ppc/fdt.h"
#include "qemu/range.h"
+#include "sysemu/sysemu.h"
+#include "hw/ppc/spapr_numa.h"
-void spapr_nvdimm_validate_opts(NVDIMMDevice *nvdimm, uint64_t size,
- Error **errp)
+void spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
+ uint64_t size, Error **errp)
{
- char *uuidstr = NULL;
+ const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
+ const MachineState *ms = MACHINE(hotplug_dev);
+ const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
+ g_autofree char *uuidstr = NULL;
QemuUUID uuid;
int ret;
+ if (!mc->nvdimm_supported) {
+ error_setg(errp, "NVDIMM hotplug not supported for this machine");
+ return;
+ }
+
+ /*
+ * NVDIMM support went live in 5.1 without considering that, in
+ * other archs, the user needs to enable NVDIMM support with the
+ * 'nvdimm' machine option and the default behavior is NVDIMM
+ * support disabled. It is too late to roll back to the standard
+ * behavior without breaking 5.1 guests. What we can do is to
+ * ensure that, if the user sets nvdimm=off, we error out
+ * regardless of being 5.1 or newer.
+ */
+ if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
+ error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
+ return;
+ }
+
if (object_property_get_int(OBJECT(nvdimm), NVDIMM_LABEL_SIZE_PROP,
&error_abort) == 0) {
error_setg(errp, "PAPR requires NVDIMM devices to have label-size set");
@@ -54,7 +79,6 @@ void spapr_nvdimm_validate_opts(NVDIMMDevice *nvdimm, uint64_t size,
&error_abort);
ret = qemu_uuid_parse(uuidstr, &uuid);
g_assert(!ret);
- g_free(uuidstr);
if (qemu_uuid_is_null(&uuid)) {
error_setg(errp, "NVDIMM device requires the uuid to be set");
@@ -83,16 +107,6 @@ void spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp)
}
}
-int spapr_pmem_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
- void *fdt, int *fdt_start_offset, Error **errp)
-{
- NVDIMMDevice *nvdimm = NVDIMM(drc->dev);
-
- *fdt_start_offset = spapr_dt_nvdimm(fdt, 0, nvdimm);
-
- return 0;
-}
-
void spapr_create_nvdimm_dr_connectors(SpaprMachineState *spapr)
{
MachineState *machine = MACHINE(spapr);
@@ -104,8 +118,8 @@ void spapr_create_nvdimm_dr_connectors(SpaprMachineState *spapr)
}
-int spapr_dt_nvdimm(void *fdt, int parent_offset,
- NVDIMMDevice *nvdimm)
+static int spapr_dt_nvdimm(SpaprMachineState *spapr, void *fdt,
+ int parent_offset, NVDIMMDevice *nvdimm)
{
int child_offset;
char *buf;
@@ -115,11 +129,6 @@ int spapr_dt_nvdimm(void *fdt, int parent_offset,
&error_abort);
uint64_t slot = object_property_get_uint(OBJECT(nvdimm), PC_DIMM_SLOT_PROP,
&error_abort);
- uint32_t associativity[] = {
- cpu_to_be32(0x4), /* length */
- cpu_to_be32(0x0), cpu_to_be32(0x0),
- cpu_to_be32(0x0), cpu_to_be32(node)
- };
uint64_t lsize = nvdimm->label_size;
uint64_t size = object_property_get_int(OBJECT(nvdimm), PC_DIMM_SIZE_PROP,
NULL);
@@ -139,8 +148,7 @@ int spapr_dt_nvdimm(void *fdt, int parent_offset,
_FDT((fdt_setprop_string(fdt, child_offset, "compatible", "ibm,pmemory")));
_FDT((fdt_setprop_string(fdt, child_offset, "device_type", "ibm,pmemory")));
- _FDT((fdt_setprop(fdt, child_offset, "ibm,associativity", associativity,
- sizeof(associativity))));
+ spapr_numa_write_associativity_dt(spapr, fdt, child_offset, node);
buf = qemu_uuid_unparse_strdup(&nvdimm->uuid);
_FDT((fdt_setprop_string(fdt, child_offset, "ibm,unit-guid", buf)));
@@ -161,7 +169,17 @@ int spapr_dt_nvdimm(void *fdt, int parent_offset,
return child_offset;
}
-void spapr_dt_persistent_memory(void *fdt)
+int spapr_pmem_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
+ void *fdt, int *fdt_start_offset, Error **errp)
+{
+ NVDIMMDevice *nvdimm = NVDIMM(drc->dev);
+
+ *fdt_start_offset = spapr_dt_nvdimm(spapr, fdt, 0, nvdimm);
+
+ return 0;
+}
+
+void spapr_dt_persistent_memory(SpaprMachineState *spapr, void *fdt)
{
int offset = fdt_subnode_offset(fdt, 0, "persistent-memory");
GSList *iter, *nvdimms = nvdimm_get_device_list();
@@ -179,7 +197,7 @@ void spapr_dt_persistent_memory(void *fdt)
for (iter = nvdimms; iter; iter = iter->next) {
NVDIMMDevice *nvdimm = iter->data;
- spapr_dt_nvdimm(fdt, offset, nvdimm);
+ spapr_dt_nvdimm(spapr, fdt, offset, nvdimm);
}
g_slist_free(nvdimms);
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 0a418f1e67..4d97ff6c70 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -52,6 +52,7 @@
#include "sysemu/kvm.h"
#include "sysemu/hostmem.h"
#include "sysemu/numa.h"
+#include "hw/ppc/spapr_numa.h"
/* Copied from the kernel arch/powerpc/platforms/pseries/msi.c */
#define RTAS_QUERY_FN 0
@@ -2321,11 +2322,6 @@ int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb,
cpu_to_be32(1),
cpu_to_be32(RTAS_IBM_RESET_PE_DMA_WINDOW)
};
- uint32_t associativity[] = {cpu_to_be32(0x4),
- cpu_to_be32(0x0),
- cpu_to_be32(0x0),
- cpu_to_be32(0x0),
- cpu_to_be32(phb->numa_node)};
SpaprTceTable *tcet;
SpaprDrc *drc;
Error *err = NULL;
@@ -2358,8 +2354,7 @@ int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb,
/* Advertise NUMA via ibm,associativity */
if (phb->numa_node != -1) {
- _FDT(fdt_setprop(fdt, bus_off, "ibm,associativity", associativity,
- sizeof(associativity)));
+ spapr_numa_write_associativity_dt(spapr, fdt, bus_off, phb->numa_node);
}
/* Build the interrupt-map, this must matches what is done
diff --git a/hw/ppc/spapr_pci_nvlink2.c b/hw/ppc/spapr_pci_nvlink2.c
index 76ae77ebc8..8ef9b40a18 100644
--- a/hw/ppc/spapr_pci_nvlink2.c
+++ b/hw/ppc/spapr_pci_nvlink2.c
@@ -26,6 +26,7 @@
#include "qemu-common.h"
#include "hw/pci/pci.h"
#include "hw/pci-host/spapr.h"
+#include "hw/ppc/spapr_numa.h"
#include "qemu/error-report.h"
#include "hw/ppc/fdt.h"
#include "hw/pci/pci_bridge.h"
@@ -37,8 +38,6 @@
#define PHANDLE_NVLINK(phb, gn, nn) (0x00130000 | (((phb)->index) << 8) | \
((gn) << 4) | (nn))
-#define SPAPR_GPU_NUMA_ID (cpu_to_be32(1))
-
typedef struct SpaprPhbPciNvGpuSlot {
uint64_t tgt;
uint64_t gpa;
@@ -360,13 +359,6 @@ void spapr_phb_nvgpu_ram_populate_dt(SpaprPhbState *sphb, void *fdt)
Object *nv_mrobj = object_property_get_link(OBJECT(nvslot->gpdev),
"nvlink2-mr[0]",
&error_abort);
- uint32_t associativity[] = {
- cpu_to_be32(0x4),
- cpu_to_be32(nvslot->numa_id),
- cpu_to_be32(nvslot->numa_id),
- cpu_to_be32(nvslot->numa_id),
- cpu_to_be32(nvslot->numa_id)
- };
uint64_t size = object_property_get_uint(nv_mrobj, "size", NULL);
uint64_t mem_reg[2] = { cpu_to_be64(nvslot->gpa), cpu_to_be64(size) };
char *mem_name = g_strdup_printf("memory@%"PRIx64, nvslot->gpa);
@@ -376,14 +368,8 @@ void spapr_phb_nvgpu_ram_populate_dt(SpaprPhbState *sphb, void *fdt)
_FDT((fdt_setprop_string(fdt, off, "device_type", "memory")));
_FDT((fdt_setprop(fdt, off, "reg", mem_reg, sizeof(mem_reg))));
- if (sphb->pre_5_1_assoc) {
- associativity[1] = SPAPR_GPU_NUMA_ID;
- associativity[2] = SPAPR_GPU_NUMA_ID;
- associativity[3] = SPAPR_GPU_NUMA_ID;
- }
-
- _FDT((fdt_setprop(fdt, off, "ibm,associativity", associativity,
- sizeof(associativity))));
+ spapr_numa_write_associativity_dt(SPAPR_MACHINE(qdev_get_machine()),
+ fdt, off, nvslot->numa_id);
_FDT((fdt_setprop_string(fdt, off, "compatible",
"ibm,coherent-device-memory")));
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
index 25af9db75e..fe2ea75f65 100644
--- a/hw/riscv/meson.build
+++ b/hw/riscv/meson.build
@@ -1,5 +1,5 @@
riscv_ss = ss.source_set()
-riscv_ss.add(files('boot.c'))
+riscv_ss.add(files('boot.c'), fdt)
riscv_ss.add(files('numa.c'))
riscv_ss.add(when: 'CONFIG_HART', if_true: files('riscv_hart.c'))
riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c'))
diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index d17dc03c73..57f0a1336f 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -1219,6 +1219,9 @@ static void spapr_vscsi_realize(SpaprVioDevice *dev, Error **errp)
scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
&vscsi_scsi_info, NULL);
+
+ /* ibmvscsi SCSI bus does not allow hotplug. */
+ qbus_set_hotplug_handler(BUS(&s->bus), NULL);
}
void spapr_vscsi_create(SpaprVioBus *bus)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index cf7dfa4af5..6bf9d27d8a 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -218,22 +218,12 @@ static void dummy_cpu_set_irq(void *opaque, int irq, int level)
{
}
-static void main_cpu_reset(void *opaque)
+static void sun4m_cpu_reset(void *opaque)
{
SPARCCPU *cpu = opaque;
CPUState *cs = CPU(cpu);
cpu_reset(cs);
- cs->halted = 0;
-}
-
-static void secondary_cpu_reset(void *opaque)
-{
- SPARCCPU *cpu = opaque;
- CPUState *cs = CPU(cpu);
-
- cpu_reset(cs);
- cs->halted = 1;
}
static void cpu_halt_signal(void *opaque, int irq, int level)
@@ -819,21 +809,17 @@ static const TypeInfo ram_info = {
static void cpu_devinit(const char *cpu_type, unsigned int id,
uint64_t prom_addr, qemu_irq **cpu_irqs)
{
- CPUState *cs;
SPARCCPU *cpu;
CPUSPARCState *env;
- cpu = SPARC_CPU(cpu_create(cpu_type));
+ cpu = SPARC_CPU(object_new(cpu_type));
env = &cpu->env;
cpu_sparc_set_id(env, id);
- if (id == 0) {
- qemu_register_reset(main_cpu_reset, cpu);
- } else {
- qemu_register_reset(secondary_cpu_reset, cpu);
- cs = CPU(cpu);
- cs->halted = 1;
- }
+ qemu_register_reset(sun4m_cpu_reset, cpu);
+ object_property_set_bool(OBJECT(cpu), "start-powered-off", id != 0,
+ &error_fatal);
+ qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal);
*cpu_irqs = qemu_allocate_irqs(cpu_set_irq, cpu, MAX_PILS);
env->prom_addr = prom_addr;
}
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 8f145733ce..9fc2696db5 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -374,6 +374,10 @@ struct CPUState {
bool created;
bool stop;
bool stopped;
+
+ /* Should CPU start in powered-off state? */
+ bool start_powered_off;
+
bool unplug;
bool crash_occurred;
bool exit_request;
diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h
index 8a99d958bb..c1efdaa4cb 100644
--- a/include/hw/ipmi/ipmi.h
+++ b/include/hw/ipmi/ipmi.h
@@ -53,6 +53,7 @@ enum ipmi_op {
#define IPMI_CC_INVALID_DATA_FIELD 0xcc
#define IPMI_CC_BMC_INIT_IN_PROGRESS 0xd2
#define IPMI_CC_COMMAND_NOT_SUPPORTED 0xd5
+#define IPMI_CC_UNSPECIFIED 0xff
#define IPMI_NETFN_APP 0x06
#define IPMI_NETFN_OEM 0x3a
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index a1e230ad39..e50a2672e3 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -105,6 +105,21 @@ typedef enum {
#define FDT_MAX_SIZE 0x100000
+/*
+ * NUMA related macros. MAX_DISTANCE_REF_POINTS was taken
+ * from Linux kernel arch/powerpc/mm/numa.h. It represents the
+ * amount of associativity domains for non-CPU resources.
+ *
+ * NUMA_ASSOC_SIZE is the base array size of an ibm,associativity
+ * array for any non-CPU resource.
+ *
+ * VCPU_ASSOC_SIZE represents the size of ibm,associativity array
+ * for CPUs, which has an extra element (vcpu_id) in the end.
+ */
+#define MAX_DISTANCE_REF_POINTS 4
+#define NUMA_ASSOC_SIZE (MAX_DISTANCE_REF_POINTS + 1)
+#define VCPU_ASSOC_SIZE (NUMA_ASSOC_SIZE + 1)
+
typedef struct SpaprCapabilities SpaprCapabilities;
struct SpaprCapabilities {
uint8_t caps[SPAPR_CAP_NUM];
@@ -231,6 +246,8 @@ struct SpaprMachineState {
unsigned gpu_numa_id;
SpaprTpmProxy *tpm_proxy;
+ uint32_t numa_assoc_array[MAX_NODES][NUMA_ASSOC_SIZE];
+
Error *fwnmi_migration_blocker;
};
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index 21af8deac1..f270860769 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -29,62 +29,21 @@
TYPE_SPAPR_DR_CONNECTOR)
#define TYPE_SPAPR_DRC_PHYSICAL "spapr-drc-physical"
-#define SPAPR_DRC_PHYSICAL_GET_CLASS(obj) \
- OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_PHYSICAL)
-#define SPAPR_DRC_PHYSICAL_CLASS(klass) \
- OBJECT_CLASS_CHECK(SpaprDrcClass, klass, \
- TYPE_SPAPR_DRC_PHYSICAL)
#define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(SpaprDrcPhysical, (obj), \
TYPE_SPAPR_DRC_PHYSICAL)
#define TYPE_SPAPR_DRC_LOGICAL "spapr-drc-logical"
-#define SPAPR_DRC_LOGICAL_GET_CLASS(obj) \
- OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_LOGICAL)
-#define SPAPR_DRC_LOGICAL_CLASS(klass) \
- OBJECT_CLASS_CHECK(SpaprDrcClass, klass, \
- TYPE_SPAPR_DRC_LOGICAL)
-#define SPAPR_DRC_LOGICAL(obj) OBJECT_CHECK(SpaprDrc, (obj), \
- TYPE_SPAPR_DRC_LOGICAL)
#define TYPE_SPAPR_DRC_CPU "spapr-drc-cpu"
-#define SPAPR_DRC_CPU_GET_CLASS(obj) \
- OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_CPU)
-#define SPAPR_DRC_CPU_CLASS(klass) \
- OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_CPU)
-#define SPAPR_DRC_CPU(obj) OBJECT_CHECK(SpaprDrc, (obj), \
- TYPE_SPAPR_DRC_CPU)
#define TYPE_SPAPR_DRC_PCI "spapr-drc-pci"
-#define SPAPR_DRC_PCI_GET_CLASS(obj) \
- OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_PCI)
-#define SPAPR_DRC_PCI_CLASS(klass) \
- OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_PCI)
-#define SPAPR_DRC_PCI(obj) OBJECT_CHECK(SpaprDrc, (obj), \
- TYPE_SPAPR_DRC_PCI)
#define TYPE_SPAPR_DRC_LMB "spapr-drc-lmb"
-#define SPAPR_DRC_LMB_GET_CLASS(obj) \
- OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_LMB)
-#define SPAPR_DRC_LMB_CLASS(klass) \
- OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_LMB)
-#define SPAPR_DRC_LMB(obj) OBJECT_CHECK(SpaprDrc, (obj), \
- TYPE_SPAPR_DRC_LMB)
#define TYPE_SPAPR_DRC_PHB "spapr-drc-phb"
-#define SPAPR_DRC_PHB_GET_CLASS(obj) \
- OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_PHB)
-#define SPAPR_DRC_PHB_CLASS(klass) \
- OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_PHB)
-#define SPAPR_DRC_PHB(obj) OBJECT_CHECK(SpaprDrc, (obj), \
- TYPE_SPAPR_DRC_PHB)
#define TYPE_SPAPR_DRC_PMEM "spapr-drc-pmem"
-#define SPAPR_DRC_PMEM_GET_CLASS(obj) \
- OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_PMEM)
-#define SPAPR_DRC_PMEM_CLASS(klass) \
- OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_PMEM)
-#define SPAPR_DRC_PMEM(obj) OBJECT_CHECK(SpaprDrc, (obj), \
- TYPE_SPAPR_DRC_PMEM)
+
/*
* Various hotplug types managed by SpaprDrc
*
diff --git a/include/hw/ppc/spapr_numa.h b/include/hw/ppc/spapr_numa.h
new file mode 100644
index 0000000000..b3fd950634
--- /dev/null
+++ b/include/hw/ppc/spapr_numa.h
@@ -0,0 +1,35 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition NUMA associativity handling
+ *
+ * Copyright IBM Corp. 2020
+ *
+ * Authors:
+ * Daniel Henrique Barboza <danielhb413@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_SPAPR_NUMA_H
+#define HW_SPAPR_NUMA_H
+
+#include "hw/boards.h"
+#include "hw/ppc/spapr.h"
+
+/*
+ * Having both SpaprMachineState and MachineState as arguments
+ * feels odd, but it will spare a MACHINE() call inside the
+ * function. spapr_machine_init() is the only caller for it, and
+ * it has both pointers resolved already.
+ */
+void spapr_numa_associativity_init(SpaprMachineState *spapr,
+ MachineState *machine);
+void spapr_numa_write_rtas_dt(SpaprMachineState *spapr, void *fdt, int rtas);
+void spapr_numa_write_associativity_dt(SpaprMachineState *spapr, void *fdt,
+ int offset, int nodeid);
+int spapr_numa_fixup_cpu_dt(SpaprMachineState *spapr, void *fdt,
+ int offset, PowerPCCPU *cpu);
+int spapr_numa_write_assoc_lookup_arrays(SpaprMachineState *spapr, void *fdt,
+ int offset);
+
+#endif /* HW_SPAPR_NUMA_H */
diff --git a/include/hw/ppc/spapr_nvdimm.h b/include/hw/ppc/spapr_nvdimm.h
index b3330cc485..3eb344e8e9 100644
--- a/include/hw/ppc/spapr_nvdimm.h
+++ b/include/hw/ppc/spapr_nvdimm.h
@@ -27,10 +27,9 @@ QEMU_BUILD_BUG_ON(SPAPR_MINIMUM_SCM_BLOCK_SIZE % SPAPR_MEMORY_BLOCK_SIZE);
int spapr_pmem_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp);
-int spapr_dt_nvdimm(void *fdt, int parent_offset, NVDIMMDevice *nvdimm);
-void spapr_dt_persistent_memory(void *fdt);
-void spapr_nvdimm_validate_opts(NVDIMMDevice *nvdimm, uint64_t size,
- Error **errp);
+void spapr_dt_persistent_memory(SpaprMachineState *spapr, void *fdt);
+void spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
+ uint64_t size, Error **errp);
void spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp);
void spapr_create_nvdimm_dr_connectors(SpaprMachineState *spapr);
diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index a1c8540ab4..26c8d90d71 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -49,6 +49,8 @@ typedef struct SpaprXive {
void *tm_mmap;
MemoryRegion tm_mmio_kvm;
VMChangeStateEntry *change;
+
+ uint8_t hv_prio;
} SpaprXive;
typedef struct SpaprXiveClass {
diff --git a/meson.build b/meson.build
index 04e070bb3b..5421eca66a 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
project('qemu', ['c'], meson_version: '>=0.55.0',
default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11',
- 'b_lundef=false','b_colorout=auto'],
+ 'b_colorout=auto'],
version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
not_found = dependency('', required: false)
@@ -14,7 +14,6 @@ ss = import('sourceset')
sh = find_program('sh')
cc = meson.get_compiler('c')
config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
-config_all_disas = keyval.load(meson.current_build_dir() / 'config-all-disas.mak')
enable_modules = 'CONFIG_MODULES' in config_host
enable_static = 'CONFIG_STATIC' in config_host
build_docs = 'BUILD_DOCS' in config_host
@@ -33,6 +32,23 @@ endforeach
have_tools = 'CONFIG_TOOLS' in config_host
have_block = have_system or have_tools
+python = import('python').find_installation()
+
+supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
+supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
+ 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
+
+cpu = host_machine.cpu_family()
+targetos = host_machine.system()
+
+configure_file(input: files('scripts/ninjatool.py'),
+ output: 'ninjatool',
+ configuration: config_host)
+
+##################
+# Compiler flags #
+##################
+
add_project_arguments(config_host['QEMU_CFLAGS'].split(),
native: false, language: ['c', 'objc'])
add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
@@ -42,7 +58,13 @@ add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
add_project_arguments(config_host['QEMU_INCLUDES'].split(),
language: ['c', 'cpp', 'objc'])
-python = import('python').find_installation()
+# Specify linker-script with add_project_link_arguments so that it is not placed
+# within a linker --start-group/--end-group pair
+if 'CONFIG_FUZZ' in config_host
+ add_project_link_arguments(['-Wl,-T,',
+ (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
+ native: false, language: ['c', 'cpp', 'objc'])
+endif
link_language = meson.get_external_property('link_language', 'cpp')
if link_language == 'cpp'
@@ -59,17 +81,6 @@ if 'SPARSE_CFLAGS' in config_host
'compile_commands.json'])
endif
-configure_file(input: files('scripts/ninjatool.py'),
- output: 'ninjatool',
- configuration: config_host)
-
-supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
-supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
- 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
-
-cpu = host_machine.cpu_family()
-targetos = host_machine.system()
-
m = cc.find_library('m', required: false)
util = cc.find_library('util', required: false)
winmm = []
@@ -101,8 +112,11 @@ elif targetos == 'haiku'
cc.find_library('network'),
cc.find_library('bsd')]
endif
-glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
- link_args: config_host['GLIB_LIBS'].split())
+# The path to glib.h is added to all compilation commands. This was
+# grandfathered in from the QEMU Makefiles.
+add_project_arguments(config_host['GLIB_CFLAGS'].split(),
+ native: false, language: ['c', 'cpp', 'objc'])
+glib = declare_dependency(link_args: config_host['GLIB_LIBS'].split())
gio = not_found
if 'CONFIG_GIO' in config_host
gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
@@ -208,6 +222,10 @@ libmpathpersist = not_found
if config_host.has_key('CONFIG_MPATH')
libmpathpersist = cc.find_library('mpathpersist')
endif
+libdl = not_found
+if 'CONFIG_PLUGIN' in config_host
+ libdl = cc.find_library('dl', required: true)
+endif
libiscsi = not_found
if 'CONFIG_LIBISCSI' in config_host
libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
@@ -297,7 +315,8 @@ if 'CONFIG_AUDIO_COREAUDIO' in config_host
endif
opengl = not_found
if 'CONFIG_OPENGL' in config_host
- opengl = declare_dependency(link_args: config_host['OPENGL_LIBS'].split())
+ opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
+ link_args: config_host['OPENGL_LIBS'].split())
else
endif
gtk = not_found
@@ -410,6 +429,15 @@ libdaxctl = not_found
if 'CONFIG_LIBDAXCTL' in config_host
libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
endif
+tasn1 = not_found
+if 'CONFIG_TASN1' in config_host
+ tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
+ link_args: config_host['TASN1_LIBS'].split())
+endif
+keyutils = dependency('libkeyutils', required: false,
+ method: 'pkg-config', static: enable_static)
+
+has_gettid = cc.has_function('gettid')
# Create config-host.h
@@ -420,6 +448,8 @@ config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
config_host_data.set('CONFIG_VNC_PNG', png.found())
config_host_data.set('CONFIG_VNC_SASL', sasl.found())
config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
+config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
+config_host_data.set('CONFIG_GETTID', has_gettid)
config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
@@ -449,10 +479,45 @@ endforeach
genh += configure_file(output: 'config-host.h', configuration: config_host_data)
minikconf = find_program('scripts/minikconf.py')
+config_all_devices = {}
+config_all_disas = {}
config_devices_mak_list = []
config_devices_h = {}
config_target_h = {}
config_target_mak = {}
+
+disassemblers = {
+ 'alpha' : ['CONFIG_ALPHA_DIS'],
+ 'arm' : ['CONFIG_ARM_DIS'],
+ 'avr' : ['CONFIG_AVR_DIS'],
+ 'cris' : ['CONFIG_CRIS_DIS'],
+ 'hppa' : ['CONFIG_HPPA_DIS'],
+ 'i386' : ['CONFIG_I386_DIS'],
+ 'x86_64' : ['CONFIG_I386_DIS'],
+ 'x32' : ['CONFIG_I386_DIS'],
+ 'lm32' : ['CONFIG_LM32_DIS'],
+ 'm68k' : ['CONFIG_M68K_DIS'],
+ 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
+ 'mips' : ['CONFIG_MIPS_DIS'],
+ 'moxie' : ['CONFIG_MOXIE_DIS'],
+ 'nios2' : ['CONFIG_NIOS2_DIS'],
+ 'or1k' : ['CONFIG_OPENRISC_DIS'],
+ 'ppc' : ['CONFIG_PPC_DIS'],
+ 'riscv' : ['CONFIG_RISCV_DIS'],
+ 'rx' : ['CONFIG_RX_DIS'],
+ 's390' : ['CONFIG_S390_DIS'],
+ 'sh4' : ['CONFIG_SH4_DIS'],
+ 'sparc' : ['CONFIG_SPARC_DIS'],
+ 'xtensa' : ['CONFIG_XTENSA_DIS'],
+}
+if link_language == 'cpp'
+ disassemblers += {
+ 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
+ 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
+ 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
+ }
+endif
+
kconfig_external_symbols = [
'CONFIG_KVM',
'CONFIG_XEN',
@@ -468,9 +533,19 @@ kconfig_external_symbols = [
'CONFIG_PVRDMA',
]
ignored = ['TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_DIRS']
+
foreach target : target_dirs
config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak')
+ foreach k, v: disassemblers
+ if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
+ foreach sym: v
+ config_target += { sym: 'y' }
+ config_all_disas += { sym: 'y' }
+ endforeach
+ endif
+ endforeach
+
config_target_data = configuration_data()
foreach k, v: config_target
if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
@@ -517,11 +592,11 @@ foreach target : target_dirs
config_devices_h += {target: configure_file(output: target + '-config-devices.h',
configuration: config_devices_data)}
config_target += config_devices
+ config_all_devices += config_devices
endif
config_target_mak += {target: config_target}
endforeach
-grepy = find_program('scripts/grepy.sh')
# This configuration is used to build files that are shared by
# multiple binaries, and then extracted out of the "common"
# static_library target.
@@ -531,17 +606,6 @@ grepy = find_program('scripts/grepy.sh')
# targets that are not built for this compilation. The CONFIG_ALL
# pseudo symbol replaces it.
-if have_system
- config_all_devices_mak = configure_file(
- output: 'config-all-devices.mak',
- input: config_devices_mak_list,
- capture: true,
- command: [grepy, '@INPUT@'],
- )
- config_all_devices = keyval.load(config_all_devices_mak)
-else
- config_all_devices = {}
-endif
config_all = config_all_devices
config_all += config_host
config_all += config_all_disas
@@ -868,7 +932,7 @@ foreach d, list : modules
endforeach
nm = find_program('nm')
-undefsym = find_program('scripts/undefsym.sh')
+undefsym = find_program('scripts/undefsym.py')
block_syms = custom_target('block.syms', output: 'block.syms',
input: [libqemuutil, block_mods],
capture: true,
@@ -1028,7 +1092,6 @@ foreach target : target_dirs
'gui': false,
'sources': specific_fuzz.sources(),
'dependencies': specific_fuzz.dependencies(),
- 'link_depends': [files('tests/qtest/fuzz/fork_fuzz.ld')],
}]
endif
else
@@ -1102,7 +1165,6 @@ if have_tools
dependencies: [block, qemuutil], install: true)
qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
dependencies: [block, qemuutil], install: true)
- qemu_block_tools += [qemu_img, qemu_io, qemu_nbd]
subdir('storage-daemon')
subdir('contrib/rdmacm-mux')
@@ -1293,7 +1355,6 @@ summary_info += {'CFLAGS': config_host['CFLAGS']}
summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
summary_info += {'make': config_host['MAKE']}
-summary_info += {'install': config_host['INSTALL']}
summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
summary_info += {'sphinx-build': config_host['SPHINX_BUILD']}
summary_info += {'genisoimage': config_host['GENISOIMAGE']}
diff --git a/monitor/meson.build b/monitor/meson.build
index 0484a64341..eb2a534fdc 100644
--- a/monitor/meson.build
+++ b/monitor/meson.build
@@ -6,4 +6,4 @@ softmmu_ss.add(files(
'qmp-cmds.c',
))
-specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files('misc.c'))
+specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files('misc.c'), spice])
diff --git a/pc-bios/hppa-firmware.img b/pc-bios/hppa-firmware.img
index f0f8d0e164..4ba8c7f8b8 100644
--- a/pc-bios/hppa-firmware.img
+++ b/pc-bios/hppa-firmware.img
Binary files differ
diff --git a/qapi/audio.json b/qapi/audio.json
index f62bd0d7f6..3b843878d2 100644
--- a/qapi/audio.json
+++ b/qapi/audio.json
@@ -159,20 +159,20 @@
# recording.
#
# @server-name: select from among several possible concurrent server instances
-# (default: environment variable $JACK_DEFAULT_SERVER if set, else "default")
+# (default: environment variable $JACK_DEFAULT_SERVER if set, else "default")
#
# @client-name: the client name to use. The server will modify this name to
-# create a unique variant, if needed unless @exact-name is true (default: the
-# guest's name)
+# create a unique variant, if needed unless @exact-name is true (default: the
+# guest's name)
#
# @connect-ports: if set, a regular expression of JACK client port name(s) to
-# monitor for and automatically connect to
+# monitor for and automatically connect to
#
# @start-server: start a jack server process if one is not already present
-# (default: false)
+# (default: false)
#
# @exact-name: use the exact name requested otherwise JACK automatically
-# generates a unique one, if needed (default: false)
+# generates a unique one, if needed (default: false)
#
# Since: 5.1
##
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 55b58ba892..c5ac22d246 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -373,7 +373,7 @@
#
# Features:
# @deprecated: Member @encryption_key_missing is deprecated. It is
-# always false.
+# always false.
#
# Since: 0.14.0
#
@@ -508,7 +508,7 @@
#
# Features:
# @deprecated: Member @status is deprecated. Use @recording and
-# @locked instead.
+# @locked instead.
#
# Since: 1.3
##
@@ -618,7 +618,7 @@
#
# Features:
# @deprecated: Member @dirty-bitmaps is deprecated. Use @inserted
-# member @dirty-bitmaps instead.
+# member @dirty-bitmaps instead.
#
# Since: 0.14.0
##
@@ -1646,7 +1646,7 @@
#
# Features:
# @deprecated: Members @base and @top are deprecated. Use @base-node
-# and @top-node instead.
+# and @top-node instead.
#
# Returns: - Nothing on success
# - If @device does not exist, DeviceNotFound
@@ -5211,6 +5211,9 @@
# server will present them as named exports; for example, another
# QEMU instance could refer to them as "nbd:HOST:PORT:exportname=NAME".
#
+# Keep this type consistent with the NbdServerOptions type. The only intended
+# difference is using SocketAddressLegacy instead of SocketAddress.
+#
# @addr: Address on which to listen.
# @tls-creds: ID of the TLS credentials object (since 2.6).
# @tls-authz: ID of the QAuthZ authorization object used to validate
@@ -5221,9 +5224,6 @@
#
# Returns: error if the server is already running.
#
-# Keep this type consistent with the NbdServerOptions type. The only intended
-# difference is using SocketAddressLegacy instead of SocketAddress.
-#
# Since: 1.3.0
##
{ 'command': 'nbd-server-start',
diff --git a/qapi/control.json b/qapi/control.json
index de51e9916c..134f842baf 100644
--- a/qapi/control.json
+++ b/qapi/control.json
@@ -177,8 +177,8 @@
#
# Features:
# @deprecated: This command is deprecated, because its output doesn't
-# reflect compile-time configuration. Use 'query-qmp-schema'
-# instead.
+# reflect compile-time configuration. Use 'query-qmp-schema'
+# instead.
#
# Returns: A list of @EventInfo.
#
diff --git a/qapi/machine.json b/qapi/machine.json
index abc6fd0477..0ac1880e4a 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -191,8 +191,8 @@
#
# Features:
# @deprecated: This command is deprecated, because it interferes with
-# the guest. Use 'query-cpus-fast' instead to avoid the vCPU
-# interruption.
+# the guest. Use 'query-cpus-fast' instead to avoid the vCPU
+# interruption.
#
# Returns: a list of @CpuInfo for each virtual CPU
#
@@ -316,7 +316,7 @@
#
# Features:
# @deprecated: This command is deprecated. Use `device_add` instead.
-# See the `query-hotpluggable-cpus` command for details.
+# See the `query-hotpluggable-cpus` command for details.
#
# Returns: Nothing on success
#
diff --git a/qapi/migration.json b/qapi/migration.json
index 5f6b06172c..675f70bb67 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -667,18 +667,18 @@
# Defaults to none. (Since 5.0)
#
# @multifd-zlib-level: Set the compression level to be used in live
-# migration, the compression level is an integer between 0
-# and 9, where 0 means no compression, 1 means the best
-# compression speed, and 9 means best compression ratio which
-# will consume more CPU.
-# Defaults to 1. (Since 5.0)
+# migration, the compression level is an integer between 0
+# and 9, where 0 means no compression, 1 means the best
+# compression speed, and 9 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
#
# @multifd-zstd-level: Set the compression level to be used in live
-# migration, the compression level is an integer between 0
-# and 20, where 0 means no compression, 1 means the best
-# compression speed, and 20 means best compression ratio which
-# will consume more CPU.
-# Defaults to 1. (Since 5.0)
+# migration, the compression level is an integer between 0
+# and 20, where 0 means no compression, 1 means the best
+# compression speed, and 20 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
#
# @block-bitmap-mapping: Maps block nodes and bitmaps on them to
# aliases for the purpose of dirty bitmap migration. Such
@@ -827,18 +827,18 @@
# Defaults to none. (Since 5.0)
#
# @multifd-zlib-level: Set the compression level to be used in live
-# migration, the compression level is an integer between 0
-# and 9, where 0 means no compression, 1 means the best
-# compression speed, and 9 means best compression ratio which
-# will consume more CPU.
-# Defaults to 1. (Since 5.0)
+# migration, the compression level is an integer between 0
+# and 9, where 0 means no compression, 1 means the best
+# compression speed, and 9 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
#
# @multifd-zstd-level: Set the compression level to be used in live
-# migration, the compression level is an integer between 0
-# and 20, where 0 means no compression, 1 means the best
-# compression speed, and 20 means best compression ratio which
-# will consume more CPU.
-# Defaults to 1. (Since 5.0)
+# migration, the compression level is an integer between 0
+# and 20, where 0 means no compression, 1 means the best
+# compression speed, and 20 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
#
# @block-bitmap-mapping: Maps block nodes and bitmaps on them to
# aliases for the purpose of dirty bitmap migration. Such
@@ -1023,18 +1023,18 @@
# Defaults to none. (Since 5.0)
#
# @multifd-zlib-level: Set the compression level to be used in live
-# migration, the compression level is an integer between 0
-# and 9, where 0 means no compression, 1 means the best
-# compression speed, and 9 means best compression ratio which
-# will consume more CPU.
-# Defaults to 1. (Since 5.0)
+# migration, the compression level is an integer between 0
+# and 9, where 0 means no compression, 1 means the best
+# compression speed, and 9 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
#
# @multifd-zstd-level: Set the compression level to be used in live
-# migration, the compression level is an integer between 0
-# and 20, where 0 means no compression, 1 means the best
-# compression speed, and 20 means best compression ratio which
-# will consume more CPU.
-# Defaults to 1. (Since 5.0)
+# migration, the compression level is an integer between 0
+# and 20, where 0 means no compression, 1 means the best
+# compression speed, and 20 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
#
# @block-bitmap-mapping: Maps block nodes and bitmaps on them to
# aliases for the purpose of dirty bitmap migration. Such
@@ -1362,7 +1362,7 @@
#
# Features:
# @deprecated: This command is deprecated. Use
-# 'migrate-set-parameters' instead.
+# 'migrate-set-parameters' instead.
#
# Returns: nothing on success
#
@@ -1386,7 +1386,7 @@
#
# Features:
# @deprecated: This command is deprecated. Use
-# 'migrate-set-parameters' instead.
+# 'migrate-set-parameters' instead.
#
# Returns: nothing on success
#
@@ -1410,7 +1410,7 @@
#
# Features:
# @deprecated: This command is deprecated. Use
-# 'migrate-set-parameters' instead.
+# 'migrate-set-parameters' instead.
#
# The size will be rounded down to the nearest power of 2.
# The cache size can be modified before and during ongoing migration
@@ -1436,7 +1436,7 @@
#
# Features:
# @deprecated: This command is deprecated. Use
-# 'query-migrate-parameters' instead.
+# 'query-migrate-parameters' instead.
#
# Returns: XBZRLE cache size in bytes
#
diff --git a/qapi/misc.json b/qapi/misc.json
index 9d32820dc1..8cf6ebe67c 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -877,8 +877,8 @@
#
# Features:
# @deprecated: This command is deprecated. For changing block
-# devices, use 'blockdev-change-medium' instead; for changing VNC
-# parameters, use 'change-vnc-password' instead.
+# devices, use 'blockdev-change-medium' instead; for changing VNC
+# parameters, use 'change-vnc-password' instead.
#
# Returns: - Nothing on success.
# - If @device is not a valid block device, DeviceNotFound
diff --git a/qapi/net.json b/qapi/net.json
index ddb113e5e5..a3a1336001 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -457,7 +457,7 @@
#
# Since: 2.7
#
-# @vhost-vdpa since 5.1
+# @vhost-vdpa since 5.1
##
{ 'enum': 'NetClientDriver',
'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
diff --git a/roms/seabios-hppa b/roms/seabios-hppa
-Subproject 4ff7639e2b86d5775fa7d5cd0dbfa4d3a385a70
+Subproject 73b740f77190643b2ada5ee97a9a108c6ef2a37
diff --git a/rules.mak b/rules.mak
deleted file mode 100644
index c66c8218f0..0000000000
--- a/rules.mak
+++ /dev/null
@@ -1,158 +0,0 @@
-
-# These are used when we want to do substitutions without confusing Make
-NULL :=
-SPACE := $(NULL) #
-COMMA := ,
-
-# Don't use implicit rules or variables
-# we have explicit rules for everything
-MAKEFLAGS += -rR
-
-# Files with this suffixes are final, don't try to generate them
-# using implicit rules
-%/trace-events:
-%.hx:
-%.py:
-%.objs:
-%.d:
-%.h:
-%.c:
-%.cc:
-%.cpp:
-%.m:
-%.mak:
-
-# Flags for dependency generation
-QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(@D)/$(*F).d
-
-# Compiler searches the source file dir first, but in vpath builds
-# we need to make it search the build dir too, before any other
-# explicit search paths. There are two search locations in the build
-# dir, one absolute and the other relative to the compiler working
-# directory. These are the same for target-independent files, but
-# different for target-dependent ones.
-QEMU_LOCAL_INCLUDES = -iquote $(BUILD_DIR) -iquote $(BUILD_DIR)/$(@D) -iquote $(@D)
-
-WL := -Wl,
-ifdef CONFIG_DARWIN
-whole-archive = $(WL)-force_load,$1
-else
-whole-archive = $(WL)--whole-archive $1 $(WL)--no-whole-archive
-endif
-
-extract-libs = $(strip $(foreach o,$1,$($o-libs)))
-
-%.o: %.c
- @mkdir -p $(dir $@)
- $(call quiet-command,$(CC) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \
- $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) \
- -c -o $@ $<,"CC","$(TARGET_DIR)$@")
-
-# If we have a CXX we might have some C++ objects, in which case we
-# must link with the C++ compiler, not the plain C compiler.
-LINKPROG = $(or $(CXX),$(CC))
-
-LINK = $(call quiet-command, $(LINKPROG) $(CFLAGS) $(QEMU_LDFLAGS) -o $@ \
- $(filter-out %.a %.fa,$1) \
- $(foreach l,$(filter %.fa,$1),$(call whole-archive,$l)) \
- $(filter %.a,$1) \
- $(call extract-libs,$1) $(LIBS),"LINK","$(TARGET_DIR)$@")
-
-%.o: %.S
- $(call quiet-command,$(CCAS) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \
- $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) \
- -c -o $@ $<,"CCAS","$(TARGET_DIR)$@")
-
-%.o: %.cc
- $(call quiet-command,$(CXX) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \
- $(QEMU_CXXFLAGS) $(QEMU_DGFLAGS) $(CXXFLAGS) $($@-cflags) \
- -c -o $@ $<,"CXX","$(TARGET_DIR)$@")
-
-%.o: %.cpp
- $(call quiet-command,$(CXX) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \
- $(QEMU_CXXFLAGS) $(QEMU_DGFLAGS) $(CXXFLAGS) $($@-cflags) \
- -c -o $@ $<,"CXX","$(TARGET_DIR)$@")
-
-%.o: %.m
- $(call quiet-command,$(OBJCC) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \
- $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) \
- -c -o $@ $<,"OBJC","$(TARGET_DIR)$@")
-
-%.o: %.dtrace
- $(call quiet-command,dtrace -o $@ -G -s $<,"GEN","$(TARGET_DIR)$@")
-
-.PHONY: modules
-modules:
-
-%$(EXESUF): %.o
- $(call LINK,$(filter %.o %.a %.fa, $^))
-
-%.a:
- $(call quiet-command,rm -f $@ && $(AR) rcs $@ $^,"AR","$(TARGET_DIR)$@")
-
-# Usage: $(call quiet-command,command and args,"NAME","args to print")
-# This will run "command and args", and either:
-# if V=1 just print the whole command and args
-# otherwise print the 'quiet' output in the format " NAME args to print"
-# NAME should be a short name of the command, 7 letters or fewer.
-# If called with only a single argument, will print nothing in quiet mode.
-quiet-command-run = $(if $(V),,$(if $2,printf " %-7s %s\n" $2 $3 && ))$1
-quiet-@ = $(if $(V),,@)
-quiet-command = $(quiet-@)$(call quiet-command-run,$1,$2,$3)
-
-# cc-option
-# Usage: CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
-
-cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \
- >/dev/null 2>&1 && echo OK), $2, $3)
-cc-c-option = $(if $(shell $(CC) $1 $2 -c -o /dev/null -xc /dev/null \
- >/dev/null 2>&1 && echo OK), $2, $3)
-
-VPATH_SUFFIXES = %.c %.h %.S %.cc %.cpp %.m %.mak %.texi %.sh %.rc Kconfig% %.json.in
-set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath $(PATTERN) $1)))
-
-# install-prog list, dir
-define install-prog
- $(INSTALL_DIR) "$2"
- $(INSTALL_PROG) $1 "$2"
- $(if $(STRIP),$(STRIP) $(foreach T,$1,"$2/$(notdir $T)"),)
-endef
-
-# Logical functions (for operating on y/n values like CONFIG_FOO vars)
-# Inputs to these must be either "y" (true) or "n" or "" (both false)
-# Output is always either "y" or "n".
-# Usage: $(call land,$(CONFIG_FOO),$(CONFIG_BAR))
-# Logical NOT
-lnot = $(if $(subst n,,$1),n,y)
-# Logical AND
-land = $(if $(findstring yy,$1$2),y,n)
-# Logical OR
-lor = $(if $(findstring y,$1$2),y,n)
-# Logical XOR (note that this is the inverse of leqv)
-lxor = $(if $(filter $(call lnot,$1),$(call lnot,$2)),n,y)
-# Logical equivalence (note that leqv "","n" is true)
-leqv = $(if $(filter $(call lnot,$1),$(call lnot,$2)),y,n)
-# Logical if: like make's $(if) but with an leqv-like test
-lif = $(if $(subst n,,$1),$2,$3)
-
-# String testing functions: inputs to these can be any string;
-# the output is always either "y" or "n". Leading and trailing whitespace
-# is ignored when comparing strings.
-# String equality
-eq = $(if $(subst $2,,$1)$(subst $1,,$2),n,y)
-# String inequality
-ne = $(if $(subst $2,,$1)$(subst $1,,$2),y,n)
-# Emptiness/non-emptiness tests:
-isempty = $(if $1,n,y)
-notempty = $(if $1,y,n)
-
-.PHONY: clean-timestamp
-clean-timestamp:
- rm -f *.timestamp
-clean: clean-timestamp
-
-# will delete the target of a rule if commands exit with a nonzero exit status
-.DELETE_ON_ERROR:
-
-print-%:
- @echo '$*=$($*)'
diff --git a/scripts/grepy.sh b/scripts/grepy.sh
deleted file mode 100755
index aee46ddc8d..0000000000
--- a/scripts/grepy.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-grep -h '=y$' "$@" | sort -u
diff --git a/scripts/mtest2make.py b/scripts/mtest2make.py
index d7a51bf97e..9cbb2e374d 100644
--- a/scripts/mtest2make.py
+++ b/scripts/mtest2make.py
@@ -19,38 +19,25 @@ class Suite(object):
print('''
SPEED = quick
-# $1 = test command, $2 = test name
-.test-human-tap = $1 < /dev/null | ./scripts/tap-driver.pl --test-name="$2" $(if $(V),,--show-failures-only)
-.test-human-exitcode = $1 < /dev/null
-.test-tap-tap = $1 < /dev/null | sed "s/^[a-z][a-z]* [0-9]*/& $2/" || true
-.test-tap-exitcode = printf "%s\\n" 1..1 "`$1 < /dev/null > /dev/null || echo "not "`ok 1 $2"
-.test.print = echo $(if $(V),'$1','Running test $2') >&3
+# $1 = environment, $2 = test command, $3 = test name, $4 = dir
+.test-human-tap = $1 $(if $4,(cd $4 && $2),$2) < /dev/null | ./scripts/tap-driver.pl --test-name="$3" $(if $(V),,--show-failures-only)
+.test-human-exitcode = $1 $(PYTHON) scripts/test-driver.py $(if $4,-C$4) $(if $(V),--verbose) -- $2 < /dev/null
+.test-tap-tap = $1 $(if $4,(cd $4 && $2),$2) < /dev/null | sed "s/^[a-z][a-z]* [0-9]*/& $3/" || true
+.test-tap-exitcode = printf "%s\\n" 1..1 "`$1 $(if $4,(cd $4 && $2),$2) < /dev/null > /dev/null || echo "not "`ok 1 $3"
+.test.human-print = echo $(if $(V),'$1 $2','Running test $3') &&
.test.env = MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$(( $${RANDOM:-0} % 255 + 1))}
# $1 = test name, $2 = test target (human or tap)
-.test.run = $(call .test.print,$(.test.cmd.$1),$(.test.name.$1)) && $(call .test-$2-$(.test.driver.$1),$(.test.cmd.$1),$(.test.name.$1))
-
-define .test.human_k
- @exec 3>&1; rc=0; $(foreach TEST, $1, $(call .test.run,$(TEST),human) || rc=$$?;) \\
- exit $$rc
-endef
-define .test.human_no_k
- $(foreach TEST, $1, @exec 3>&1; $(call .test.run,$(TEST),human)
-)
-endef
-.test.human = \\
- $(if $(findstring k, $(MAKEFLAGS)), $(.test.human_k), $(.test.human_no_k))
-
-define .test.tap
- @exec 3>&1; { $(foreach TEST, $1, $(call .test.run,$(TEST),tap); ) } \\
- | ./scripts/tap-merge.pl | tee "$@" \\
- | ./scripts/tap-driver.pl $(if $(V),, --show-failures-only)
-endef
+.test.run = $(call .test.$2-print,$(.test.env.$1),$(.test.cmd.$1),$(.test.name.$1)) $(call .test-$2-$(.test.driver.$1),$(.test.env.$1),$(.test.cmd.$1),$(.test.name.$1),$(.test.dir.$1))
+
+.test.output-format = human
''')
-suites = defaultdict(Suite)
+introspect = json.load(sys.stdin)
i = 0
-for test in json.load(sys.stdin):
+
+def process_tests(test, suites):
+ global i
env = ' '.join(('%s=%s' % (shlex.quote(k), shlex.quote(v))
for k, v in test['env'].items()))
executable = test['cmd'][0]
@@ -65,15 +52,19 @@ for test in json.load(sys.stdin):
test['cmd'][0] = executable
else:
test['cmd'][0] = executable
- cmd = '$(.test.env) %s %s' % (env, ' '.join((shlex.quote(x) for x in test['cmd'])))
- if test['workdir'] is not None:
- cmd = '(cd %s && %s)' % (shlex.quote(test['workdir']), cmd)
+ cmd = ' '.join((shlex.quote(x) for x in test['cmd']))
driver = test['protocol'] if 'protocol' in test else 'exitcode'
i += 1
+ if test['workdir'] is not None:
+ print('.test.dir.%d := %s' % (i, shlex.quote(test['workdir'])))
print('.test.name.%d := %s' % (i, test['name']))
print('.test.driver.%d := %s' % (i, driver))
+ print('.test.env.%d := $(.test.env) %s' % (i, env))
print('.test.cmd.%d := %s' % (i, cmd))
+ print('.PHONY: run-test-%d' % (i,))
+ print('run-test-%d: all' % (i,))
+ print('\t@$(call .test.run,%d,$(.test.output-format))' % (i,))
test_suites = test['suite'] or ['default']
is_slow = any(s.endswith('-slow') for s in test_suites)
@@ -88,22 +79,41 @@ for test in json.load(sys.stdin):
suites[s].tests.append(i)
suites[s].executables.add(executable)
-print('.PHONY: check check-report.tap')
-print('check:')
-print('check-report.tap:')
-print('\t@cat $^ | scripts/tap-merge.pl >$@')
-for name, suite in suites.items():
+def emit_prolog(suites, prefix):
+ all_tap = ' '.join(('%s-report-%s.tap' % (prefix, k) for k in suites.keys()))
+ print('.PHONY: %s %s-report.tap %s' % (prefix, prefix, all_tap))
+ print('%s: run-tests' % (prefix,))
+ print('%s-report.tap %s: %s-report%%.tap: all' % (prefix, all_tap, prefix))
+ print('''\t$(MAKE) .test.output-format=tap --quiet -Otarget V=1 %s$* | ./scripts/tap-merge.pl | tee "$@" \\
+ | ./scripts/tap-driver.pl $(if $(V),, --show-failures-only)''' % (prefix, ))
+
+def emit_suite(name, suite, prefix):
executables = ' '.join(suite.executables)
slow_test_numbers = ' '.join((str(x) for x in suite.slow_tests))
test_numbers = ' '.join((str(x) for x in suite.tests))
- print('.test.suite-quick.%s := %s' % (name, test_numbers))
- print('.test.suite-slow.%s := $(.test.suite-quick.%s) %s' % (name, name, slow_test_numbers))
- print('check-build: %s' % executables)
- print('.PHONY: check-%s' % name)
- print('.PHONY: check-report-%s.tap' % name)
- print('check: check-%s' % name)
- print('check-%s: all %s' % (name, executables))
- print('\t$(call .test.human, $(.test.suite-$(SPEED).%s))' % (name, ))
- print('check-report.tap: check-report-%s.tap' % name)
- print('check-report-%s.tap: %s' % (name, executables))
- print('\t$(call .test.tap, $(.test.suite-$(SPEED).%s))' % (name, ))
+ target = '%s-%s' % (prefix, name)
+ print('.test.quick.%s := %s' % (target, test_numbers))
+ print('.test.slow.%s := $(.test.quick.%s) %s' % (target, target, slow_test_numbers))
+ print('%s-build: %s' % (prefix, executables))
+ print('.PHONY: %s' % (target, ))
+ print('.PHONY: %s-report-%s.tap' % (prefix, name))
+ print('%s: run-tests' % (target, ))
+ print('ifneq ($(filter %s %s, $(MAKECMDGOALS)),)' % (target, prefix))
+ print('.tests += $(.test.$(SPEED).%s)' % (target, ))
+ print('endif')
+
+testsuites = defaultdict(Suite)
+for test in introspect['tests']:
+ process_tests(test, testsuites)
+emit_prolog(testsuites, 'check')
+for name, suite in testsuites.items():
+ emit_suite(name, suite, 'check')
+
+benchsuites = defaultdict(Suite)
+for test in introspect['benchmarks']:
+ process_tests(test, benchsuites)
+emit_prolog(benchsuites, 'bench')
+for name, suite in benchsuites.items():
+ emit_suite(name, suite, 'bench')
+
+print('run-tests: $(patsubst %, run-test-%, $(.tests))')
diff --git a/scripts/ninjatool.py b/scripts/ninjatool.py
index ba6bd9a2a6..627a1cab45 100755
--- a/scripts/ninjatool.py
+++ b/scripts/ninjatool.py
@@ -34,6 +34,7 @@ import os
import re
import json
import argparse
+import hashlib
import shutil
@@ -51,6 +52,9 @@ else:
normpath = os.path.normpath
+def sha1_text(text):
+ return hashlib.sha1(text.encode()).hexdigest()
+
# ---- lexer and parser ----
PATH_RE = r"[^$\s:|]+|\$[$ :]|\$[a-zA-Z0-9_-]+|\$\{[a-zA-Z0-9_.-]+\}"
@@ -767,7 +771,6 @@ class Ninja2Make(NinjaParserEventsWithVars):
self.build_vars = defaultdict(lambda: dict())
self.rule_targets = defaultdict(lambda: list())
self.stamp_targets = defaultdict(lambda: list())
- self.num_stamp = defaultdict(lambda: 0)
self.all_outs = set()
self.all_ins = set()
self.all_phony = set()
@@ -903,8 +906,7 @@ class Ninja2Make(NinjaParserEventsWithVars):
if len(out) == 1:
stamp = out[0] + '.stamp'
else:
- stamp = '%s%d.stamp' %(rule, self.num_stamp[rule])
- self.num_stamp[rule] += 1
+ stamp = '%s@%s.stamp' % (rule, sha1_text(targets)[0:11])
self.print('%s: %s; @:' % (targets, stamp))
self.print('%s: %s | %s; ${ninja-command-restat}' % (stamp, inputs, orderonly))
self.rule_targets[rule].append(stamp)
diff --git a/scripts/oss-fuzz/build.sh b/scripts/oss-fuzz/build.sh
index f0b7442c96..d16207eb67 100755
--- a/scripts/oss-fuzz/build.sh
+++ b/scripts/oss-fuzz/build.sh
@@ -81,7 +81,7 @@ rm qemu-fuzz-i386
# Build a second time to build the final binary with correct rpath
../configure --disable-werror --cc="$CC" --cxx="$CXX" --enable-fuzzing \
--prefix="$DEST_DIR" --bindir="$DEST_DIR" --datadir="$DEST_DIR/data/" \
- --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="-Wl,-rpath,'\$\$ORIGIN/lib'" \
+ --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="-Wl,-rpath,\$ORIGIN/lib" \
--target-list="i386-softmmu"
make "-j$(nproc)" qemu-fuzz-i386 V=1
diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
index abadacbb0e..165925ca72 100644
--- a/scripts/qapi/parser.py
+++ b/scripts/qapi/parser.py
@@ -52,8 +52,8 @@ class QAPISchemaParser:
info = self.info
if self.tok == '#':
self.reject_expr_doc(cur_doc)
- cur_doc = self.get_doc(info)
- self.docs.append(cur_doc)
+ for cur_doc in self.get_doc(info):
+ self.docs.append(cur_doc)
continue
expr = self.get_expr(False)
@@ -270,7 +270,8 @@ class QAPISchemaParser:
raise QAPIParseError(
self, "junk after '##' at start of documentation comment")
- doc = QAPIDoc(self, info)
+ docs = []
+ cur_doc = QAPIDoc(self, info)
self.accept(False)
while self.tok == '#':
if self.val.startswith('##'):
@@ -279,10 +280,20 @@ class QAPISchemaParser:
raise QAPIParseError(
self,
"junk after '##' at end of documentation comment")
- doc.end_comment()
+ cur_doc.end_comment()
+ docs.append(cur_doc)
self.accept()
- return doc
- doc.append(self.val)
+ return docs
+ if self.val.startswith('# ='):
+ if cur_doc.symbol:
+ raise QAPIParseError(
+ self,
+ "unexpected '=' markup in definition documentation")
+ if cur_doc.body.text:
+ cur_doc.end_comment()
+ docs.append(cur_doc)
+ cur_doc = QAPIDoc(self, info)
+ cur_doc.append(self.val)
self.accept(False)
raise QAPIParseError(self, "documentation comment must end with '##'")
@@ -311,7 +322,6 @@ class QAPIDoc:
def __init__(self, name=None):
# optional section name (argument/member or section name)
self.name = name
- # the list of lines for this section
self.text = ''
def append(self, line):
diff --git a/scripts/test-driver.py b/scripts/test-driver.py
new file mode 100644
index 0000000000..eef74b29a8
--- /dev/null
+++ b/scripts/test-driver.py
@@ -0,0 +1,35 @@
+#! /usr/bin/env python3
+
+# Wrapper for tests that hides the output if they succeed.
+# Used by "make check"
+#
+# Copyright (C) 2020 Red Hat, Inc.
+#
+# Author: Paolo Bonzini <pbonzini@redhat.com>
+
+import subprocess
+import sys
+import os
+import argparse
+
+parser = argparse.ArgumentParser(description='Test driver for QEMU')
+parser.add_argument('-C', metavar='DIR', dest='dir', default='.',
+ help='change to DIR before doing anything else')
+parser.add_argument('-v', '--verbose', dest='verbose', action='store_true',
+ help='be more verbose')
+parser.add_argument('test_args', nargs=argparse.REMAINDER)
+
+args = parser.parse_args()
+os.chdir(args.dir)
+
+test_args = args.test_args
+if test_args[0] == '--':
+ test_args = test_args[1:]
+
+if args.verbose:
+ result = subprocess.run(test_args, stdout=None, stderr=None)
+else:
+ result = subprocess.run(test_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ if result.returncode:
+ sys.stdout.buffer.write(result.stdout)
+sys.exit(result.returncode)
diff --git a/scripts/undefsym.py b/scripts/undefsym.py
new file mode 100644
index 0000000000..69a895cd26
--- /dev/null
+++ b/scripts/undefsym.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+
+# Before a shared module's DSO is produced, a static library is built for it
+# and passed to this script. The script generates -Wl,-u options to force
+# the inclusion of symbol from libqemuutil.a if the shared modules need them,
+# This is necessary because the modules may use functions not needed by the
+# executable itself, which would cause the function to not be linked in.
+# Then the DSO loading would fail because of the missing symbol.
+
+
+import sys
+import subprocess
+
+def filter_lines_set(stdout, from_staticlib):
+ linesSet = set()
+ for line in stdout.splitlines():
+ tokens = line.split(b' ')
+ if len(tokens) >= 1:
+ if len(tokens) > 1:
+ if from_staticlib and tokens[1] == b'U':
+ continue
+ if not from_staticlib and tokens[1] != b'U':
+ continue
+ new_line = b'-Wl,-u,' + tokens[0]
+ if not new_line in linesSet:
+ linesSet.add(new_line)
+ return linesSet
+
+def main(args):
+ if len(args) <= 3:
+ sys.exit(0)
+
+ nm = args[1]
+ staticlib = args[2]
+ pc = subprocess.run([nm, "-P", "-g", staticlib], stdout=subprocess.PIPE)
+ if pc.returncode != 0:
+ sys.exit(1)
+ staticlib_syms = filter_lines_set(pc.stdout, True)
+
+ shared_modules = args[3:]
+ pc = subprocess.run([nm, "-P", "-g"] + shared_modules, stdout=subprocess.PIPE)
+ if pc.returncode != 0:
+ sys.exit(1)
+ modules_undef_syms = filter_lines_set(pc.stdout, False)
+ lines = sorted(staticlib_syms.intersection(modules_undef_syms))
+ sys.stdout.buffer.write(b'\n'.join(lines))
+
+if __name__ == "__main__":
+ main(sys.argv)
diff --git a/scripts/undefsym.sh b/scripts/undefsym.sh
deleted file mode 100755
index b9ec332e95..0000000000
--- a/scripts/undefsym.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/bin/env bash
-
-# Before a shared module's DSO is produced, a static library is built for it
-# and passed to this script. The script generates -Wl,-u options to force
-# the inclusion of symbol from libqemuutil.a if the shared modules need them,
-# This is necessary because the modules may use functions not needed by the
-# executable itself, which would cause the function to not be linked in.
-# Then the DSO loading would fail because of the missing symbol.
-
-if test $# -le 2; then
- exit 0
-fi
-
-NM=$1
-staticlib=$2
-shift 2
-# Find symbols defined in static libraries and undefined in shared modules
-comm -12 \
- <( $NM -P -g $staticlib | awk '$2!="U"{print "-Wl,-u," $1}' | sort -u) \
- <( $NM -P -g "$@" | awk '$2=="U"{print "-Wl,-u," $1}' | sort -u)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index c179e0752d..6b4e708c08 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -174,8 +174,7 @@ static void arm_cpu_reset(DeviceState *dev)
env->vfp.xregs[ARM_VFP_MVFR1] = cpu->isar.mvfr1;
env->vfp.xregs[ARM_VFP_MVFR2] = cpu->isar.mvfr2;
- cpu->power_state = cpu->start_powered_off ? PSCI_OFF : PSCI_ON;
- s->halted = cpu->start_powered_off;
+ cpu->power_state = s->start_powered_off ? PSCI_OFF : PSCI_ON;
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
@@ -2186,7 +2185,6 @@ static const ARMCPUInfo arm_cpus[] = {
};
static Property arm_cpu_properties[] = {
- DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index a1c7d8ebae..6036f61d60 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -817,9 +817,6 @@ struct ARMCPU {
*/
uint32_t psci_version;
- /* Should CPU start in PSCI powered-off state? */
- bool start_powered_off;
-
/* Current power state, access guarded by BQL */
ARMPSCIState power_state;
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
index 0af46b41c8..1f2b8f8b7a 100644
--- a/target/arm/kvm32.c
+++ b/target/arm/kvm32.c
@@ -218,7 +218,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
/* Determine init features for this CPU */
memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));
- if (cpu->start_powered_off) {
+ if (cs->start_powered_off) {
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
}
if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index ef1e960285..987b35e33f 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -774,7 +774,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
/* Determine init features for this CPU */
memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));
- if (cpu->start_powered_off) {
+ if (cs->start_powered_off) {
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
}
if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 801a4fb1ba..fb6c59d075 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -196,9 +196,12 @@ struct CPUHPPAState {
target_ureg shadow[7]; /* shadow registers */
/* ??? The number of entries isn't specified by the architecture. */
+#define HPPA_TLB_ENTRIES 256
+#define HPPA_BTLB_ENTRIES 0
+
/* ??? Implement a unified itlb/dtlb for the moment. */
/* ??? We should use a more intelligent data structure. */
- hppa_tlb_entry tlb[256];
+ hppa_tlb_entry tlb[HPPA_TLB_ENTRIES];
uint32_t tlb_last;
};
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index f0dd71dd08..dceaad65e9 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -149,9 +149,9 @@ lci 000001 ----- ----- -- 01001100 0 t:5
# Arith/Log
####
-andcm 000010 ..... ..... .... 000000 0 ..... @rrr_cf
-and 000010 ..... ..... .... 001000 0 ..... @rrr_cf
-or 000010 ..... ..... .... 001001 0 ..... @rrr_cf
+andcm 000010 ..... ..... .... 000000 - ..... @rrr_cf
+and 000010 ..... ..... .... 001000 - ..... @rrr_cf
+or 000010 ..... ..... .... 001001 - ..... @rrr_cf
xor 000010 ..... ..... .... 001010 0 ..... @rrr_cf
uxor 000010 ..... ..... .... 001110 0 ..... @rrr_cf
ds 000010 ..... ..... .... 010001 0 ..... @rrr_cf
@@ -161,13 +161,13 @@ uaddcm_tc 000010 ..... ..... .... 100111 0 ..... @rrr_cf
dcor 000010 ..... 00000 .... 101110 0 ..... @rr_cf
dcor_i 000010 ..... 00000 .... 101111 0 ..... @rr_cf
-add 000010 ..... ..... .... 0110.. 0 ..... @rrr_cf_sh
+add 000010 ..... ..... .... 0110.. - ..... @rrr_cf_sh
add_l 000010 ..... ..... .... 1010.. 0 ..... @rrr_cf_sh
add_tsv 000010 ..... ..... .... 1110.. 0 ..... @rrr_cf_sh
add_c 000010 ..... ..... .... 011100 0 ..... @rrr_cf_sh0
add_c_tsv 000010 ..... ..... .... 111100 0 ..... @rrr_cf_sh0
-sub 000010 ..... ..... .... 010000 0 ..... @rrr_cf
+sub 000010 ..... ..... .... 010000 - ..... @rrr_cf
sub_tsv 000010 ..... ..... .... 110000 0 ..... @rrr_cf
sub_tc 000010 ..... ..... .... 010011 0 ..... @rrr_cf
sub_tsv_tc 000010 ..... ..... .... 110011 0 ..... @rrr_cf
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 6392524135..9b2482159d 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -26,7 +26,6 @@
#include "cpu.h"
#include "qemu/module.h"
#include "hw/qdev-properties.h"
-#include "migration/vmstate.h"
#include "exec/exec-all.h"
#include "fpu/softfloat-helpers.h"
@@ -135,10 +134,6 @@ static void mb_cpu_reset(DeviceState *dev)
#else
mb_cpu_write_msr(env, 0);
mmu_init(&env->mmu);
- env->mmu.c_mmu = 3;
- env->mmu.c_mmu_tlb_access = 3;
- env->mmu.c_mmu_zones = 16;
- env->mmu.c_addr_mask = MAKE_64BIT_MASK(0, cpu->cfg.addr_size);
#endif
}
@@ -153,7 +148,6 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
CPUState *cs = CPU(dev);
MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(dev);
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
- CPUMBState *env = &cpu->env;
uint8_t version_code = 0;
const char *version;
int i = 0;
@@ -173,16 +167,6 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
qemu_init_vcpu(cs);
- env->pvr.regs[0] = PVR0_USE_EXC_MASK
- | PVR0_USE_ICACHE_MASK
- | PVR0_USE_DCACHE_MASK;
- env->pvr.regs[2] = PVR2_D_OPB_MASK
- | PVR2_D_LMB_MASK
- | PVR2_I_OPB_MASK
- | PVR2_I_LMB_MASK
- | PVR2_FPU_EXC_MASK
- | 0;
-
version = cpu->cfg.version ? cpu->cfg.version : DEFAULT_CPU_VERSION;
for (i = 0; mb_cpu_lookup[i].name && version; i++) {
if (strcmp(mb_cpu_lookup[i].name, version) == 0) {
@@ -195,46 +179,58 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
qemu_log("Invalid MicroBlaze version number: %s\n", cpu->cfg.version);
}
- env->pvr.regs[0] |= (cpu->cfg.stackprot ? PVR0_SPROT_MASK : 0) |
- (cpu->cfg.use_fpu ? PVR0_USE_FPU_MASK : 0) |
- (cpu->cfg.use_hw_mul ? PVR0_USE_HW_MUL_MASK : 0) |
- (cpu->cfg.use_barrel ? PVR0_USE_BARREL_MASK : 0) |
- (cpu->cfg.use_div ? PVR0_USE_DIV_MASK : 0) |
- (cpu->cfg.use_mmu ? PVR0_USE_MMU_MASK : 0) |
- (cpu->cfg.endi ? PVR0_ENDI_MASK : 0) |
- (version_code << PVR0_VERSION_SHIFT) |
- (cpu->cfg.pvr == C_PVR_FULL ? PVR0_PVR_FULL_MASK : 0) |
- cpu->cfg.pvr_user1;
-
- env->pvr.regs[1] = cpu->cfg.pvr_user2;
- env->pvr.regs[2] |= (cpu->cfg.use_fpu ? PVR2_USE_FPU_MASK : 0) |
- (cpu->cfg.use_fpu > 1 ? PVR2_USE_FPU2_MASK : 0) |
- (cpu->cfg.use_hw_mul ? PVR2_USE_HW_MUL_MASK : 0) |
- (cpu->cfg.use_hw_mul > 1 ? PVR2_USE_MUL64_MASK : 0) |
- (cpu->cfg.use_barrel ? PVR2_USE_BARREL_MASK : 0) |
- (cpu->cfg.use_div ? PVR2_USE_DIV_MASK : 0) |
- (cpu->cfg.use_msr_instr ? PVR2_USE_MSR_INSTR : 0) |
- (cpu->cfg.use_pcmp_instr ? PVR2_USE_PCMP_INSTR : 0) |
- (cpu->cfg.dopb_bus_exception ?
- PVR2_DOPB_BUS_EXC_MASK : 0) |
- (cpu->cfg.iopb_bus_exception ?
- PVR2_IOPB_BUS_EXC_MASK : 0) |
- (cpu->cfg.div_zero_exception ?
- PVR2_DIV_ZERO_EXC_MASK : 0) |
- (cpu->cfg.illegal_opcode_exception ?
- PVR2_ILL_OPCODE_EXC_MASK : 0) |
- (cpu->cfg.unaligned_exceptions ?
- PVR2_UNALIGNED_EXC_MASK : 0) |
- (cpu->cfg.opcode_0_illegal ?
- PVR2_OPCODE_0x0_ILL_MASK : 0);
-
- env->pvr.regs[5] |= cpu->cfg.dcache_writeback ?
- PVR5_DCACHE_WRITEBACK_MASK : 0;
-
- env->pvr.regs[10] = 0x0c000000 | /* Default to spartan 3a dsp family. */
- (cpu->cfg.addr_size - 32) << PVR10_ASIZE_SHIFT;
- env->pvr.regs[11] = (cpu->cfg.use_mmu ? PVR11_USE_MMU : 0) |
- 16 << 17;
+ cpu->cfg.pvr_regs[0] =
+ (PVR0_USE_EXC_MASK |
+ PVR0_USE_ICACHE_MASK |
+ PVR0_USE_DCACHE_MASK |
+ (cpu->cfg.stackprot ? PVR0_SPROT_MASK : 0) |
+ (cpu->cfg.use_fpu ? PVR0_USE_FPU_MASK : 0) |
+ (cpu->cfg.use_hw_mul ? PVR0_USE_HW_MUL_MASK : 0) |
+ (cpu->cfg.use_barrel ? PVR0_USE_BARREL_MASK : 0) |
+ (cpu->cfg.use_div ? PVR0_USE_DIV_MASK : 0) |
+ (cpu->cfg.use_mmu ? PVR0_USE_MMU_MASK : 0) |
+ (cpu->cfg.endi ? PVR0_ENDI_MASK : 0) |
+ (version_code << PVR0_VERSION_SHIFT) |
+ (cpu->cfg.pvr == C_PVR_FULL ? PVR0_PVR_FULL_MASK : 0) |
+ cpu->cfg.pvr_user1);
+
+ cpu->cfg.pvr_regs[1] = cpu->cfg.pvr_user2;
+
+ cpu->cfg.pvr_regs[2] =
+ (PVR2_D_OPB_MASK |
+ PVR2_D_LMB_MASK |
+ PVR2_I_OPB_MASK |
+ PVR2_I_LMB_MASK |
+ PVR2_FPU_EXC_MASK |
+ (cpu->cfg.use_fpu ? PVR2_USE_FPU_MASK : 0) |
+ (cpu->cfg.use_fpu > 1 ? PVR2_USE_FPU2_MASK : 0) |
+ (cpu->cfg.use_hw_mul ? PVR2_USE_HW_MUL_MASK : 0) |
+ (cpu->cfg.use_hw_mul > 1 ? PVR2_USE_MUL64_MASK : 0) |
+ (cpu->cfg.use_barrel ? PVR2_USE_BARREL_MASK : 0) |
+ (cpu->cfg.use_div ? PVR2_USE_DIV_MASK : 0) |
+ (cpu->cfg.use_msr_instr ? PVR2_USE_MSR_INSTR : 0) |
+ (cpu->cfg.use_pcmp_instr ? PVR2_USE_PCMP_INSTR : 0) |
+ (cpu->cfg.dopb_bus_exception ? PVR2_DOPB_BUS_EXC_MASK : 0) |
+ (cpu->cfg.iopb_bus_exception ? PVR2_IOPB_BUS_EXC_MASK : 0) |
+ (cpu->cfg.div_zero_exception ? PVR2_DIV_ZERO_EXC_MASK : 0) |
+ (cpu->cfg.illegal_opcode_exception ? PVR2_ILL_OPCODE_EXC_MASK : 0) |
+ (cpu->cfg.unaligned_exceptions ? PVR2_UNALIGNED_EXC_MASK : 0) |
+ (cpu->cfg.opcode_0_illegal ? PVR2_OPCODE_0x0_ILL_MASK : 0));
+
+ cpu->cfg.pvr_regs[5] |=
+ cpu->cfg.dcache_writeback ? PVR5_DCACHE_WRITEBACK_MASK : 0;
+
+ cpu->cfg.pvr_regs[10] =
+ (0x0c000000 | /* Default to spartan 3a dsp family. */
+ (cpu->cfg.addr_size - 32) << PVR10_ASIZE_SHIFT);
+
+ cpu->cfg.pvr_regs[11] = ((cpu->cfg.use_mmu ? PVR11_USE_MMU : 0) |
+ 16 << 17);
+
+ cpu->cfg.mmu = 3;
+ cpu->cfg.mmu_tlb_access = 3;
+ cpu->cfg.mmu_zones = 16;
+ cpu->cfg.addr_mask = MAKE_64BIT_MASK(0, cpu->cfg.addr_size);
mcc->parent_realize(dev, errp);
}
@@ -254,11 +250,6 @@ static void mb_cpu_initfn(Object *obj)
#endif
}
-static const VMStateDescription vmstate_mb_cpu = {
- .name = "cpu",
- .unmigratable = 1,
-};
-
static Property mb_properties[] = {
DEFINE_PROP_UINT32("base-vectors", MicroBlazeCPU, cfg.base_vectors, 0),
DEFINE_PROP_BOOL("use-stack-protection", MicroBlazeCPU, cfg.stackprot,
@@ -338,8 +329,8 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
#ifndef CONFIG_USER_ONLY
cc->do_transaction_failed = mb_cpu_transaction_failed;
cc->get_phys_page_debug = mb_cpu_get_phys_page_debug;
-#endif
dc->vmsd = &vmstate_mb_cpu;
+#endif
device_class_set_props(dc, mb_properties);
cc->gdb_num_core_regs = 32 + 27;
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index a25a2b427f..297b36879a 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -264,10 +264,10 @@ struct CPUMBState {
/* MSR_UM (1 << 11) */
/* MSR_VM (1 << 13) */
/* ESR_ESS_MASK [11:5] -- unwind into iflags for unaligned excp */
+#define D_FLAG (1 << 12) /* Bit in ESR. */
#define DRTI_FLAG (1 << 16)
#define DRTE_FLAG (1 << 17)
#define DRTB_FLAG (1 << 18)
-#define D_FLAG (1 << 19) /* Bit in ESR. */
/* TB dependent CPUMBState. */
#define IFLAGS_TB_MASK (D_FLAG | BIMM_FLAG | IMM_FLAG | \
@@ -278,19 +278,54 @@ struct CPUMBState {
#if !defined(CONFIG_USER_ONLY)
/* Unified MMU. */
- struct microblaze_mmu mmu;
+ MicroBlazeMMU mmu;
#endif
/* Fields up to this point are cleared by a CPU reset */
struct {} end_reset_fields;
/* These fields are preserved on reset. */
-
- struct {
- uint32_t regs[13];
- } pvr;
};
+/*
+ * Microblaze Configuration Settings
+ *
+ * Note that the structure is sorted by type and size to minimize holes.
+ */
+typedef struct {
+ char *version;
+
+ uint64_t addr_mask;
+
+ uint32_t base_vectors;
+ uint32_t pvr_user2;
+ uint32_t pvr_regs[13];
+
+ uint8_t addr_size;
+ uint8_t use_fpu;
+ uint8_t use_hw_mul;
+ uint8_t pvr_user1;
+ uint8_t pvr;
+ uint8_t mmu;
+ uint8_t mmu_tlb_access;
+ uint8_t mmu_zones;
+
+ bool stackprot;
+ bool use_barrel;
+ bool use_div;
+ bool use_msr_instr;
+ bool use_pcmp_instr;
+ bool use_mmu;
+ bool dcache_writeback;
+ bool endi;
+ bool dopb_bus_exception;
+ bool iopb_bus_exception;
+ bool illegal_opcode_exception;
+ bool opcode_0_illegal;
+ bool div_zero_exception;
+ bool unaligned_exceptions;
+} MicroBlazeCPUConfig;
+
/**
* MicroBlazeCPU:
* @env: #CPUMBState
@@ -305,32 +340,7 @@ struct MicroBlazeCPU {
CPUNegativeOffsetState neg;
CPUMBState env;
-
- /* Microblaze Configuration Settings */
- struct {
- bool stackprot;
- uint32_t base_vectors;
- uint8_t addr_size;
- uint8_t use_fpu;
- uint8_t use_hw_mul;
- bool use_barrel;
- bool use_div;
- bool use_msr_instr;
- bool use_pcmp_instr;
- bool use_mmu;
- bool dcache_writeback;
- bool endi;
- bool dopb_bus_exception;
- bool iopb_bus_exception;
- bool illegal_opcode_exception;
- bool opcode_0_illegal;
- bool div_zero_exception;
- bool unaligned_exceptions;
- uint8_t pvr_user1;
- uint32_t pvr_user2;
- char *version;
- uint8_t pvr;
- } cfg;
+ MicroBlazeCPUConfig cfg;
};
@@ -419,4 +429,8 @@ static inline int cpu_mmu_index(CPUMBState *env, bool ifetch)
return MMU_KERNEL_IDX;
}
+#ifndef CONFIG_USER_ONLY
+extern const VMStateDescription vmstate_mb_cpu;
+#endif
+
#endif
diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
index 08d6a0e807..be39fd4540 100644
--- a/target/microblaze/gdbstub.c
+++ b/target/microblaze/gdbstub.c
@@ -78,7 +78,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
break;
case GDB_PVR0 ... GDB_PVR11:
/* PVR12 is intentionally skipped */
- val = env->pvr.regs[n - GDB_PVR0];
+ val = cpu->cfg.pvr_regs[n - GDB_PVR0];
break;
case GDB_EDR:
val = env->edr;
@@ -132,10 +132,6 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
case GDB_BTR:
env->btr = tmp;
break;
- case GDB_PVR0 ... GDB_PVR11:
- /* PVR12 is intentionally skipped */
- env->pvr.regs[n - GDB_PVR0] = tmp;
- break;
case GDB_EDR:
env->edr = tmp;
break;
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 00090526da..3d6ce1b31b 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -52,7 +52,7 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
{
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
CPUMBState *env = &cpu->env;
- struct microblaze_mmu_lookup lu;
+ MicroBlazeMMULookup lu;
unsigned int hit;
int prot;
@@ -64,7 +64,7 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
return true;
}
- hit = mmu_translate(&env->mmu, &lu, address, access_type, mmu_idx);
+ hit = mmu_translate(cpu, &lu, address, access_type, mmu_idx);
if (likely(hit)) {
uint32_t vaddr = address & TARGET_PAGE_MASK;
uint32_t paddr = lu.paddr + vaddr - lu.vaddr;
@@ -111,6 +111,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
CPUMBState *env = &cpu->env;
uint32_t t, msr = mb_cpu_read_msr(env);
+ bool set_esr;
/* IMM flag cannot propagate across a branch and into the dslot. */
assert((env->iflags & (D_FLAG | IMM_FLAG)) != (D_FLAG | IMM_FLAG));
@@ -118,142 +119,114 @@ void mb_cpu_do_interrupt(CPUState *cs)
assert((env->iflags & (D_FLAG | BIMM_FLAG)) != BIMM_FLAG);
/* RTI flags are private to translate. */
assert(!(env->iflags & (DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)));
- env->res_addr = RES_ADDR_NONE;
+
switch (cs->exception_index) {
- case EXCP_HW_EXCP:
- if (!(env->pvr.regs[0] & PVR0_USE_EXC_MASK)) {
- qemu_log_mask(LOG_GUEST_ERROR, "Exception raised on system without exceptions!\n");
- return;
- }
-
- env->regs[17] = env->pc + 4;
- env->esr &= ~(1 << 12);
-
- /* Exception breaks branch + dslot sequence? */
- if (env->iflags & D_FLAG) {
- env->esr |= 1 << 12 ;
- env->btr = env->btarget;
- }
-
- /* Disable the MMU. */
- t = (msr & (MSR_VM | MSR_UM)) << 1;
- msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
- msr |= t;
- /* Exception in progress. */
- msr |= MSR_EIP;
- mb_cpu_write_msr(env, msr);
-
- qemu_log_mask(CPU_LOG_INT,
- "hw exception at pc=%x ear=%" PRIx64 " "
- "esr=%x iflags=%x\n",
- env->pc, env->ear,
- env->esr, env->iflags);
- log_cpu_state_mask(CPU_LOG_INT, cs, 0);
- env->iflags = 0;
- env->pc = cpu->cfg.base_vectors + 0x20;
- break;
-
- case EXCP_MMU:
+ case EXCP_HW_EXCP:
+ if (!(cpu->cfg.pvr_regs[0] & PVR0_USE_EXC_MASK)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Exception raised on system without exceptions!\n");
+ return;
+ }
+
+ qemu_log_mask(CPU_LOG_INT,
+ "INT: HWE at pc=%08x msr=%08x iflags=%x\n",
+ env->pc, msr, env->iflags);
+
+ /* Exception breaks branch + dslot sequence? */
+ set_esr = true;
+ env->esr &= ~D_FLAG;
+ if (env->iflags & D_FLAG) {
+ env->esr |= D_FLAG;
+ env->btr = env->btarget;
+ }
+
+ /* Exception in progress. */
+ msr |= MSR_EIP;
+ env->regs[17] = env->pc + 4;
+ env->pc = cpu->cfg.base_vectors + 0x20;
+ break;
+
+ case EXCP_MMU:
+ qemu_log_mask(CPU_LOG_INT,
+ "INT: MMU at pc=%08x msr=%08x "
+ "ear=%" PRIx64 " iflags=%x\n",
+ env->pc, msr, env->ear, env->iflags);
+
+ /* Exception breaks branch + dslot sequence? */
+ set_esr = true;
+ env->esr &= ~D_FLAG;
+ if (env->iflags & D_FLAG) {
+ env->esr |= D_FLAG;
+ env->btr = env->btarget;
+ /* Reexecute the branch. */
+ env->regs[17] = env->pc - (env->iflags & BIMM_FLAG ? 8 : 4);
+ } else if (env->iflags & IMM_FLAG) {
+ /* Reexecute the imm. */
+ env->regs[17] = env->pc - 4;
+ } else {
env->regs[17] = env->pc;
+ }
- qemu_log_mask(CPU_LOG_INT,
- "MMU exception at pc=%x iflags=%x ear=%" PRIx64 "\n",
- env->pc, env->iflags, env->ear);
-
- env->esr &= ~(1 << 12);
- /* Exception breaks branch + dslot sequence? */
- if (env->iflags & D_FLAG) {
- env->esr |= 1 << 12 ;
- env->btr = env->btarget;
-
- /* Reexecute the branch. */
- env->regs[17] -= 4;
- /* was the branch immprefixed?. */
- if (env->iflags & BIMM_FLAG) {
- env->regs[17] -= 4;
- log_cpu_state_mask(CPU_LOG_INT, cs, 0);
- }
- } else if (env->iflags & IMM_FLAG) {
- env->regs[17] -= 4;
- }
-
- /* Disable the MMU. */
- t = (msr & (MSR_VM | MSR_UM)) << 1;
- msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
- msr |= t;
- /* Exception in progress. */
- msr |= MSR_EIP;
- mb_cpu_write_msr(env, msr);
-
- qemu_log_mask(CPU_LOG_INT,
- "exception at pc=%x ear=%" PRIx64 " iflags=%x\n",
- env->pc, env->ear, env->iflags);
- log_cpu_state_mask(CPU_LOG_INT, cs, 0);
- env->iflags = 0;
- env->pc = cpu->cfg.base_vectors + 0x20;
- break;
-
- case EXCP_IRQ:
- assert(!(msr & (MSR_EIP | MSR_BIP)));
- assert(msr & MSR_IE);
- assert(!(env->iflags & (D_FLAG | IMM_FLAG)));
-
- t = (msr & (MSR_VM | MSR_UM)) << 1;
-
-#if 0
-#include "disas/disas.h"
-
-/* Useful instrumentation when debugging interrupt issues in either
- the models or in sw. */
- {
- const char *sym;
-
- sym = lookup_symbol(env->pc);
- if (sym
- && (!strcmp("netif_rx", sym)
- || !strcmp("process_backlog", sym))) {
-
- qemu_log("interrupt at pc=%x msr=%x %x iflags=%x sym=%s\n",
- env->pc, msr, t, env->iflags, sym);
-
- log_cpu_state(cs, 0);
- }
- }
-#endif
- qemu_log_mask(CPU_LOG_INT,
- "interrupt at pc=%x msr=%x %x iflags=%x\n",
- env->pc, msr, t, env->iflags);
-
- msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM | MSR_IE);
- msr |= t;
- mb_cpu_write_msr(env, msr);
-
- env->regs[14] = env->pc;
- env->iflags = 0;
- env->pc = cpu->cfg.base_vectors + 0x10;
- //log_cpu_state_mask(CPU_LOG_INT, cs, 0);
- break;
-
- case EXCP_HW_BREAK:
- assert(!(env->iflags & (D_FLAG | IMM_FLAG)));
-
- t = (msr & (MSR_VM | MSR_UM)) << 1;
- qemu_log_mask(CPU_LOG_INT,
- "break at pc=%x msr=%x %x iflags=%x\n",
- env->pc, msr, t, env->iflags);
- log_cpu_state_mask(CPU_LOG_INT, cs, 0);
- msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
- msr |= t;
- msr |= MSR_BIP;
- env->regs[16] = env->pc;
- env->iflags = 0;
- env->pc = cpu->cfg.base_vectors + 0x18;
- mb_cpu_write_msr(env, msr);
- break;
- default:
- cpu_abort(cs, "unhandled exception type=%d\n",
- cs->exception_index);
- break;
+ /* Exception in progress. */
+ msr |= MSR_EIP;
+ env->pc = cpu->cfg.base_vectors + 0x20;
+ break;
+
+ case EXCP_IRQ:
+ assert(!(msr & (MSR_EIP | MSR_BIP)));
+ assert(msr & MSR_IE);
+ assert(!(env->iflags & (D_FLAG | IMM_FLAG)));
+
+ qemu_log_mask(CPU_LOG_INT,
+ "INT: DEV at pc=%08x msr=%08x iflags=%x\n",
+ env->pc, msr, env->iflags);
+ set_esr = false;
+
+ /* Disable interrupts. */
+ msr &= ~MSR_IE;
+ env->regs[14] = env->pc;
+ env->pc = cpu->cfg.base_vectors + 0x10;
+ break;
+
+ case EXCP_HW_BREAK:
+ assert(!(env->iflags & (D_FLAG | IMM_FLAG)));
+
+ qemu_log_mask(CPU_LOG_INT,
+ "INT: BRK at pc=%08x msr=%08x iflags=%x\n",
+ env->pc, msr, env->iflags);
+ set_esr = false;
+
+ /* Break in progress. */
+ msr |= MSR_BIP;
+ env->regs[16] = env->pc;
+ env->pc = cpu->cfg.base_vectors + 0x18;
+ break;
+
+ default:
+ cpu_abort(cs, "unhandled exception type=%d\n", cs->exception_index);
+ /* not reached */
+ }
+
+ /* Save previous mode, disable mmu, disable user-mode. */
+ t = (msr & (MSR_VM | MSR_UM)) << 1;
+ msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
+ msr |= t;
+ mb_cpu_write_msr(env, msr);
+
+ env->res_addr = RES_ADDR_NONE;
+ env->iflags = 0;
+
+ if (!set_esr) {
+ qemu_log_mask(CPU_LOG_INT,
+ " to pc=%08x msr=%08x\n", env->pc, msr);
+ } else if (env->esr & D_FLAG) {
+ qemu_log_mask(CPU_LOG_INT,
+ " to pc=%08x msr=%08x esr=%04x btr=%08x\n",
+ env->pc, msr, env->esr, env->btr);
+ } else {
+ qemu_log_mask(CPU_LOG_INT,
+ " to pc=%08x msr=%08x esr=%04x\n",
+ env->pc, msr, env->esr);
}
}
@@ -262,12 +235,12 @@ hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
CPUMBState *env = &cpu->env;
target_ulong vaddr, paddr = 0;
- struct microblaze_mmu_lookup lu;
+ MicroBlazeMMULookup lu;
int mmu_idx = cpu_mmu_index(env, false);
unsigned int hit;
if (mmu_idx != MMU_NOMMU_IDX) {
- hit = mmu_translate(&env->mmu, &lu, addr, 0, 0);
+ hit = mmu_translate(cpu, &lu, addr, 0, 0);
if (hit) {
vaddr = addr & TARGET_PAGE_MASK;
paddr = lu.paddr + vaddr - lu.vaddr;
diff --git a/target/microblaze/machine.c b/target/microblaze/machine.c
new file mode 100644
index 0000000000..acdb8d0474
--- /dev/null
+++ b/target/microblaze/machine.c
@@ -0,0 +1,106 @@
+/*
+ * Microblaze VMState for qemu.
+ *
+ * Copyright (c) 2020 Linaro, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "migration/cpu.h"
+
+
+static VMStateField vmstate_mmu_fields[] = {
+ VMSTATE_UINT64_2DARRAY(rams, MicroBlazeMMU, 2, TLB_ENTRIES),
+ VMSTATE_UINT8_ARRAY(tids, MicroBlazeMMU, TLB_ENTRIES),
+ VMSTATE_UINT32_ARRAY(regs, MicroBlazeMMU, 3),
+ VMSTATE_END_OF_LIST()
+};
+
+static const VMStateDescription vmstate_mmu = {
+ .name = "mmu",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = vmstate_mmu_fields,
+};
+
+static int get_msr(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field)
+{
+ CPUMBState *env = container_of(opaque, CPUMBState, msr);
+
+ mb_cpu_write_msr(env, qemu_get_be32(f));
+ return 0;
+}
+
+static int put_msr(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field, QJSON *vmdesc)
+{
+ CPUMBState *env = container_of(opaque, CPUMBState, msr);
+
+ qemu_put_be32(f, mb_cpu_read_msr(env));
+ return 0;
+}
+
+static const VMStateInfo vmstate_msr = {
+ .name = "msr",
+ .get = get_msr,
+ .put = put_msr,
+};
+
+static VMStateField vmstate_env_fields[] = {
+ VMSTATE_UINT32_ARRAY(regs, CPUMBState, 32),
+
+ VMSTATE_UINT32(pc, CPUMBState),
+ VMSTATE_SINGLE(msr, CPUMBState, 0, vmstate_msr, uint32_t),
+ VMSTATE_UINT32(esr, CPUMBState),
+ VMSTATE_UINT32(fsr, CPUMBState),
+ VMSTATE_UINT32(btr, CPUMBState),
+ VMSTATE_UINT32(edr, CPUMBState),
+ VMSTATE_UINT32(slr, CPUMBState),
+ VMSTATE_UINT32(shr, CPUMBState),
+ VMSTATE_UINT64(ear, CPUMBState),
+
+ VMSTATE_UINT32(btarget, CPUMBState),
+ VMSTATE_UINT32(imm, CPUMBState),
+ VMSTATE_UINT32(iflags, CPUMBState),
+
+ VMSTATE_UINT32(res_val, CPUMBState),
+ VMSTATE_UINTTL(res_addr, CPUMBState),
+
+ VMSTATE_STRUCT(mmu, CPUMBState, 0, vmstate_mmu, MicroBlazeMMU),
+
+ VMSTATE_END_OF_LIST()
+};
+
+static const VMStateDescription vmstate_env = {
+ .name = "env",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = vmstate_env_fields,
+};
+
+static VMStateField vmstate_cpu_fields[] = {
+ VMSTATE_CPU(),
+ VMSTATE_STRUCT(env, MicroBlazeCPU, 1, vmstate_env, CPUMBState),
+ VMSTATE_END_OF_LIST()
+};
+
+const VMStateDescription vmstate_mb_cpu = {
+ .name = "cpu",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = vmstate_cpu_fields,
+};
diff --git a/target/microblaze/meson.build b/target/microblaze/meson.build
index 639c3f73a8..05ee0ec163 100644
--- a/target/microblaze/meson.build
+++ b/target/microblaze/meson.build
@@ -11,7 +11,10 @@ microblaze_ss.add(files(
))
microblaze_softmmu_ss = ss.source_set()
-microblaze_softmmu_ss.add(files('mmu.c'))
+microblaze_softmmu_ss.add(files(
+ 'mmu.c',
+ 'machine.c',
+))
target_arch += {'microblaze': microblaze_ss}
target_softmmu_arch += {'microblaze': microblaze_softmmu_ss}
diff --git a/target/microblaze/mmu.c b/target/microblaze/mmu.c
index 6e583d78d9..1dbbb271c4 100644
--- a/target/microblaze/mmu.c
+++ b/target/microblaze/mmu.c
@@ -35,7 +35,7 @@ static unsigned int tlb_decode_size(unsigned int f)
static void mmu_flush_idx(CPUMBState *env, unsigned int idx)
{
CPUState *cs = env_cpu(env);
- struct microblaze_mmu *mmu = &env->mmu;
+ MicroBlazeMMU *mmu = &env->mmu;
unsigned int tlb_size;
uint32_t tlb_tag, end, t;
@@ -55,7 +55,7 @@ static void mmu_flush_idx(CPUMBState *env, unsigned int idx)
static void mmu_change_pid(CPUMBState *env, unsigned int newpid)
{
- struct microblaze_mmu *mmu = &env->mmu;
+ MicroBlazeMMU *mmu = &env->mmu;
unsigned int i;
uint32_t t;
@@ -73,10 +73,10 @@ static void mmu_change_pid(CPUMBState *env, unsigned int newpid)
}
/* rw - 0 = read, 1 = write, 2 = fetch. */
-unsigned int mmu_translate(struct microblaze_mmu *mmu,
- struct microblaze_mmu_lookup *lu,
+unsigned int mmu_translate(MicroBlazeCPU *cpu, MicroBlazeMMULookup *lu,
target_ulong vaddr, int rw, int mmu_idx)
{
+ MicroBlazeMMU *mmu = &cpu->env.mmu;
unsigned int i, hit = 0;
unsigned int tlb_ex = 0, tlb_wr = 0, tlb_zsel;
uint64_t tlb_tag, tlb_rpn, mask;
@@ -115,13 +115,13 @@ unsigned int mmu_translate(struct microblaze_mmu *mmu,
t0 = mmu->regs[MMU_R_ZPR] >> (30 - (tlb_zsel * 2));
t0 &= 0x3;
- if (tlb_zsel > mmu->c_mmu_zones) {
+ if (tlb_zsel > cpu->cfg.mmu_zones) {
qemu_log_mask(LOG_GUEST_ERROR,
"tlb zone select out of range! %d\n", tlb_zsel);
t0 = 1; /* Ignore. */
}
- if (mmu->c_mmu == 1) {
+ if (cpu->cfg.mmu == 1) {
t0 = 1; /* Zones are disabled. */
}
@@ -158,7 +158,7 @@ unsigned int mmu_translate(struct microblaze_mmu *mmu,
tlb_rpn = d & TLB_RPN_MASK;
lu->vaddr = tlb_tag;
- lu->paddr = tlb_rpn & mmu->c_addr_mask;
+ lu->paddr = tlb_rpn & cpu->cfg.addr_mask;
lu->size = tlb_size;
lu->err = ERR_HIT;
lu->idx = i;
@@ -176,10 +176,11 @@ done:
/* Writes/reads to the MMU's special regs end up here. */
uint32_t mmu_read(CPUMBState *env, bool ext, uint32_t rn)
{
+ MicroBlazeCPU *cpu = env_archcpu(env);
unsigned int i;
uint32_t r = 0;
- if (env->mmu.c_mmu < 2 || !env->mmu.c_mmu_tlb_access) {
+ if (cpu->cfg.mmu < 2 || !cpu->cfg.mmu_tlb_access) {
qemu_log_mask(LOG_GUEST_ERROR, "MMU access on MMU-less system\n");
return 0;
}
@@ -192,7 +193,7 @@ uint32_t mmu_read(CPUMBState *env, bool ext, uint32_t rn)
/* Reads to HI/LO trig reads from the mmu rams. */
case MMU_R_TLBLO:
case MMU_R_TLBHI:
- if (!(env->mmu.c_mmu_tlb_access & 1)) {
+ if (!(cpu->cfg.mmu_tlb_access & 1)) {
qemu_log_mask(LOG_GUEST_ERROR,
"Invalid access to MMU reg %d\n", rn);
return 0;
@@ -205,7 +206,7 @@ uint32_t mmu_read(CPUMBState *env, bool ext, uint32_t rn)
break;
case MMU_R_PID:
case MMU_R_ZPR:
- if (!(env->mmu.c_mmu_tlb_access & 1)) {
+ if (!(cpu->cfg.mmu_tlb_access & 1)) {
qemu_log_mask(LOG_GUEST_ERROR,
"Invalid access to MMU reg %d\n", rn);
return 0;
@@ -228,12 +229,14 @@ uint32_t mmu_read(CPUMBState *env, bool ext, uint32_t rn)
void mmu_write(CPUMBState *env, bool ext, uint32_t rn, uint32_t v)
{
+ MicroBlazeCPU *cpu = env_archcpu(env);
uint64_t tmp64;
unsigned int i;
+
qemu_log_mask(CPU_LOG_MMU,
"%s rn=%d=%x old=%x\n", __func__, rn, v, env->mmu.regs[rn]);
- if (env->mmu.c_mmu < 2 || !env->mmu.c_mmu_tlb_access) {
+ if (cpu->cfg.mmu < 2 || !cpu->cfg.mmu_tlb_access) {
qemu_log_mask(LOG_GUEST_ERROR, "MMU access on MMU-less system\n");
return;
}
@@ -259,7 +262,7 @@ void mmu_write(CPUMBState *env, bool ext, uint32_t rn, uint32_t v)
env->mmu.rams[rn & 1][i] = deposit64(tmp64, ext * 32, 32, v);
break;
case MMU_R_ZPR:
- if (env->mmu.c_mmu_tlb_access <= 1) {
+ if (cpu->cfg.mmu_tlb_access <= 1) {
qemu_log_mask(LOG_GUEST_ERROR,
"Invalid access to MMU reg %d\n", rn);
return;
@@ -273,7 +276,7 @@ void mmu_write(CPUMBState *env, bool ext, uint32_t rn, uint32_t v)
env->mmu.regs[rn] = v;
break;
case MMU_R_PID:
- if (env->mmu.c_mmu_tlb_access <= 1) {
+ if (cpu->cfg.mmu_tlb_access <= 1) {
qemu_log_mask(LOG_GUEST_ERROR,
"Invalid access to MMU reg %d\n", rn);
return;
@@ -290,17 +293,17 @@ void mmu_write(CPUMBState *env, bool ext, uint32_t rn, uint32_t v)
break;
case MMU_R_TLBSX:
{
- struct microblaze_mmu_lookup lu;
+ MicroBlazeMMULookup lu;
int hit;
- if (env->mmu.c_mmu_tlb_access <= 1) {
+ if (cpu->cfg.mmu_tlb_access <= 1) {
qemu_log_mask(LOG_GUEST_ERROR,
"Invalid access to MMU reg %d\n", rn);
return;
}
- hit = mmu_translate(&env->mmu, &lu,
- v & TLB_EPN_MASK, 0, cpu_mmu_index(env, false));
+ hit = mmu_translate(cpu, &lu, v & TLB_EPN_MASK,
+ 0, cpu_mmu_index(env, false));
if (hit) {
env->mmu.regs[MMU_R_TLBX] = lu.idx;
} else {
@@ -314,7 +317,7 @@ void mmu_write(CPUMBState *env, bool ext, uint32_t rn, uint32_t v)
}
}
-void mmu_init(struct microblaze_mmu *mmu)
+void mmu_init(MicroBlazeMMU *mmu)
{
int i;
for (i = 0; i < ARRAY_SIZE(mmu->regs); i++) {
diff --git a/target/microblaze/mmu.h b/target/microblaze/mmu.h
index 75e5301c79..7d0fbb8341 100644
--- a/target/microblaze/mmu.h
+++ b/target/microblaze/mmu.h
@@ -63,23 +63,16 @@
#define TLB_ENTRIES 64
-struct microblaze_mmu
-{
+typedef struct {
/* Data and tag brams. */
uint64_t rams[2][TLB_ENTRIES];
/* We keep a separate ram for the tids to avoid the 48 bit tag width. */
uint8_t tids[TLB_ENTRIES];
/* Control flops. */
uint32_t regs[3];
+} MicroBlazeMMU;
- int c_mmu;
- int c_mmu_tlb_access;
- int c_mmu_zones;
- uint64_t c_addr_mask; /* Mask to apply to physical addresses. */
-};
-
-struct microblaze_mmu_lookup
-{
+typedef struct {
uint32_t paddr;
uint32_t vaddr;
unsigned int size;
@@ -88,13 +81,12 @@ struct microblaze_mmu_lookup
enum {
ERR_PROT, ERR_MISS, ERR_HIT
} err;
-};
+} MicroBlazeMMULookup;
-unsigned int mmu_translate(struct microblaze_mmu *mmu,
- struct microblaze_mmu_lookup *lu,
+unsigned int mmu_translate(MicroBlazeCPU *cpu, MicroBlazeMMULookup *lu,
target_ulong vaddr, int rw, int mmu_idx);
uint32_t mmu_read(CPUMBState *env, bool ea, uint32_t rn);
void mmu_write(CPUMBState *env, bool ea, uint32_t rn, uint32_t v);
-void mmu_init(struct microblaze_mmu *mmu);
+void mmu_init(MicroBlazeMMU *mmu);
#endif
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index 4614e99db3..757f3ff04b 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -134,7 +134,7 @@ static void update_fpu_flags(CPUMBState *env, int flags, uintptr_t ra)
raise = 1;
}
if (raise
- && (env->pvr.regs[2] & PVR2_FPU_EXC_MASK)
+ && (env_archcpu(env)->cfg.pvr_regs[2] & PVR2_FPU_EXC_MASK)
&& (env->msr & MSR_EE)) {
raise_fpu_exception(env, ra);
}
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index a8a3249185..abfcc7e6c8 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -37,7 +37,12 @@
/* is_jmp field values */
#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
-#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */
+#define DISAS_EXIT DISAS_TARGET_1 /* all cpu state modified dynamically */
+
+/* cpu state besides pc was modified dynamically; update pc to next */
+#define DISAS_EXIT_NEXT DISAS_TARGET_2
+/* cpu state besides pc was modified dynamically; update pc to btarget */
+#define DISAS_EXIT_JUMP DISAS_TARGET_3
static TCGv_i32 cpu_R[32];
static TCGv_i32 cpu_pc;
@@ -55,7 +60,7 @@ static TCGv_i32 cpu_res_val;
/* This is the state at translation time. */
typedef struct DisasContext {
DisasContextBase base;
- MicroBlazeCPU *cpu;
+ const MicroBlazeCPUConfig *cfg;
/* TCG op of the current insn_start. */
TCGOp *insn_start;
@@ -65,7 +70,6 @@ typedef struct DisasContext {
/* Decoder. */
uint32_t ext_imm;
- unsigned int cpustate_changed;
unsigned int tb_flags;
unsigned int tb_flags_to_set;
int mem_index;
@@ -143,7 +147,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
tcg_gen_exit_tb(dc->base.tb, n);
} else {
tcg_gen_movi_i32(cpu_pc, dest);
- tcg_gen_exit_tb(NULL, 0);
+ tcg_gen_lookup_and_goto_ptr();
}
dc->base.is_jmp = DISAS_NORETURN;
}
@@ -155,7 +159,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
static bool trap_illegal(DisasContext *dc, bool cond)
{
if (cond && (dc->tb_flags & MSR_EE)
- && dc->cpu->cfg.illegal_opcode_exception) {
+ && dc->cfg->illegal_opcode_exception) {
gen_raise_hw_excp(dc, ESR_EC_ILLEGAL_OP);
}
return cond;
@@ -175,6 +179,21 @@ static bool trap_userspace(DisasContext *dc, bool cond)
return cond_user;
}
+/*
+ * Return true, and log an error, if the current insn is
+ * within a delay slot.
+ */
+static bool invalid_delay_slot(DisasContext *dc, const char *insn_type)
+{
+ if (dc->tb_flags & D_FLAG) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Invalid insn in delay slot: %s at %08x\n",
+ insn_type, (uint32_t)dc->base.pc_next);
+ return true;
+ }
+ return false;
+}
+
static TCGv_i32 reg_for_read(DisasContext *dc, int reg)
{
if (likely(reg != 0)) {
@@ -272,7 +291,7 @@ static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
#define DO_TYPEA_CFG(NAME, CFG, SE, FN) \
static bool trans_##NAME(DisasContext *dc, arg_typea *a) \
- { return dc->cpu->cfg.CFG && do_typea(dc, a, SE, FN); }
+ { return dc->cfg->CFG && do_typea(dc, a, SE, FN); }
#define DO_TYPEA0(NAME, SE, FN) \
static bool trans_##NAME(DisasContext *dc, arg_typea0 *a) \
@@ -280,7 +299,7 @@ static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
#define DO_TYPEA0_CFG(NAME, CFG, SE, FN) \
static bool trans_##NAME(DisasContext *dc, arg_typea0 *a) \
- { return dc->cpu->cfg.CFG && do_typea0(dc, a, SE, FN); }
+ { return dc->cfg->CFG && do_typea0(dc, a, SE, FN); }
#define DO_TYPEBI(NAME, SE, FNI) \
static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
@@ -288,7 +307,7 @@ static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
#define DO_TYPEBI_CFG(NAME, CFG, SE, FNI) \
static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
- { return dc->cpu->cfg.CFG && do_typeb_imm(dc, a, SE, FNI); }
+ { return dc->cfg->CFG && do_typeb_imm(dc, a, SE, FNI); }
#define DO_TYPEBV(NAME, SE, FN) \
static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
@@ -496,6 +515,9 @@ DO_TYPEA_CFG(idivu, use_div, true, gen_idivu)
static bool trans_imm(DisasContext *dc, arg_imm *arg)
{
+ if (invalid_delay_slot(dc, "imm")) {
+ return true;
+ }
dc->ext_imm = arg->imm << 16;
tcg_gen_movi_i32(cpu_imm, dc->ext_imm);
dc->tb_flags_to_set = IMM_FLAG;
@@ -661,7 +683,7 @@ static TCGv compute_ldst_addr_typea(DisasContext *dc, int ra, int rb)
tcg_gen_movi_tl(ret, 0);
}
- if ((ra == 1 || rb == 1) && dc->cpu->cfg.stackprot) {
+ if ((ra == 1 || rb == 1) && dc->cfg->stackprot) {
gen_helper_stackprot(cpu_env, ret);
}
return ret;
@@ -681,7 +703,7 @@ static TCGv compute_ldst_addr_typeb(DisasContext *dc, int ra, int imm)
tcg_gen_movi_tl(ret, (uint32_t)imm);
}
- if (ra == 1 && dc->cpu->cfg.stackprot) {
+ if (ra == 1 && dc->cfg->stackprot) {
gen_helper_stackprot(cpu_env, ret);
}
return ret;
@@ -690,7 +712,7 @@ static TCGv compute_ldst_addr_typeb(DisasContext *dc, int ra, int imm)
#ifndef CONFIG_USER_ONLY
static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
{
- int addr_size = dc->cpu->cfg.addr_size;
+ int addr_size = dc->cfg->addr_size;
TCGv ret = tcg_temp_new();
if (addr_size == 32 || ra == 0) {
@@ -750,7 +772,7 @@ static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
if (size > MO_8 &&
(dc->tb_flags & MSR_EE) &&
- dc->cpu->cfg.unaligned_exceptions) {
+ dc->cfg->unaligned_exceptions) {
record_unaligned_ess(dc, rd, size, false);
mop |= MO_ALIGN;
}
@@ -896,7 +918,7 @@ static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop,
if (size > MO_8 &&
(dc->tb_flags & MSR_EE) &&
- dc->cpu->cfg.unaligned_exceptions) {
+ dc->cfg->unaligned_exceptions) {
record_unaligned_ess(dc, rd, size, true);
mop |= MO_ALIGN;
}
@@ -1063,6 +1085,9 @@ static bool do_branch(DisasContext *dc, int dest_rb, int dest_imm,
{
uint32_t add_pc;
+ if (invalid_delay_slot(dc, "branch")) {
+ return true;
+ }
if (delay) {
setup_dslot(dc, dest_rb < 0);
}
@@ -1102,6 +1127,9 @@ static bool do_bcc(DisasContext *dc, int dest_rb, int dest_imm,
{
TCGv_i32 zero, next;
+ if (invalid_delay_slot(dc, "bcc")) {
+ return true;
+ }
if (delay) {
setup_dslot(dc, dest_rb < 0);
}
@@ -1154,6 +1182,10 @@ static bool trans_brk(DisasContext *dc, arg_typea_br *arg)
if (trap_userspace(dc, true)) {
return true;
}
+ if (invalid_delay_slot(dc, "brk")) {
+ return true;
+ }
+
tcg_gen_mov_i32(cpu_pc, reg_for_read(dc, arg->rb));
if (arg->rd) {
tcg_gen_movi_i32(cpu_R[arg->rd], dc->base.pc_next);
@@ -1161,7 +1193,7 @@ static bool trans_brk(DisasContext *dc, arg_typea_br *arg)
tcg_gen_ori_i32(cpu_msr, cpu_msr, MSR_BIP);
tcg_gen_movi_tl(cpu_res_addr, -1);
- dc->base.is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_EXIT;
return true;
}
@@ -1172,6 +1204,10 @@ static bool trans_brki(DisasContext *dc, arg_typeb_br *arg)
if (trap_userspace(dc, imm != 0x8 && imm != 0x18)) {
return true;
}
+ if (invalid_delay_slot(dc, "brki")) {
+ return true;
+ }
+
tcg_gen_movi_i32(cpu_pc, imm);
if (arg->rd) {
tcg_gen_movi_i32(cpu_R[arg->rd], dc->base.pc_next);
@@ -1202,7 +1238,7 @@ static bool trans_brki(DisasContext *dc, arg_typeb_br *arg)
~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM));
}
tcg_gen_ori_i32(cpu_msr, cpu_msr, msr_to_set);
- dc->base.is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_EXIT;
#endif
return true;
@@ -1212,6 +1248,11 @@ static bool trans_mbar(DisasContext *dc, arg_mbar *arg)
{
int mbar_imm = arg->imm;
+ /* Note that mbar is a specialized branch instruction. */
+ if (invalid_delay_slot(dc, "mbar")) {
+ return true;
+ }
+
/* Data access memory barrier. */
if ((mbar_imm & 2) == 0) {
tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
@@ -1250,7 +1291,7 @@ static bool trans_mbar(DisasContext *dc, arg_mbar *arg)
*
* Therefore, choose to end the TB always.
*/
- dc->cpustate_changed = 1;
+ dc->base.is_jmp = DISAS_EXIT_NEXT;
return true;
}
@@ -1259,6 +1300,10 @@ static bool do_rts(DisasContext *dc, arg_typeb_bc *arg, int to_set)
if (trap_userspace(dc, to_set)) {
return true;
}
+ if (invalid_delay_slot(dc, "rts")) {
+ return true;
+ }
+
dc->tb_flags_to_set |= to_set;
setup_dslot(dc, true);
@@ -1280,7 +1325,7 @@ DO_RTS(rtsd, 0)
static bool trans_zero(DisasContext *dc, arg_zero *arg)
{
/* If opcode_0_illegal, trap. */
- if (dc->cpu->cfg.opcode_0_illegal) {
+ if (dc->cfg->opcode_0_illegal) {
trap_illegal(dc, true);
return true;
}
@@ -1302,19 +1347,6 @@ static void msr_read(DisasContext *dc, TCGv_i32 d)
tcg_temp_free_i32(t);
}
-#ifndef CONFIG_USER_ONLY
-static void msr_write(DisasContext *dc, TCGv_i32 v)
-{
- dc->cpustate_changed = 1;
-
- /* Install MSR_C. */
- tcg_gen_extract_i32(cpu_msr_c, v, 2, 1);
-
- /* Clear MSR_C and MSR_CC; MSR_PVR is not writable, and is always clear. */
- tcg_gen_andi_i32(cpu_msr, v, ~(MSR_C | MSR_CC | MSR_PVR));
-}
-#endif
-
static bool do_msrclrset(DisasContext *dc, arg_type_msr *arg, bool set)
{
uint32_t imm = arg->imm;
@@ -1347,7 +1379,7 @@ static bool do_msrclrset(DisasContext *dc, arg_type_msr *arg, bool set)
} else {
tcg_gen_andi_i32(cpu_msr, cpu_msr, ~imm);
}
- dc->cpustate_changed = 1;
+ dc->base.is_jmp = DISAS_EXIT_NEXT;
}
return true;
}
@@ -1380,7 +1412,13 @@ static bool trans_mts(DisasContext *dc, arg_mts *arg)
TCGv_i32 src = reg_for_read(dc, arg->ra);
switch (arg->rs) {
case SR_MSR:
- msr_write(dc, src);
+ /* Install MSR_C. */
+ tcg_gen_extract_i32(cpu_msr_c, src, 2, 1);
+ /*
+ * Clear MSR_C and MSR_CC;
+ * MSR_PVR is not writable, and is always clear.
+ */
+ tcg_gen_andi_i32(cpu_msr, src, ~(MSR_C | MSR_CC | MSR_PVR));
break;
case SR_FSR:
tcg_gen_st_i32(src, cpu_env, offsetof(CPUMBState, fsr));
@@ -1412,7 +1450,7 @@ static bool trans_mts(DisasContext *dc, arg_mts *arg)
qemu_log_mask(LOG_GUEST_ERROR, "Invalid mts reg 0x%x\n", arg->rs);
return true;
}
- dc->cpustate_changed = 1;
+ dc->base.is_jmp = DISAS_EXIT_NEXT;
return true;
#endif
}
@@ -1501,7 +1539,8 @@ static bool trans_mfs(DisasContext *dc, arg_mfs *arg)
case 0x2000 ... 0x200c:
tcg_gen_ld_i32(dest, cpu_env,
- offsetof(CPUMBState, pvr.regs[arg->rs - 0x2000]));
+ offsetof(MicroBlazeCPU, cfg.pvr_regs[arg->rs - 0x2000])
+ - offsetof(MicroBlazeCPU, env));
break;
default:
qemu_log_mask(LOG_GUEST_ERROR, "Invalid mfs reg 0x%x\n", arg->rs);
@@ -1521,7 +1560,6 @@ static void do_rti(DisasContext *dc)
tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
tcg_temp_free_i32(tmp);
- dc->tb_flags &= ~DRTI_FLAG;
}
static void do_rtb(DisasContext *dc)
@@ -1534,7 +1572,6 @@ static void do_rtb(DisasContext *dc)
tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
tcg_temp_free_i32(tmp);
- dc->tb_flags &= ~DRTB_FLAG;
}
static void do_rte(DisasContext *dc)
@@ -1548,7 +1585,6 @@ static void do_rte(DisasContext *dc)
tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
tcg_temp_free_i32(tmp);
- dc->tb_flags &= ~DRTE_FLAG;
}
/* Insns connected to FSL or AXI stream attached devices. */
@@ -1622,9 +1658,8 @@ static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
int bound;
- dc->cpu = cpu;
+ dc->cfg = &cpu->cfg;
dc->tb_flags = dc->base.tb->flags;
- dc->cpustate_changed = 0;
dc->ext_imm = dc->base.tb->cs_base;
dc->r0 = NULL;
dc->r0_set = false;
@@ -1700,20 +1735,47 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
dc->base.pc_next += 4;
if (dc->jmp_cond != TCG_COND_NEVER && !(dc->tb_flags & D_FLAG)) {
- if (dc->tb_flags & DRTI_FLAG) {
- do_rti(dc);
- } else if (dc->tb_flags & DRTB_FLAG) {
- do_rtb(dc);
- } else if (dc->tb_flags & DRTE_FLAG) {
- do_rte(dc);
+ /*
+ * Finish any return-from branch.
+ */
+ uint32_t rt_ibe = dc->tb_flags & (DRTI_FLAG | DRTB_FLAG | DRTE_FLAG);
+ if (unlikely(rt_ibe != 0)) {
+ dc->tb_flags &= ~(DRTI_FLAG | DRTB_FLAG | DRTE_FLAG);
+ if (rt_ibe & DRTI_FLAG) {
+ do_rti(dc);
+ } else if (rt_ibe & DRTB_FLAG) {
+ do_rtb(dc);
+ } else {
+ do_rte(dc);
+ }
}
- dc->base.is_jmp = DISAS_JUMP;
- }
- /* Force an exit if the per-tb cpu state has changed. */
- if (dc->base.is_jmp == DISAS_NEXT && dc->cpustate_changed) {
- dc->base.is_jmp = DISAS_UPDATE;
- tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
+ /* Complete the branch, ending the TB. */
+ switch (dc->base.is_jmp) {
+ case DISAS_NORETURN:
+ /*
+ * E.g. illegal insn in a delay slot. We've already exited
+ * and will handle D_FLAG in mb_cpu_do_interrupt.
+ */
+ break;
+ case DISAS_NEXT:
+ /*
+ * Normal insn a delay slot.
+ * However, the return-from-exception type insns should
+ * return to the main loop, as they have adjusted MSR.
+ */
+ dc->base.is_jmp = (rt_ibe ? DISAS_EXIT_JUMP : DISAS_JUMP);
+ break;
+ case DISAS_EXIT_NEXT:
+ /*
+ * E.g. mts insn in a delay slot. Continue with btarget,
+ * but still return to the main loop.
+ */
+ dc->base.is_jmp = DISAS_EXIT_JUMP;
+ break;
+ default:
+ g_assert_not_reached();
+ }
}
}
@@ -1733,13 +1795,15 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
gen_goto_tb(dc, 0, dc->base.pc_next);
return;
- case DISAS_UPDATE:
- if (unlikely(cs->singlestep_enabled)) {
- gen_raise_exception(dc, EXCP_DEBUG);
- } else {
- tcg_gen_exit_tb(NULL, 0);
- }
- return;
+ case DISAS_EXIT:
+ break;
+ case DISAS_EXIT_NEXT:
+ tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
+ break;
+ case DISAS_EXIT_JUMP:
+ tcg_gen_mov_i32(cpu_pc, cpu_btarget);
+ tcg_gen_discard_i32(cpu_btarget);
+ break;
case DISAS_JUMP:
if (dc->jmp_dest != -1 && !cs->singlestep_enabled) {
@@ -1774,13 +1838,20 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
if (unlikely(cs->singlestep_enabled)) {
gen_raise_exception(dc, EXCP_DEBUG);
} else {
- tcg_gen_exit_tb(NULL, 0);
+ tcg_gen_lookup_and_goto_ptr();
}
return;
default:
g_assert_not_reached();
}
+
+ /* Finish DISAS_EXIT_* */
+ if (unlikely(cs->singlestep_enabled)) {
+ gen_raise_exception(dc, EXCP_DEBUG);
+ } else {
+ tcg_gen_exit_tb(NULL, 0);
+ }
}
static void mb_tr_disas_log(const DisasContextBase *dcb, CPUState *cs)
@@ -1848,11 +1919,6 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
env->esr, env->fsr, env->btr, env->edr,
env->ear, env->slr, env->shr);
- for (i = 0; i < 12; i++) {
- qemu_fprintf(f, "rpvr%-2d=%08x%c",
- i, env->pvr.regs[i], i % 4 == 3 ? '\n' : ' ');
- }
-
for (i = 0; i < 32; i++) {
qemu_fprintf(f, "r%2.2d=%08x%c",
i, env->regs[i], i % 4 == 3 ? '\n' : ' ');
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 08eb674d22..749cd548f0 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -291,9 +291,9 @@ static void s390_cpu_initfn(Object *obj)
S390CPU *cpu = S390_CPU(obj);
cpu_set_cpustate_pointers(cpu);
- cs->halted = 1;
cs->exception_index = EXCP_HLT;
#if !defined(CONFIG_USER_ONLY)
+ cs->start_powered_off = true;
object_property_add(obj, "crash-information", "GuestPanicInformation",
s390_cpu_get_crash_info_qom, NULL, NULL, NULL);
cpu->env.tod_timer =
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 497f1f21ff..f93e611220 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -34,403 +34,12 @@ endif
ifneq ($(wildcard config-host.mak),)
export SRC_PATH
-# TODO don't duplicate $(SRC_PATH)/Makefile's qapi-py here
-qapi-py = $(SRC_PATH)/scripts/qapi/__init__.py \
-$(SRC_PATH)/scripts/qapi/commands.py \
-$(SRC_PATH)/scripts/qapi/common.py \
-$(SRC_PATH)/scripts/qapi/doc.py \
-$(SRC_PATH)/scripts/qapi/error.py \
-$(SRC_PATH)/scripts/qapi/events.py \
-$(SRC_PATH)/scripts/qapi/expr.py \
-$(SRC_PATH)/scripts/qapi/gen.py \
-$(SRC_PATH)/scripts/qapi/introspect.py \
-$(SRC_PATH)/scripts/qapi/parser.py \
-$(SRC_PATH)/scripts/qapi/schema.py \
-$(SRC_PATH)/scripts/qapi/source.py \
-$(SRC_PATH)/scripts/qapi/types.py \
-$(SRC_PATH)/scripts/qapi/visit.py \
-$(SRC_PATH)/scripts/qapi-gen.py
-
# Get the list of all supported sysemu targets
SYSEMU_TARGET_LIST := $(subst -softmmu.mak,,$(notdir \
$(wildcard $(SRC_PATH)/default-configs/*-softmmu.mak)))
-check-unit-y += tests/check-qdict$(EXESUF)
-check-unit-y += tests/check-block-qdict$(EXESUF)
-check-unit-y += tests/check-qnum$(EXESUF)
-check-unit-y += tests/check-qstring$(EXESUF)
-check-unit-y += tests/check-qlist$(EXESUF)
-check-unit-y += tests/check-qnull$(EXESUF)
-check-unit-y += tests/check-qobject$(EXESUF)
-check-unit-y += tests/check-qjson$(EXESUF)
-check-unit-y += tests/check-qlit$(EXESUF)
-check-unit-y += tests/test-qobject-output-visitor$(EXESUF)
-check-unit-y += tests/test-clone-visitor$(EXESUF)
-check-unit-y += tests/test-qobject-input-visitor$(EXESUF)
-check-unit-$(CONFIG_SOFTMMU) += tests/test-qmp-cmds$(EXESUF)
-check-unit-y += tests/test-string-input-visitor$(EXESUF)
-check-unit-y += tests/test-string-output-visitor$(EXESUF)
-check-unit-y += tests/test-qmp-event$(EXESUF)
-check-unit-y += tests/test-opts-visitor$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-coroutine$(EXESUF)
-check-unit-y += tests/test-visitor-serialization$(EXESUF)
-check-unit-$(CONFIG_SOFTMMU) += tests/test-iov$(EXESUF)
-check-unit-y += tests/test-bitmap$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-aio$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-aio-multithread$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-throttle$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-thread-pool$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-hbitmap$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-bdrv-drain$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-bdrv-graph-mod$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-blockjob$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-blockjob-txn$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-block-backend$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-block-iothread$(EXESUF)
-ifeq ($(CONFIG_POSIX),y)
-check-unit-$(CONFIG_BLOCK) += tests/test-image-locking$(EXESUF)
-endif
-check-unit-y += tests/test-x86-cpuid$(EXESUF)
-# all code tested by test-x86-cpuid is inside topology.h
-ifeq ($(CONFIG_SOFTMMU),y)
-check-unit-y += tests/test-xbzrle$(EXESUF)
-check-unit-$(CONFIG_POSIX) += tests/test-vmstate$(EXESUF)
-endif
-check-unit-y += tests/test-cutils$(EXESUF)
-check-unit-y += tests/test-shift128$(EXESUF)
-check-unit-y += tests/test-mul64$(EXESUF)
-check-unit-y += tests/test-int128$(EXESUF)
-# all code tested by test-int128 is inside int128.h
-check-unit-y += tests/rcutorture$(EXESUF)
-check-unit-y += tests/test-rcu-list$(EXESUF)
-check-unit-y += tests/test-rcu-simpleq$(EXESUF)
-check-unit-y += tests/test-rcu-tailq$(EXESUF)
-check-unit-y += tests/test-rcu-slist$(EXESUF)
-check-unit-y += tests/test-qdist$(EXESUF)
-check-unit-y += tests/test-qht$(EXESUF)
-check-unit-y += tests/test-qht-par$(EXESUF)
-check-unit-y += tests/test-bitops$(EXESUF)
-check-unit-y += tests/test-bitcnt$(EXESUF)
-check-unit-y += tests/test-qgraph$(EXESUF)
-check-unit-y += tests/check-qom-interface$(EXESUF)
-check-unit-y += tests/check-qom-proplist$(EXESUF)
-check-unit-y += tests/test-qemu-opts$(EXESUF)
-check-unit-y += tests/test-keyval$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-write-threshold$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-crypto-hash$(EXESUF)
-check-speed-$(CONFIG_BLOCK) += tests/benchmark-crypto-hash$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-crypto-hmac$(EXESUF)
-check-speed-$(CONFIG_BLOCK) += tests/benchmark-crypto-hmac$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-crypto-cipher$(EXESUF)
-check-speed-$(CONFIG_BLOCK) += tests/benchmark-crypto-cipher$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-crypto-secret$(EXESUF)
-check-unit-$(call land,$(CONFIG_BLOCK),$(CONFIG_GNUTLS)) += tests/test-crypto-tlscredsx509$(EXESUF)
-check-unit-$(call land,$(CONFIG_BLOCK),$(CONFIG_GNUTLS)) += tests/test-crypto-tlssession$(EXESUF)
-ifndef CONFIG_TSAN
-# Some tests: test-char, test-qdev-global-props, and test-qga,
-# are not runnable under TSan due to a known issue.
-# https://github.com/google/sanitizers/issues/1116
-check-unit-$(CONFIG_SOFTMMU) += tests/test-char$(EXESUF)
-check-unit-$(CONFIG_SOFTMMU) += tests/test-qdev-global-props$(EXESUF)
-ifeq ($(CONFIG_GUEST_AGENT),y)
-check-unit-$(call land,$(CONFIG_LINUX),$(CONFIG_VIRTIO_SERIAL)) += tests/test-qga$(EXESUF)
-endif
-endif
-check-unit-$(CONFIG_SOFTMMU) += tests/test-timed-average$(EXESUF)
-check-unit-$(call land,$(CONFIG_SOFTMMU),$(CONFIG_INOTIFY1)) += tests/test-util-filemonitor$(EXESUF)
-check-unit-$(CONFIG_SOFTMMU) += tests/test-util-sockets$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-authz-simple$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-authz-list$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-authz-listfile$(EXESUF)
-check-unit-$(call land,$(CONFIG_BLOCK),$(CONFIG_AUTH_PAM)) += tests/test-authz-pam$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-io-task$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-io-channel-socket$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-io-channel-file$(EXESUF)
-check-unit-$(call land,$(CONFIG_BLOCK),$(CONFIG_GNUTLS)) += tests/test-io-channel-tls$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-io-channel-command$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-io-channel-buffer$(EXESUF)
-check-unit-$(CONFIG_SOFTMMU) += tests/test-base64$(EXESUF)
-check-unit-$(call land,$(CONFIG_BLOCK),$(if $(CONFIG_NETTLE),y,$(CONFIG_GCRYPT))) += tests/test-crypto-pbkdf$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-crypto-ivgen$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-crypto-afsplit$(EXESUF)
-check-unit-$(call land,$(CONFIG_BLOCK),$(CONFIG_QEMU_PRIVATE_XTS)) += tests/test-crypto-xts$(EXESUF)
-check-unit-$(CONFIG_BLOCK) += tests/test-crypto-block$(EXESUF)
-check-unit-y += tests/test-logging$(EXESUF)
-check-unit-$(call land,$(CONFIG_BLOCK),$(CONFIG_REPLICATION)) += tests/test-replication$(EXESUF)
-check-unit-$(CONFIG_SOFTMMU) += tests/test-bufferiszero$(EXESUF)
-check-unit-y += tests/test-uuid$(EXESUF)
-check-unit-y += tests/ptimer-test$(EXESUF)
-check-unit-y += tests/test-qapi-util$(EXESUF)
-
-generated-files-y += tests/test-qapi-types.h
-generated-files-y += tests/include/test-qapi-types-sub-module.h
-generated-files-y += tests/test-qapi-types-sub-sub-module.h
-generated-files-y += tests/test-qapi-visit.h
-generated-files-y += tests/include/test-qapi-visit-sub-module.h
-generated-files-y += tests/test-qapi-visit-sub-sub-module.h
-generated-files-y += tests/test-qapi-commands.h
-generated-files-y += tests/test-qapi-init-commands.h
-generated-files-y += tests/include/test-qapi-commands-sub-module.h
-generated-files-y += tests/test-qapi-commands-sub-sub-module.h
-generated-files-y += tests/test-qapi-emit-events.h
-generated-files-y += tests/test-qapi-events.h
-generated-files-y += tests/include/test-qapi-events-sub-module.h
-generated-files-y += tests/test-qapi-events-sub-sub-module.h
-generated-files-y += tests/test-qapi-introspect.h
-
-QEMU_CFLAGS += -I$(SRC_PATH)/tests -I$(SRC_PATH)/tests/qtest
-
-
-# Deps that are common to various different sets of tests below
-test-util-obj-y = libqemuutil.a
-test-qom-obj-y = $(qom-obj-y) $(test-util-obj-y)
-test-qapi-obj-y = tests/test-qapi-types.o \
- tests/include/test-qapi-types-sub-module.o \
- tests/test-qapi-types-sub-sub-module.o \
- tests/test-qapi-visit.o \
- tests/include/test-qapi-visit-sub-module.o \
- tests/test-qapi-visit-sub-sub-module.o \
- tests/test-qapi-introspect.o \
- $(test-qom-obj-y)
-benchmark-crypto-obj-$(CONFIG_BLOCK) = $(authz-obj-y) $(crypto-obj-y) $(test-qom-obj-y)
-test-crypto-obj-$(CONFIG_BLOCK) = $(authz-obj-y) $(crypto-obj-y) $(test-qom-obj-y)
-test-io-obj-$(CONFIG_BLOCK) = $(io-obj-y) $(test-crypto-obj-y)
-test-authz-obj-$(CONFIG_BLOCK) = $(test-qom-obj-y) $(authz-obj-y)
-test-block-obj-$(CONFIG_BLOCK) = $(block-obj-y) $(test-io-obj-y) tests/iothread.o
-
-tests/check-qnum$(EXESUF): tests/check-qnum.o $(test-util-obj-y)
-tests/check-qstring$(EXESUF): tests/check-qstring.o $(test-util-obj-y)
-tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y)
-tests/check-block-qdict$(EXESUF): tests/check-block-qdict.o $(test-util-obj-y)
-tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y)
-tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y)
-tests/check-qobject$(EXESUF): tests/check-qobject.o $(test-util-obj-y)
-tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y)
-tests/check-qlit$(EXESUF): tests/check-qlit.o $(test-util-obj-y)
-tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y)
-tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y)
-
-tests/test-char$(EXESUF): tests/test-char.o $(test-util-obj-y) $(test-io-obj-y) $(chardev-obj-y) tests/socket-helpers.o
-tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y)
-tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y)
-tests/test-aio-multithread$(EXESUF): tests/test-aio-multithread.o $(test-block-obj-y)
-tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y)
-tests/test-bdrv-drain$(EXESUF): tests/test-bdrv-drain.o $(test-block-obj-y) $(test-util-obj-y)
-tests/test-bdrv-graph-mod$(EXESUF): tests/test-bdrv-graph-mod.o $(test-block-obj-y) $(test-util-obj-y)
-tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y)
-tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
-tests/test-block-backend$(EXESUF): tests/test-block-backend.o $(test-block-obj-y) $(test-util-obj-y)
-tests/test-block-iothread$(EXESUF): tests/test-block-iothread.o $(test-block-obj-y) $(test-util-obj-y)
-tests/test-image-locking$(EXESUF): tests/test-image-locking.o $(test-block-obj-y) $(test-util-obj-y)
-tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
-tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
-tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) $(test-crypto-obj-y)
-tests/test-bitmap$(EXESUF): tests/test-bitmap.o $(test-util-obj-y)
-tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
-tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/libmigration.fa $(test-util-obj-y) \
- $(test-io-obj-y)
-tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o $(test-util-obj-y)
-tests/test-int128$(EXESUF): tests/test-int128.o
-tests/rcutorture$(EXESUF): tests/rcutorture.o $(test-util-obj-y)
-tests/test-rcu-list$(EXESUF): tests/test-rcu-list.o $(test-util-obj-y)
-tests/test-rcu-simpleq$(EXESUF): tests/test-rcu-simpleq.o $(test-util-obj-y)
-tests/test-rcu-tailq$(EXESUF): tests/test-rcu-tailq.o $(test-util-obj-y)
-tests/test-rcu-slist$(EXESUF): tests/test-rcu-slist.o $(test-util-obj-y)
-tests/test-qdist$(EXESUF): tests/test-qdist.o $(test-util-obj-y)
-tests/test-qht$(EXESUF): tests/test-qht.o $(test-util-obj-y)
-tests/test-qht-par$(EXESUF): tests/test-qht-par.o tests/qht-bench$(EXESUF) $(test-util-obj-y)
-tests/qht-bench$(EXESUF): tests/qht-bench.o $(test-util-obj-y)
-tests/test-bufferiszero$(EXESUF): tests/test-bufferiszero.o $(test-util-obj-y)
-tests/atomic_add-bench$(EXESUF): tests/atomic_add-bench.o $(test-util-obj-y)
-tests/atomic64-bench$(EXESUF): tests/atomic64-bench.o $(test-util-obj-y)
-
-tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o hw/core/libhwcore.fa \
- $(test-qapi-obj-y)
-tests/test-vmstate$(EXESUF): tests/test-vmstate.o migration/libmigration.fa \
- $(test-io-obj-y)
-tests/test-timed-average$(EXESUF): tests/test-timed-average.o $(test-util-obj-y)
-tests/test-base64$(EXESUF): tests/test-base64.o $(test-util-obj-y)
-tests/ptimer-test$(EXESUF): tests/ptimer-test.o tests/ptimer-test-stubs.o hw/core/ptimer.o
-tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
-tests/test-keyval$(EXESUF): tests/test-keyval.o $(test-util-obj-y) $(test-qapi-obj-y)
-tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-obj-y)
-tests/test-uuid$(EXESUF): tests/test-uuid.o $(test-util-obj-y)
-tests/test-qapi-util$(EXESUF): tests/test-qapi-util.o $(test-util-obj-y)
-
-tests/test-logging$(EXESUF): tests/test-logging.o $(test-util-obj-y)
-
-tests/test-replication$(EXESUF): tests/test-replication.o $(test-util-obj-y) \
- $(test-block-obj-y)
-
-tests/test-qapi-types.c tests/test-qapi-types.h \
-tests/include/test-qapi-types-sub-module.c \
-tests/include/test-qapi-types-sub-module.h \
-tests/test-qapi-types-sub-sub-module.c \
-tests/test-qapi-types-sub-sub-module.h \
-tests/test-qapi-visit.c tests/test-qapi-visit.h \
-tests/include/test-qapi-visit-sub-module.c \
-tests/include/test-qapi-visit-sub-module.h \
-tests/test-qapi-visit-sub-sub-module.c \
-tests/test-qapi-visit-sub-sub-module.h \
-tests/test-qapi-commands.h tests/test-qapi-commands.c \
-tests/include/test-qapi-commands-sub-module.h \
-tests/include/test-qapi-commands-sub-module.c \
-tests/test-qapi-commands-sub-sub-module.h \
-tests/test-qapi-commands-sub-sub-module.c \
-tests/test-qapi-emit-events.c tests/test-qapi-emit-events.h \
-tests/test-qapi-events.c tests/test-qapi-events.h \
-tests/test-qapi-init-commands.c \
-tests/test-qapi-init-commands.h \
-tests/include/test-qapi-events-sub-module.c \
-tests/include/test-qapi-events-sub-module.h \
-tests/test-qapi-events-sub-sub-module.c \
-tests/test-qapi-events-sub-sub-module.h \
-tests/test-qapi-introspect.c tests/test-qapi-introspect.h: \
-tests/test-qapi-gen-timestamp ;
-tests/test-qapi-gen-timestamp: \
- $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json \
- $(SRC_PATH)/tests/qapi-schema/include/sub-module.json \
- $(SRC_PATH)/tests/qapi-schema/sub-sub-module.json \
- $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-gen.py \
- -o tests -p "test-" $<, \
- "GEN","$(@:%-timestamp=%)")
- @rm -f tests/test-qapi-doc.texi
- @>$@
-
-tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y)
-tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y)
-tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) tests/test-qapi-emit-events.o tests/test-qapi-events.o
-tests/test-qobject-output-visitor$(EXESUF): tests/test-qobject-output-visitor.o $(test-qapi-obj-y)
-tests/test-clone-visitor$(EXESUF): tests/test-clone-visitor.o $(test-qapi-obj-y)
-tests/test-qobject-input-visitor$(EXESUF): tests/test-qobject-input-visitor.o $(test-qapi-obj-y)
-tests/test-qmp-cmds$(EXESUF): tests/test-qmp-cmds.o tests/test-qapi-commands.o tests/test-qapi-init-commands.o $(test-qapi-obj-y)
-tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y)
-tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y)
-
-tests/test-shift128$(EXESUF): tests/test-shift128.o $(test-util-obj-y)
-tests/test-mul64$(EXESUF): tests/test-mul64.o $(test-util-obj-y)
-tests/test-bitops$(EXESUF): tests/test-bitops.o $(test-util-obj-y)
-tests/test-bitcnt$(EXESUF): tests/test-bitcnt.o $(test-util-obj-y)
-tests/test-qgraph$(EXESUF): tests/test-qgraph.o tests/qtest/libqos/qgraph.o $(test-util-obj-y)
-tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y)
-tests/benchmark-crypto-hash$(EXESUF): tests/benchmark-crypto-hash.o $(test-crypto-obj-y)
-tests/test-crypto-hmac$(EXESUF): tests/test-crypto-hmac.o $(test-crypto-obj-y)
-tests/benchmark-crypto-hmac$(EXESUF): tests/benchmark-crypto-hmac.o $(test-crypto-obj-y)
-tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y)
-tests/benchmark-crypto-cipher$(EXESUF): tests/benchmark-crypto-cipher.o $(test-crypto-obj-y)
-tests/test-crypto-secret$(EXESUF): tests/test-crypto-secret.o $(test-crypto-obj-y)
-tests/test-crypto-xts$(EXESUF): tests/test-crypto-xts.o $(test-crypto-obj-y)
-
-ifeq ($(CONFIG_TEST_SECRET_KEYRING),y)
-tests/test-crypto-secret.o-libs := -lkeyutils
-endif
-
-tests/crypto-tls-x509-helpers.o-cflags := $(TASN1_CFLAGS)
-tests/crypto-tls-x509-helpers.o-libs := $(TASN1_LIBS)
-tests/pkix_asn1_tab.o-cflags := $(TASN1_CFLAGS)
-
-tests/test-crypto-tlscredsx509.o-cflags := $(TASN1_CFLAGS)
-tests/test-crypto-tlscredsx509$(EXESUF): tests/test-crypto-tlscredsx509.o \
- tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y)
-
-tests/test-crypto-tlssession.o-cflags := $(TASN1_CFLAGS)
-tests/test-crypto-tlssession$(EXESUF): tests/test-crypto-tlssession.o \
- tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o \
- tests/crypto-tls-psk-helpers.o \
- $(test-crypto-obj-y)
-tests/test-util-filemonitor$(EXESUF): tests/test-util-filemonitor.o \
- $(test-util-obj-y)
-tests/test-util-sockets$(EXESUF): tests/test-util-sockets.o \
- tests/socket-helpers.o $(test-util-obj-y)
-tests/test-authz-simple$(EXESUF): tests/test-authz-simple.o $(test-authz-obj-y)
-tests/test-authz-list$(EXESUF): tests/test-authz-list.o $(test-authz-obj-y)
-tests/test-authz-listfile$(EXESUF): tests/test-authz-listfile.o $(test-authz-obj-y)
-tests/test-authz-pam$(EXESUF): tests/test-authz-pam.o $(test-authz-obj-y)
-tests/test-io-task$(EXESUF): tests/test-io-task.o $(test-io-obj-y)
-tests/test-io-channel-socket$(EXESUF): tests/test-io-channel-socket.o \
- tests/io-channel-helpers.o tests/socket-helpers.o $(test-io-obj-y)
-tests/test-io-channel-file$(EXESUF): tests/test-io-channel-file.o \
- tests/io-channel-helpers.o $(test-io-obj-y)
-tests/test-io-channel-tls$(EXESUF): tests/test-io-channel-tls.o \
- tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o \
- tests/io-channel-helpers.o $(test-io-obj-y)
-tests/test-io-channel-command$(EXESUF): tests/test-io-channel-command.o \
- tests/io-channel-helpers.o $(test-io-obj-y)
-tests/test-io-channel-buffer$(EXESUF): tests/test-io-channel-buffer.o \
- tests/io-channel-helpers.o $(test-io-obj-y)
-tests/test-crypto-pbkdf$(EXESUF): tests/test-crypto-pbkdf.o $(test-crypto-obj-y)
-tests/test-crypto-ivgen$(EXESUF): tests/test-crypto-ivgen.o $(test-crypto-obj-y)
-tests/test-crypto-afsplit$(EXESUF): tests/test-crypto-afsplit.o $(test-crypto-obj-y)
-tests/test-crypto-block$(EXESUF): tests/test-crypto-block.o $(test-crypto-obj-y)
-
-tests/migration/stress$(EXESUF): tests/migration/stress.o
- $(call quiet-command, $(LINKPROG) -static -O3 $(PTHREAD_LIB) -o $@ $< ,"LINK","$(TARGET_DIR)$@")
-
-INITRD_WORK_DIR=tests/migration/initrd
-
-tests/migration/initrd-stress.img: tests/migration/stress$(EXESUF)
- mkdir -p $(INITRD_WORK_DIR)
- cp $< $(INITRD_WORK_DIR)/init
- (cd $(INITRD_WORK_DIR) && (find | cpio --quiet -o -H newc | gzip -9)) > $@
- rm $(INITRD_WORK_DIR)/init
- rmdir $(INITRD_WORK_DIR)
-
-tests/test-qga$(EXESUF): qga/qemu-ga$(EXESUF)
-tests/test-qga$(EXESUF): tests/test-qga.o tests/qtest/libqtest.o $(test-util-obj-y)
-tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o $(test-util-obj-y) libvhost-user.a
-tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
-
SPEED = quick
-# gtester tests, possibly with verbose output
-# do_test_tap runs all tests, even if some of them fail, while do_test_human
-# stops at the first failure unless -k is given on the command line
-
-define do_test_human_k
- $(quiet-@)rc=0; $(foreach COMMAND, $1, \
- $(call quiet-command-run, \
- export MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$(( $${RANDOM:-0} % 255 + 1))} $2; \
- $(COMMAND) -m=$(SPEED) -k --tap < /dev/null \
- | ./scripts/tap-driver.pl --test-name="$(notdir $(COMMAND))" $(if $(V),, --show-failures-only) \
- || rc=$$?;, "TEST", "$@: $(COMMAND)")) exit $$rc
-endef
-define do_test_human_no_k
- $(foreach COMMAND, $1, \
- $(call quiet-command, \
- MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$(( $${RANDOM:-0} % 255 + 1))} $2 \
- $(COMMAND) -m=$(SPEED) -k --tap < /dev/null \
- | ./scripts/tap-driver.pl --test-name="$(notdir $(COMMAND))" $(if $(V),, --show-failures-only), \
- "TEST", "$@: $(COMMAND)")
-)
-endef
-do_test_human = \
- $(if $(findstring k, $(MAKEFLAGS)), $(do_test_human_k), $(do_test_human_no_k))
-
-define do_test_tap
- $(call quiet-command, \
- { export MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$(( $${RANDOM:-0} % 255 + 1))} $2; \
- $(foreach COMMAND, $1, \
- $(COMMAND) -m=$(SPEED) -k --tap < /dev/null \
- | sed "s/^\(not \)\?ok [0-9]* /&$(notdir $(COMMAND)) /" || true; ) } \
- | ./scripts/tap-merge.pl | tee "$@" \
- | ./scripts/tap-driver.pl $(if $(V),, --show-failures-only), \
- "TAP","$@")
-endef
-
-build-unit: $(check-unit-y)
-
-check-unit: $(check-unit-y)
- $(call do_test_human, $^)
-
-check-speed: $(check-speed-y)
- $(call do_test_human, $^)
-
-# gtester tests with TAP output
-
-check-report-unit.tap: $(check-unit-y)
- $(call do_test_tap,$^)
-
# Per guest TCG tests
BUILD_TCG_TARGET_RULES=$(patsubst %,build-tcg-tests-%, $(TARGET_DIRS))
@@ -470,7 +79,6 @@ check-tcg: $(RUN_TCG_TARGET_RULES)
.PHONY: clean-tcg
clean-tcg: $(CLEAN_TCG_TARGET_RULES)
-
# Python venv for running tests
.PHONY: check-venv check-acceptance
@@ -524,21 +132,27 @@ check-acceptance: check-venv $(TESTS_RESULTS_DIR) get-vm-images
# Consolidated targets
-.PHONY: check-block check-unit check check-clean get-vm-images
-check-block:
-check-build: build-unit
+.PHONY: check-block check check-clean get-vm-images
+check:
+
+ifeq ($(CONFIG_TOOLS)$(CONFIG_POSIX),yy)
+QEMU_IOTESTS_HELPERS-$(CONFIG_LINUX) = tests/qemu-iotests/socket_scm_helper$(EXESUF)
+check: check-block
+check-block: $(SRC_PATH)/tests/check-block.sh qemu-img$(EXESUF) \
+ qemu-io$(EXESUF) qemu-nbd$(EXESUF) $(QEMU_IOTESTS_HELPERS-y) \
+ $(patsubst %-softmmu,qemu-system-%,$(filter %-softmmu,$(TARGET_DIRS)))
+ @$<
+endif
+
+check-build: $(QEMU_IOTESTS_HELPERS-y)
check-clean:
- rm -rf $(check-unit-y) tests/*.o tests/*/*.o $(QEMU_IOTESTS_HELPERS-y)
- rm -f tests/test-qapi-gen-timestamp
rm -rf $(TESTS_VENV_DIR) $(TESTS_RESULTS_DIR)
-check: check-unit
-
clean: check-clean
-# Build the help program automatically
+# For backwards compatibility
--include $(wildcard tests/*.d)
+check-speed: bench-speed
endif
diff --git a/tests/benchmark-crypto-cipher.c b/tests/benchmark-crypto-cipher.c
index 53032334ec..1936aa4ae0 100644
--- a/tests/benchmark-crypto-cipher.c
+++ b/tests/benchmark-crypto-cipher.c
@@ -70,8 +70,8 @@ static void test_cipher_speed(size_t chunk_size,
}
g_test_timer_elapsed();
- g_print("Enc chunk %zu bytes ", chunk_size);
- g_print("%.2f MB/sec ", (double)total / MiB / g_test_timer_last());
+ g_test_message("Enc chunk %zu bytes ", chunk_size);
+ g_test_message("%.2f MB/sec ", (double)total / MiB / g_test_timer_last());
g_test_timer_start();
remain = total;
@@ -85,8 +85,8 @@ static void test_cipher_speed(size_t chunk_size,
}
g_test_timer_elapsed();
- g_print("Dec chunk %zu bytes ", chunk_size);
- g_print("%.2f MB/sec ", (double)total / MiB / g_test_timer_last());
+ g_test_message("Dec chunk %zu bytes ", chunk_size);
+ g_test_message("%.2f MB/sec ", (double)total / MiB / g_test_timer_last());
qcrypto_cipher_free(cipher);
g_free(plaintext);
diff --git a/tests/benchmark-crypto-hash.c b/tests/benchmark-crypto-hash.c
index d16837d00a..598111e75a 100644
--- a/tests/benchmark-crypto-hash.c
+++ b/tests/benchmark-crypto-hash.c
@@ -48,7 +48,7 @@ static void test_hash_speed(const void *opaque)
}
g_test_timer_elapsed();
- g_print("%.2f MB/sec ", (double)total / MiB / g_test_timer_last());
+ g_test_message("%.2f MB/sec ", (double)total / MiB / g_test_timer_last());
g_free(out);
g_free(in);
diff --git a/tests/benchmark-crypto-hmac.c b/tests/benchmark-crypto-hmac.c
index f1dfa240cb..f9fa22df95 100644
--- a/tests/benchmark-crypto-hmac.c
+++ b/tests/benchmark-crypto-hmac.c
@@ -55,10 +55,10 @@ static void test_hmac_speed(const void *opaque)
} while (g_test_timer_elapsed() < 5.0);
total /= MiB;
- g_print("hmac(sha256): ");
- g_print("Testing chunk_size %zu bytes ", chunk_size);
- g_print("done: %.2f MB in %.2f secs: ", total, g_test_timer_last());
- g_print("%.2f MB/sec\n", total / g_test_timer_last());
+ g_test_message("hmac(sha256): ");
+ g_test_message("Testing chunk_size %zu bytes ", chunk_size);
+ g_test_message("done: %.2f MB in %.2f secs: ", total, g_test_timer_last());
+ g_test_message("%.2f MB/sec\n", total / g_test_timer_last());
g_free(out);
g_free(in);
diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include
index 9119dff97d..3daabaa2fd 100644
--- a/tests/docker/Makefile.include
+++ b/tests/docker/Makefile.include
@@ -2,6 +2,10 @@
.PHONY: docker docker-test docker-clean docker-image docker-qemu-src
+NULL :=
+SPACE := $(NULL) #
+COMMA := ,
+
HOST_ARCH = $(if $(ARCH),$(ARCH),$(shell uname -m))
DOCKER_SUFFIX := .docker
diff --git a/tests/include/meson.build b/tests/include/meson.build
new file mode 100644
index 0000000000..fea3a6342f
--- /dev/null
+++ b/tests/include/meson.build
@@ -0,0 +1,16 @@
+# an extra target to workaround meson limitation on output files location
+test_qapi_outputs_extra = [
+ 'test-qapi-commands-sub-module.c',
+ 'test-qapi-commands-sub-module.h',
+ 'test-qapi-events-sub-module.c',
+ 'test-qapi-events-sub-module.h',
+ 'test-qapi-types-sub-module.c',
+ 'test-qapi-types-sub-module.h',
+ 'test-qapi-visit-sub-module.c',
+ 'test-qapi-visit-sub-module.h',
+]
+
+test_qapi_outputs_extra = custom_target('QAPI test (include)',
+ output: test_qapi_outputs_extra,
+ input: test_qapi_files,
+ command: 'true')
diff --git a/tests/meson.build b/tests/meson.build
index fe2c6d8e6b..998e4c48f9 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -1,3 +1,255 @@
+py3 = import('python').find_installation()
+
+qht_bench = executable('qht-bench',
+ sources: 'qht-bench.c',
+ dependencies: [qemuutil])
+
+executable('atomic_add-bench',
+ sources: files('atomic_add-bench.c'),
+ dependencies: [qemuutil],
+ build_by_default: false)
+
+executable('atomic64-bench',
+ sources: files('atomic64-bench.c'),
+ dependencies: [qemuutil],
+ build_by_default: false)
+
+test_qapi_outputs = [
+ 'qapi-builtin-types.c',
+ 'qapi-builtin-types.h',
+ 'qapi-builtin-visit.c',
+ 'qapi-builtin-visit.h',
+ 'test-qapi-commands-sub-sub-module.c',
+ 'test-qapi-commands-sub-sub-module.h',
+ 'test-qapi-commands.c',
+ 'test-qapi-commands.h',
+ 'test-qapi-emit-events.c',
+ 'test-qapi-emit-events.h',
+ 'test-qapi-events-sub-sub-module.c',
+ 'test-qapi-events-sub-sub-module.h',
+ 'test-qapi-events.c',
+ 'test-qapi-events.h',
+ 'test-qapi-init-commands.c',
+ 'test-qapi-init-commands.h',
+ 'test-qapi-introspect.c',
+ 'test-qapi-introspect.h',
+ 'test-qapi-types-sub-sub-module.c',
+ 'test-qapi-types-sub-sub-module.h',
+ 'test-qapi-types.c',
+ 'test-qapi-types.h',
+ 'test-qapi-visit-sub-sub-module.c',
+ 'test-qapi-visit-sub-sub-module.h',
+ 'test-qapi-visit.c',
+ 'test-qapi-visit.h',
+]
+
+test_qapi_files = custom_target('Test QAPI files',
+ output: test_qapi_outputs,
+ input: files('qapi-schema/qapi-schema-test.json',
+ 'qapi-schema/include/sub-module.json',
+ 'qapi-schema/sub-sub-module.json'),
+ command: [ qapi_gen, '-o', meson.current_build_dir(),
+ '-b', '-p', 'test-', '@INPUT0@' ],
+ depend_files: qapi_gen_depends)
+
+# meson doesn't like generated output in other directories
+# perhaps change qapi_gen to replace / with _, like Meson itself does?
+subdir('include')
+
+libtestqapi = static_library('testqapi', sources: [test_qapi_files, test_qapi_outputs_extra])
+testqapi = declare_dependency(link_with: libtestqapi)
+
+testblock = declare_dependency(dependencies: [block], sources: 'iothread.c')
+
+tests = {
+ 'check-block-qdict': [],
+ 'check-qdict': [],
+ 'check-qnum': [],
+ 'check-qstring': [],
+ 'check-qlist': [],
+ 'check-qnull': [],
+ 'check-qobject': [],
+ 'check-qjson': [],
+ 'check-qlit': [],
+ 'test-qobject-output-visitor': [testqapi],
+ 'test-clone-visitor': [testqapi],
+ 'test-qobject-input-visitor': [testqapi],
+ 'test-string-input-visitor': [testqapi],
+ 'test-string-output-visitor': [testqapi],
+ 'test-qmp-event': [testqapi],
+ 'test-opts-visitor': [testqapi],
+ 'test-visitor-serialization': [testqapi],
+ 'test-bitmap': [],
+ # all code tested by test-x86-cpuid is inside topology.h
+ 'test-x86-cpuid': [],
+ 'test-cutils': [],
+ 'test-shift128': [],
+ 'test-mul64': [],
+ # all code tested by test-int128 is inside int128.h
+ 'test-int128': [],
+ 'rcutorture': [],
+ 'test-rcu-list': [],
+ 'test-rcu-simpleq': [],
+ 'test-rcu-tailq': [],
+ 'test-rcu-slist': [],
+ 'test-qdist': [],
+ 'test-qht': [],
+ 'test-bitops': [],
+ 'test-bitcnt': [],
+ 'test-qgraph': ['qtest/libqos/qgraph.c'],
+ 'check-qom-interface': [qom],
+ 'check-qom-proplist': [qom],
+ 'test-qemu-opts': [],
+ 'test-keyval': [testqapi],
+ 'test-logging': [],
+ 'test-uuid': [],
+ 'ptimer-test': ['ptimer-test-stubs.c', meson.source_root() / 'hw/core/ptimer.c'],
+ 'test-qapi-util': [],
+}
+
+test_deps = {
+ 'test-qht-par': qht_bench,
+}
+
+benchs = {}
+
+if have_block
+ tests += {
+ 'test-coroutine': [testblock],
+ 'test-aio': [testblock],
+ 'test-aio-multithread': [testblock],
+ 'test-throttle': [testblock],
+ 'test-thread-pool': [testblock],
+ 'test-hbitmap': [testblock],
+ 'test-bdrv-drain': [testblock],
+ 'test-bdrv-graph-mod': [testblock],
+ 'test-blockjob': [testblock],
+ 'test-blockjob-txn': [testblock],
+ 'test-block-backend': [testblock],
+ 'test-block-iothread': [testblock],
+ 'test-write-threshold': [testblock],
+ 'test-crypto-hash': [crypto],
+ 'test-crypto-hmac': [crypto],
+ 'test-crypto-cipher': [crypto],
+ 'test-crypto-secret': [crypto, keyutils],
+ 'test-authz-simple': [authz],
+ 'test-authz-list': [authz],
+ 'test-authz-listfile': [authz],
+ 'test-io-task': [testblock],
+ 'test-io-channel-socket': ['socket-helpers.c', 'io-channel-helpers.c', io],
+ 'test-io-channel-file': ['io-channel-helpers.c', io],
+ 'test-io-channel-command': ['io-channel-helpers.c', io],
+ 'test-io-channel-buffer': ['io-channel-helpers.c', io],
+ 'test-crypto-ivgen': [io],
+ 'test-crypto-afsplit': [io],
+ 'test-crypto-block': [io],
+ }
+ if 'CONFIG_GNUTLS' in config_host and \
+ 'CONFIG_TASN1' in config_host
+ tests += {
+ 'test-crypto-tlscredsx509': ['crypto-tls-x509-helpers.c', 'pkix_asn1_tab.c',
+ tasn1, crypto],
+ 'test-crypto-tlssession': ['crypto-tls-x509-helpers.c', 'pkix_asn1_tab.c', 'crypto-tls-psk-helpers.c',
+ tasn1, crypto],
+ 'test-io-channel-tls': ['io-channel-helpers.c', 'crypto-tls-x509-helpers.c', 'pkix_asn1_tab.c',
+ tasn1, io, crypto]}
+ endif
+ if 'CONFIG_AUTH_PAM' in config_host
+ tests += {'test-authz-pam': [authz]}
+ endif
+ if 'CONFIG_QEMU_PRIVATE_XTS' in config_host
+ tests += {'test-crypto-xts': [crypto, io]}
+ endif
+ if 'CONFIG_POSIX' in config_host
+ tests += {'test-image-locking': [testblock]}
+ endif
+ if 'CONFIG_REPLICATION' in config_host
+ tests += {'test-replication': [testblock]}
+ endif
+ if 'CONFIG_NETTLE' in config_host or 'CONFIG_GCRYPT' in config_host
+ tests += {'test-crypto-pbkdf': [io]}
+ endif
+ benchs += {
+ 'benchmark-crypto-hash': [crypto],
+ 'benchmark-crypto-hmac': [crypto],
+ 'benchmark-crypto-cipher': [crypto],
+ }
+endif
+
+if have_system
+ tests += {
+ 'test-iov': [],
+ 'test-qmp-cmds': [testqapi],
+ 'test-xbzrle': [migration],
+ 'test-timed-average': [],
+ 'test-util-sockets': ['socket-helpers.c'],
+ 'test-base64': [],
+ 'test-bufferiszero': [],
+ 'test-vmstate': [migration, io]
+ }
+ if 'CONFIG_INOTIFY1' in config_host
+ tests += {'test-util-filemonitor': []}
+ endif
+
+ # Some tests: test-char, test-qdev-global-props, and test-qga,
+ # are not runnable under TSan due to a known issue.
+ # https://github.com/google/sanitizers/issues/1116
+ if 'CONFIG_TSAN' not in config_host
+ tests += {
+ 'test-char': ['socket-helpers.c', qom, io, chardev],
+ 'test-qdev-global-props': [qom, hwcore, testqapi]
+ }
+ endif
+endif
+
+if 'CONFIG_TSAN' not in config_host and \
+ 'CONFIG_GUEST_AGENT' in config_host and \
+ 'CONFIG_LINUX' in config_host
+ tests += {'test-qga': ['qtest/libqtest.c']}
+ test_deps += {'test-qga': qga}
+endif
+
+test_env = environment()
+test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
+test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
+
+foreach test_name, extra: tests
+ src = [test_name + '.c']
+ deps = [qemuutil]
+ if extra.length() > 0
+ # use a sourceset to quickly separate sources and deps
+ test_ss = ss.source_set()
+ test_ss.add(extra)
+ src += test_ss.all_sources()
+ deps += test_ss.all_dependencies()
+ endif
+ exe = executable(test_name, src, dependencies: deps)
+
+ test(test_name, exe,
+ depends: test_deps.get(test_name, []),
+ env: test_env,
+ args: ['--tap', '-k'],
+ protocol: 'tap',
+ suite: ['unit'])
+endforeach
+
+foreach bench_name, deps: benchs
+ exe = executable(bench_name, bench_name + '.c',
+ dependencies: [qemuutil] + deps)
+ benchmark(bench_name, exe,
+ args: ['--tap', '-k'],
+ protocol: 'tap',
+ suite: ['speed'])
+endforeach
+
+if have_tools and 'CONFIG_VHOST_USER' in config_host
+ executable('vhost-user-bridge',
+ sources: files('vhost-user-bridge.c'),
+ link_with: [libvhost_user],
+ dependencies: [qemuutil],
+ build_by_default: false)
+endif
+
if have_system and 'CONFIG_POSIX' in config_host
subdir('qemu-iotests')
endif
@@ -16,3 +268,4 @@ endif
subdir('qapi-schema')
subdir('qtest')
+subdir('migration')
diff --git a/tests/migration/initrd-stress.sh b/tests/migration/initrd-stress.sh
new file mode 100755
index 0000000000..0f20ac29a6
--- /dev/null
+++ b/tests/migration/initrd-stress.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+INITRD="$1"
+STRESS="$2"
+
+INITRD_DIR=$(mktemp -d -p '' "initrd-stress.XXXXXX")
+trap 'rm -rf $INITRD_DIR' EXIT
+
+cp "$STRESS" "$INITRD_DIR/init"
+(cd "$INITRD_DIR" && (find | cpio --quiet -o -H newc | gzip -9)) > "$INITRD"
diff --git a/tests/migration/meson.build b/tests/migration/meson.build
new file mode 100644
index 0000000000..f215ee7d3a
--- /dev/null
+++ b/tests/migration/meson.build
@@ -0,0 +1,14 @@
+stress = executable(
+ 'stress',
+ files('stress.c'),
+ dependencies: [glib],
+ link_args: ['-static'],
+ build_by_default: false,
+)
+
+custom_target(
+ 'initrd-stress.img',
+ output: 'initrd-stress.img',
+ input: stress,
+ command: [find_program('initrd-stress.sh'), '@OUTPUT@', '@INPUT@']
+)
diff --git a/tests/migration/stress.c b/tests/migration/stress.c
index a062ef6b55..0c72a420be 100644
--- a/tests/migration/stress.c
+++ b/tests/migration/stress.c
@@ -29,10 +29,12 @@ const char *argv0;
#define PAGE_SIZE 4096
+#ifndef CONFIG_GETTID
static int gettid(void)
{
return syscall(SYS_gettid);
}
+#endif
static __attribute__((noreturn)) void exit_failure(void)
{
@@ -47,19 +49,6 @@ static __attribute__((noreturn)) void exit_failure(void)
}
}
-static __attribute__((noreturn)) void exit_success(void)
-{
- if (getpid() == 1) {
- sync();
- reboot(RB_POWER_OFF);
- fprintf(stderr, "%s (%05d): ERROR: cannot reboot: %s\n",
- argv0, gettid(), strerror(errno));
- abort();
- } else {
- exit(0);
- }
-}
-
static int get_command_arg_str(const char *name,
char **val)
{
diff --git a/tests/qapi-schema/doc-bad-section.err b/tests/qapi-schema/doc-bad-section.err
index e69de29bb2..785cacc08c 100644
--- a/tests/qapi-schema/doc-bad-section.err
+++ b/tests/qapi-schema/doc-bad-section.err
@@ -0,0 +1 @@
+doc-bad-section.json:5:1: unexpected '=' markup in definition documentation
diff --git a/tests/qapi-schema/doc-bad-section.json b/tests/qapi-schema/doc-bad-section.json
index 560df4b087..8175d95867 100644
--- a/tests/qapi-schema/doc-bad-section.json
+++ b/tests/qapi-schema/doc-bad-section.json
@@ -1,9 +1,8 @@
# = section within an expression comment
-# BUG: not rejected
##
# @Enum:
-# == Produces *invalid* texinfo
+# == No good here
# @one: The _one_ {and only}
#
# @two is undocumented
diff --git a/tests/qapi-schema/doc-bad-section.out b/tests/qapi-schema/doc-bad-section.out
index 367e2a1c3e..e69de29bb2 100644
--- a/tests/qapi-schema/doc-bad-section.out
+++ b/tests/qapi-schema/doc-bad-section.out
@@ -1,24 +0,0 @@
-module None
-object q_empty
-enum QType
- prefix QTYPE
- member none
- member qnull
- member qnum
- member qstring
- member qdict
- member qlist
- member qbool
-module doc-bad-section.json
-enum Enum
- member one
- member two
-doc symbol=Enum
- body=
-== Produces *invalid* texinfo
- arg=one
-The _one_ {and only}
- arg=two
-
- section=None
-@two is undocumented
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 6757dd26a2..d78a424cd9 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -69,7 +69,8 @@ event EVT-BOXED Object
doc freeform
body=
= Section
-
+doc freeform
+ body=
== Subsection
*strong* _with emphasis_
diff --git a/tests/qemu-iotests/meson.build b/tests/qemu-iotests/meson.build
index 3de09fb8fa..60470936b4 100644
--- a/tests/qemu-iotests/meson.build
+++ b/tests/qemu-iotests/meson.build
@@ -4,7 +4,3 @@ if 'CONFIG_LINUX' in config_host
else
socket_scm_helper = []
endif
-test('qemu-iotests', sh, args: [files('../check-block.sh')],
- depends: [qemu_block_tools, emulators, socket_scm_helper],
- suite: 'block', timeout: 10000)
-
diff --git a/tests/qtest/fuzz/meson.build b/tests/qtest/fuzz/meson.build
index bb0a3f271d..b31ace7d5a 100644
--- a/tests/qtest/fuzz/meson.build
+++ b/tests/qtest/fuzz/meson.build
@@ -6,12 +6,9 @@ specific_fuzz_ss.add(when: 'CONFIG_I440FX', if_true: files('i440fx_fuzz.c'))
specific_fuzz_ss.add(when: 'CONFIG_VIRTIO_NET', if_true: files('virtio_net_fuzz.c'))
specific_fuzz_ss.add(when: 'CONFIG_VIRTIO_SCSI', if_true: files('virtio_scsi_fuzz.c'))
-# unfortunately declare_dependency does not support link_depends, so
-# this will be duplicated in meson.build
fork_fuzz = declare_dependency(
- link_args: ['-fsanitize=fuzzer',
- '-Wl,-T,' + (meson.current_source_dir() / 'fork_fuzz.ld'),
- '-Wl,-wrap,qtest_inb',
+ link_args: config_host['FUZZ_EXE_LDFLAGS'].split() +
+ ['-Wl,-wrap,qtest_inb',
'-Wl,-wrap,qtest_inw',
'-Wl,-wrap,qtest_inl',
'-Wl,-wrap,qtest_outb',
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
index 19931b9248..1cddf5bdaa 100644
--- a/tests/qtest/libqos/meson.build
+++ b/tests/qtest/libqos/meson.build
@@ -1,5 +1,4 @@
-libqos = static_library('qos',
- files('../libqtest.c',
+libqos_srcs = files('../libqtest.c',
'qgraph.c',
'qos_external.c',
'pci.c',
@@ -52,6 +51,10 @@ libqos = static_library('qos',
'arm-xilinx-zynq-a9-machine.c',
'ppc64_pseries-machine.c',
'x86_64_pc-machine.c',
-), build_by_default: false)
+)
+
+libqos = static_library('qos', libqos_srcs + genh,
+ name_suffix: 'fa',
+ build_by_default: false)
qos = declare_dependency(link_whole: libqos)
diff --git a/tests/tcg/Makefile.qemu b/tests/tcg/Makefile.qemu
index f8ad4c47be..0332bad10f 100644
--- a/tests/tcg/Makefile.qemu
+++ b/tests/tcg/Makefile.qemu
@@ -8,8 +8,6 @@
# to do it for us.
#
-include $(SRC_PATH)/rules.mak
-
# The configure script fills in extra information about
# useful docker images or alternative compiler flags.
diff --git a/tests/test-crypto-secret.c b/tests/test-crypto-secret.c
index 603a093f10..9d06176663 100644
--- a/tests/test-crypto-secret.c
+++ b/tests/test-crypto-secret.c
@@ -24,7 +24,7 @@
#include "crypto/secret.h"
#include "qapi/error.h"
#include "qemu/module.h"
-#ifdef CONFIG_TEST_SECRET_KEYRING
+#ifdef CONFIG_KEYUTILS
#include "crypto/secret_keyring.h"
#include <keyutils.h>
#endif
@@ -128,7 +128,7 @@ static void test_secret_indirect_emptyfile(void)
g_free(fname);
}
-#ifdef CONFIG_TEST_SECRET_KEYRING
+#ifdef CONFIG_KEYUTILS
#define DESCRIPTION "qemu_test_secret"
#define PAYLOAD "Test Payload"
@@ -268,7 +268,7 @@ static void test_secret_keyring_bad_key_access_right(void)
keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING);
}
-#endif /* CONFIG_TEST_SECRET_KEYRING */
+#endif /* CONFIG_KEYUTILS */
static void test_secret_noconv_base64_good(void)
{
@@ -571,7 +571,7 @@ int main(int argc, char **argv)
g_test_add_func("/crypto/secret/indirect/emptyfile",
test_secret_indirect_emptyfile);
-#ifdef CONFIG_TEST_SECRET_KEYRING
+#ifdef CONFIG_KEYUTILS
g_test_add_func("/crypto/secret/keyring/good",
test_secret_keyring_good);
g_test_add_func("/crypto/secret/keyring/revoked_key",
@@ -582,7 +582,7 @@ int main(int argc, char **argv)
test_secret_keyring_bad_serial_key);
g_test_add_func("/crypto/secret/keyring/bad_key_access_right",
test_secret_keyring_bad_key_access_right);
-#endif /* CONFIG_TEST_SECRET_KEYRING */
+#endif /* CONFIG_KEYUTILS */
g_test_add_func("/crypto/secret/noconv/base64/good",
test_secret_noconv_base64_good);
diff --git a/tests/test-qga.c b/tests/test-qga.c
index 65d7992edc..c1b173b3cb 100644
--- a/tests/test-qga.c
+++ b/tests/test-qga.c
@@ -4,7 +4,7 @@
#include <sys/socket.h>
#include <sys/un.h>
-#include "libqos/libqtest.h"
+#include "qtest/libqos/libqtest.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qlist.h"
diff --git a/ui/meson.build b/ui/meson.build
index 82f60756d9..dd6c110136 100644
--- a/ui/meson.build
+++ b/ui/meson.build
@@ -1,5 +1,5 @@
softmmu_ss.add(pixman)
-specific_ss.add(pixman) # for the include path
+specific_ss.add(when: ['CONFIG_SOFTMMU'], if_true: pixman) # for the include path
softmmu_ss.add(files(
'console.c',
@@ -35,6 +35,7 @@ softmmu_ss.add_all(when: vnc, if_true: vnc_ss)
softmmu_ss.add(when: vnc, if_false: files('vnc-stubs.c'))
softmmu_ss.add(when: [opengl, 'CONFIG_OPENGL'], if_true: files('shader.c', 'console-gl.c', 'egl-helpers.c', 'egl-context.c'))
softmmu_ss.add(when: [opengl, 'CONFIG_OPENGL_DMABUF'], if_true: files('egl-headless.c'))
+specific_ss.add(when: ['CONFIG_SOFTMMU'], if_true: opengl)
ui_modules = {}