/build/
/.doctrees
/config-devices.*
-/config-all-devices.*
-/config-all-disas.*
/config-host.*
/config-target.*
/config.status
# 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-%
# 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
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 \
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: ;
.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
# 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
-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)
# 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
@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 ''
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 '$*=$($*)'
+++ /dev/null
-#######################################################################
-# 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
))
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'))
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
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 . ' '`
block_drv_rw_whitelist=""
block_drv_ro_whitelist=""
host_cc="cc"
-libs_tools=""
audio_win_int=""
libs_qga=""
debug_info="yes"
gcov="no"
EXESUF=""
HOST_DSOSUF=".so"
-LDFLAGS_SHARED="-shared"
modules="no"
module_upgrades="no"
prefix="/usr/local"
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)
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"
;;
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"
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"
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"
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
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
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"
;;
--make=*) make="$optarg"
;;
- --install=*) install="$optarg"
+ --install=*)
;;
--python=*) python="$optarg" ; explicit_python=yes
;;
--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]
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)
# 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
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
# 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
# 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
# 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
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)
}
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"\
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
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"
elif compile_prog "-DCONFIG_LIBATTR" "-lattr" ; then
attr=yes
libattr_libs="-lattr"
- LIBS="$libattr_libs $LIBS"
libattr=yes
else
if test "$attr" = "yes" ; then
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
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"
fi
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
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); }
have_openpty="yes"
else
if compile_prog "" "-lutil" ; then
- libs_tools="-lutil $libs_tools"
have_openpty="yes"
fi
fi
$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" \
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)
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
##########################################
# 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
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"
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"
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
fi
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
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
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
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
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
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
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
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
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
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
TARGET_SYSTBL_ABI=common
mttcg="yes"
bflt="yes"
- echo "TARGET_ABI32=y" >> $config_target_mak
;;
mips|mipsel)
mttcg="yes"
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
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
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
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'))
`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
- Userspace emulators - qemu-$ARCH
- - Some (but not all) unit tests
+ - Unit tests
2) documentation
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
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
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
====================================
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
# == Subsection title
+Both are only permitted in free-form documentation.
+
'|' denotes examples:
# | Text of the example, may span
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(),
};
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'))
}
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);
}
#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;
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);
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;
}
unsigned size)
{
ARTISTState *s = opaque;
- int posx, posy;
int width, height;
trace_artist_reg_write(size, addr, artist_reg_name(addr & ~3ULL), 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:
{
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);
}
buf = vram_write_buffer(s);
+ posy = ADDR_TO_Y(addr);
+ posx = ADDR_TO_X(addr);
+
if (!buf->size) {
return;
}
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];
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;
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");
#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)
#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"
#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;
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);
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;
}
}
}
+ /* 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. */
/* 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)
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;
}
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,
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(),
};
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) */
*/
/*
- * 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;
}
/*
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;
* 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;
* 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;
* 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;
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) {
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();
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;
}
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;
}
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) {
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])) {
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;
}
uint8_t pq;
uint8_t old_pq;
- if (!xive_eas_is_valid(&xive->eat[i])) {
+ if (!xive_source_is_valid(xive, i)) {
continue;
}
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;
}
}
}
+ /*
+ * 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;
}
/* 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,
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)
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);
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'))
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;
}
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);
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;
}
'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(
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)
{
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 */
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 },
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,
};
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,
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);
}
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");
#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"
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)
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;
_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;
}
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;
/*
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;
}
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;
}
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;
}
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));
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[] = {
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"));
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,
/* NVDIMM devices */
if (mc->nvdimm_supported) {
- spapr_dt_persistent_memory(fdt);
+ spapr_dt_persistent_memory(spapr, fdt);
}
return fdt;
*/
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)) {
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;
}
{
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;
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,
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];
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) {
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,
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)
* 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;
}
--- /dev/null
+/*
+ * 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)
#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");
&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");
}
}
-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);
}
-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;
&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);
_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)));
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();
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);
#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
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;
/* 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
#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"
#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;
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);
_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")));
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'))
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)
{
}
-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)
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;
}
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;
#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
#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];
unsigned gpu_numa_id;
SpaprTpmProxy *tpm_proxy;
+ uint32_t numa_assoc_array[MAX_NODES][NUMA_ASSOC_SIZE];
+
Error *fwnmi_migration_blocker;
};
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
*
--- /dev/null
+/*
+ * 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 */
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);
void *tm_mmap;
MemoryRegion tm_mmio_kvm;
VMChangeStateEntry *change;
+
+ uint8_t hv_prio;
} SpaprXive;
typedef struct SpaprXiveClass {
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)
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
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(),
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'
'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 = []
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(),
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(),
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
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
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])
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',
'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_')
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.
# 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
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,
'gui': false,
'sources': specific_fuzz.sources(),
'dependencies': specific_fuzz.dependencies(),
- 'link_depends': [files('tests/qtest/fuzz/fork_fuzz.ld')],
}]
endif
else
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')
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']}
'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])
# 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
##
#
# Features:
# @deprecated: Member @encryption_key_missing is deprecated. It is
-# always false.
+# always false.
#
# Since: 0.14.0
#
#
# Features:
# @deprecated: Member @status is deprecated. Use @recording and
-# @locked instead.
+# @locked instead.
#
# Since: 1.3
##
#
# Features:
# @deprecated: Member @dirty-bitmaps is deprecated. Use @inserted
-# member @dirty-bitmaps instead.
+# member @dirty-bitmaps instead.
#
# Since: 0.14.0
##
#
# 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
# 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
#
# 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',
#
# 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.
#
#
# 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
#
#
# 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
#
# 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
# 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
# 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
#
# Features:
# @deprecated: This command is deprecated. Use
-# 'migrate-set-parameters' instead.
+# 'migrate-set-parameters' instead.
#
# Returns: nothing on success
#
#
# Features:
# @deprecated: This command is deprecated. Use
-# 'migrate-set-parameters' instead.
+# 'migrate-set-parameters' instead.
#
# Returns: nothing on success
#
#
# 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
#
# Features:
# @deprecated: This command is deprecated. Use
-# 'query-migrate-parameters' instead.
+# 'query-migrate-parameters' instead.
#
# Returns: XBZRLE cache size in bytes
#
#
# 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
#
# Since: 2.7
#
-# @vhost-vdpa since 5.1
+# @vhost-vdpa since 5.1
##
{ 'enum': 'NetClientDriver',
'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
-Subproject commit 4ff7639e2b86d5775fa7d5cd0dbfa4d3a385a701
+Subproject commit 73b740f77190643b2ada5ee97a9a108c6ef2a37b
+++ /dev/null
-
-# 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 '$*=$($*)'
+++ /dev/null
-#!/bin/sh
-
-grep -h '=y$' "$@" | sort -u
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]
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)
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))')
import re
import json
import argparse
+import hashlib
import shutil
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_.-]+\}"
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()
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)
# 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
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)
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('##'):
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 '##'")
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):
--- /dev/null
+#! /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)
--- /dev/null
+#!/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)
+++ /dev/null
-#! /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)
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';
};
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,
*/
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;
/* 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)) {
/* 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)) {
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;
};
# 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
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
#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"
#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
}
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;
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) {
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);
}
#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,
#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;
/* 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 | \
#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
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;
};
return MMU_KERNEL_IDX;
}
+#ifndef CONFIG_USER_ONLY
+extern const VMStateDescription vmstate_mb_cpu;
+#endif
+
#endif
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;
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;
{
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
CPUMBState *env = &cpu->env;
- struct microblaze_mmu_lookup lu;
+ MicroBlazeMMULookup lu;
unsigned int hit;
int prot;
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;
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));
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);
}
}
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;
--- /dev/null
+/*
+ * 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,
+};
))
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}
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;
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;
}
/* 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;
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. */
}
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;
/* 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;
}
/* 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;
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;
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;
}
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;
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;
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 {
}
}
-void mmu_init(struct microblaze_mmu *mmu)
+void mmu_init(MicroBlazeMMU *mmu)
{
int i;
for (i = 0; i < ARRAY_SIZE(mmu->regs); i++) {
#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;
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
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);
}
/* 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;
/* 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;
/* Decoder. */
uint32_t ext_imm;
- unsigned int cpustate_changed;
unsigned int tb_flags;
unsigned int tb_flags_to_set;
int mem_index;
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;
}
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;
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)) {
#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) \
#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) \
#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) \
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;
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;
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;
#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) {
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;
}
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;
}
{
uint32_t add_pc;
+ if (invalid_delay_slot(dc, "branch")) {
+ return true;
+ }
if (delay) {
setup_dslot(dc, dest_rb < 0);
}
{
TCGv_i32 zero, next;
+ if (invalid_delay_slot(dc, "bcc")) {
+ return true;
+ }
if (delay) {
setup_dslot(dc, dest_rb < 0);
}
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);
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;
}
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);
~(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;
{
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);
*
* Therefore, choose to end the TB always.
*/
- dc->cpustate_changed = 1;
+ dc->base.is_jmp = DISAS_EXIT_NEXT;
return true;
}
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);
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;
}
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;
} else {
tcg_gen_andi_i32(cpu_msr, cpu_msr, ~imm);
}
- dc->cpustate_changed = 1;
+ dc->base.is_jmp = DISAS_EXIT_NEXT;
}
return true;
}
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));
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
}
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);
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)
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)
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. */
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;
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();
+ }
}
}
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) {
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)
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' : ' ');
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 =
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))
.PHONY: clean-tcg
clean-tcg: $(CLEAN_TCG_TARGET_RULES)
-
# Python venv for running tests
.PHONY: check-venv check-acceptance
# 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
}
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;
}
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);
}
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);
} 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);
.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
--- /dev/null
+# 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')
+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
subdir('qapi-schema')
subdir('qtest')
+subdir('migration')
--- /dev/null
+#!/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"
--- /dev/null
+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@']
+)
#define PAGE_SIZE 4096
+#ifndef CONFIG_GETTID
static int gettid(void)
{
return syscall(SYS_gettid);
}
+#endif
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)
{
+doc-bad-section.json:5:1: unexpected '=' markup in definition documentation
# = section within an expression comment
-# BUG: not rejected
##
# @Enum:
-# == Produces *invalid* texinfo
+# == No good here
# @one: The _one_ {and only}
#
# @two is undocumented
-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
doc freeform
body=
= Section
-
+doc freeform
+ body=
== Subsection
*strong* _with emphasis_
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)
-
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',
-libqos = static_library('qos',
- files('../libqtest.c',
+libqos_srcs = files('../libqtest.c',
'qgraph.c',
'qos_external.c',
'pci.c',
'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)
# 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.
#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
g_free(fname);
}
-#ifdef CONFIG_TEST_SECRET_KEYRING
+#ifdef CONFIG_KEYUTILS
#define DESCRIPTION "qemu_test_secret"
#define PAYLOAD "Test Payload"
keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING);
}
-#endif /* CONFIG_TEST_SECRET_KEYRING */
+#endif /* CONFIG_KEYUTILS */
static void test_secret_noconv_base64_good(void)
{
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",
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);
#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"
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',
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 = {}