diff options
Diffstat (limited to 'tests')
146 files changed, 2325 insertions, 3667 deletions
diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include index 9f464cb92c..ff5d732889 100644 --- a/tests/docker/Makefile.include +++ b/tests/docker/Makefile.include @@ -140,25 +140,46 @@ docker-image-debian-mips-cross: docker-image-debian10 docker-image-debian-mips64-cross: docker-image-debian10 docker-image-debian-mips64el-cross: docker-image-debian10 docker-image-debian-mipsel-cross: docker-image-debian10 -docker-image-debian-powerpc-cross: docker-image-debian10 -docker-image-debian-ppc64-cross: docker-image-debian10 docker-image-debian-ppc64el-cross: docker-image-debian10 docker-image-debian-riscv64-cross: docker-image-debian10 docker-image-debian-s390x-cross: docker-image-debian10 docker-image-debian-sh4-cross: docker-image-debian10 docker-image-debian-sparc64-cross: docker-image-debian10 +# +# The build rule for hexagon-cross is special in so far for most of +# the time we don't want to build it. While dockers caching does avoid +# this most of the time sometimes we want to force the issue. +# +docker-image-debian-hexagon-cross: $(DOCKER_FILES_DIR)/debian-hexagon-cross.docker + $(if $(NOCACHE), \ + $(call quiet-command, \ + $(DOCKER_SCRIPT) build -t qemu/debian-hexagon-cross -f $< \ + $(if $V,,--quiet) --no-cache \ + --registry $(DOCKER_REGISTRY) --extra-files \ + $(DOCKER_FILES_DIR)/debian-hexagon-cross.docker.d/build-toolchain.sh, \ + "BUILD", "debian-hexagon-cross"), \ + $(call quiet-command, \ + $(DOCKER_SCRIPT) fetch $(if $V,,--quiet) \ + qemu/debian-hexagon-cross $(DOCKER_REGISTRY), \ + "FETCH", "debian-hexagon-cross") \ + $(call quiet-command, \ + $(DOCKER_SCRIPT) update $(if $V,,--quiet) \ + qemu/debian-hexagon-cross --add-current-user, \ + "PREPARE", "debian-hexagon-cross")) + # Specialist build images, sometimes very limited tools docker-image-debian-tricore-cross: docker-image-debian10 docker-image-debian-all-test-cross: docker-image-debian10 docker-image-debian-arm64-test-cross: docker-image-debian11 +docker-image-debian-powerpc-test-cross: docker-image-debian11 # These images may be good enough for building tests but not for test builds DOCKER_PARTIAL_IMAGES += debian-alpha-cross DOCKER_PARTIAL_IMAGES += debian-arm64-test-cross +DOCKER_PARTIAL_IMAGES += debian-powerpc-test-cross DOCKER_PARTIAL_IMAGES += debian-hppa-cross DOCKER_PARTIAL_IMAGES += debian-m68k-cross debian-mips64-cross -DOCKER_PARTIAL_IMAGES += debian-powerpc-cross debian-ppc64-cross DOCKER_PARTIAL_IMAGES += debian-riscv64-cross DOCKER_PARTIAL_IMAGES += debian-sh4-cross debian-sparc64-cross DOCKER_PARTIAL_IMAGES += debian-tricore-cross @@ -248,7 +269,7 @@ docker-run: docker-qemu-src $(if $(EXECUTABLE), \ $(call quiet-command, \ $(DOCKER_SCRIPT) update \ - $(IMAGE) $(EXECUTABLE), \ + $(IMAGE) --executable $(EXECUTABLE), \ " COPYING $(EXECUTABLE) to $(IMAGE)")) $(call quiet-command, \ $(DOCKER_SCRIPT) run \ diff --git a/tests/docker/docker.py b/tests/docker/docker.py index d28df4c140..4d9bb7c7ed 100755 --- a/tests/docker/docker.py +++ b/tests/docker/docker.py @@ -515,16 +515,36 @@ class BuildCommand(SubCommand): return 0 +class FetchCommand(SubCommand): + """ Fetch a docker image from the registry. Args: <tag> <registry>""" + name = "fetch" + + def args(self, parser): + parser.add_argument("tag", + help="Local tag for image") + parser.add_argument("registry", + help="Docker registry") + + def run(self, args, argv): + dkr = Docker() + dkr.command(cmd="pull", quiet=args.quiet, + argv=["%s/%s" % (args.registry, args.tag)]) + dkr.command(cmd="tag", quiet=args.quiet, + argv=["%s/%s" % (args.registry, args.tag), args.tag]) + class UpdateCommand(SubCommand): - """ Update a docker image with new executables. Args: <tag> <executable>""" + """ Update a docker image. Args: <tag> <actions>""" name = "update" def args(self, parser): parser.add_argument("tag", help="Image Tag") - parser.add_argument("executable", + parser.add_argument("--executable", help="Executable to copy") + parser.add_argument("--add-current-user", "-u", dest="user", + action="store_true", + help="Add the current user to image's passwd") def run(self, args, argv): # Create a temporary tarball with our whole build context and @@ -532,28 +552,44 @@ class UpdateCommand(SubCommand): tmp = tempfile.NamedTemporaryFile(suffix="dckr.tar.gz") tmp_tar = TarFile(fileobj=tmp, mode='w') - # Add the executable to the tarball, using the current - # configured binfmt_misc path. If we don't get a path then we - # only need the support libraries copied - ff, enabled = _check_binfmt_misc(args.executable) - - if not enabled: - print("binfmt_misc not enabled, update disabled") - return 1 - - if ff: - tmp_tar.add(args.executable, arcname=ff) - - # Add any associated libraries - libs = _get_so_libs(args.executable) - if libs: - for l in libs: - tmp_tar.add(os.path.realpath(l), arcname=l) - # Create a Docker buildfile df = StringIO() df.write(u"FROM %s\n" % args.tag) - df.write(u"ADD . /\n") + + if args.executable: + # Add the executable to the tarball, using the current + # configured binfmt_misc path. If we don't get a path then we + # only need the support libraries copied + ff, enabled = _check_binfmt_misc(args.executable) + + if not enabled: + print("binfmt_misc not enabled, update disabled") + return 1 + + if ff: + tmp_tar.add(args.executable, arcname=ff) + + # Add any associated libraries + libs = _get_so_libs(args.executable) + if libs: + for l in libs: + so_path = os.path.dirname(l) + name = os.path.basename(l) + real_l = os.path.realpath(l) + try: + tmp_tar.add(real_l, arcname="%s/%s" % (so_path, name)) + except FileNotFoundError: + print("Couldn't add %s/%s to archive" % (so_path, name)) + pass + + df.write(u"ADD . /\n") + + if args.user: + uid = os.getuid() + uname = getpwuid(uid).pw_name + df.write("\n") + df.write("RUN id %s 2>/dev/null || useradd -u %d -U %s" % + (uname, uid, uname)) df_bytes = BytesIO(bytes(df.getvalue(), "UTF-8")) diff --git a/tests/docker/dockerfiles/alpine.docker b/tests/docker/dockerfiles/alpine.docker index d63a269aef..7eeecacc46 100644 --- a/tests/docker/dockerfiles/alpine.docker +++ b/tests/docker/dockerfiles/alpine.docker @@ -9,6 +9,7 @@ ENV PACKAGES \ alsa-lib-dev \ bash \ binutils \ + ccache \ coreutils \ curl-dev \ g++ \ @@ -19,6 +20,7 @@ ENV PACKAGES \ gnutls-dev \ gtk+3.0-dev \ libaio-dev \ + libbpf-dev \ libcap-ng-dev \ libjpeg-turbo-dev \ libnfs-dev \ @@ -39,6 +41,7 @@ ENV PACKAGES \ pulseaudio-dev \ python3 \ py3-sphinx \ + py3-sphinx_rtd_theme \ shadow \ snappy-dev \ spice-dev \ diff --git a/tests/docker/dockerfiles/centos8.docker b/tests/docker/dockerfiles/centos8.docker index a8c6c528b0..efc1349cc8 100644 --- a/tests/docker/dockerfiles/centos8.docker +++ b/tests/docker/dockerfiles/centos8.docker @@ -14,6 +14,7 @@ ENV PACKAGES \ git \ glib2-devel \ libaio-devel \ + libbpf-devel \ libepoxy-devel \ libfdt-devel \ libgcrypt-devel \ diff --git a/tests/docker/dockerfiles/debian-hexagon-cross.docker b/tests/docker/dockerfiles/debian-hexagon-cross.docker new file mode 100644 index 0000000000..d5dc299dc1 --- /dev/null +++ b/tests/docker/dockerfiles/debian-hexagon-cross.docker @@ -0,0 +1,45 @@ +# +# Docker Hexagon cross-compiler target +# +# This docker target is used for building hexagon tests. As it also +# needs to be able to build QEMU itself in CI we include it's +# build-deps. It is also a "stand-alone" image so as not to be +# triggered by re-builds on other base images given it takes a long +# time to build. +# +FROM qemu/debian10 + +# Install common build utilities +RUN apt update && \ + DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \ + DEBIAN_FRONTEND=noninteractive eatmydata \ + apt install -y --no-install-recommends \ + bison \ + cmake \ + flex \ + lld \ + rsync \ + wget + +ENV TOOLCHAIN_INSTALL /usr/local +ENV ROOTFS /usr/local + +ENV LLVM_URL https://github.com/llvm/llvm-project/archive/bfcd21876adc3498065e4da92799f613e730d475.tar.gz +ENV MUSL_URL https://github.com/quic/musl/archive/aff74b395fbf59cd7e93b3691905aa1af6c0778c.tar.gz +ENV LINUX_URL https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.6.18.tar.xz + +ADD build-toolchain.sh /root/hexagon-toolchain/build-toolchain.sh + +RUN cd /root/hexagon-toolchain && ./build-toolchain.sh + +FROM debian:buster-slim +# Duplicate deb line as deb-src +RUN cat /etc/apt/sources.list | sed "s/^deb\ /deb-src /" >> /etc/apt/sources.list +# Install QEMU build deps for use in CI +RUN apt update && \ + DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \ + DEBIAN_FRONTEND=noninteractive eatmydata apt install -yy git ninja-build && \ + DEBIAN_FRONTEND=noninteractive eatmydata \ + apt build-dep -yy --arch-only qemu +COPY --from=0 /usr/local /usr/local +ENV PATH $PATH:/usr/local/bin/ diff --git a/tests/docker/dockerfiles/debian-hexagon-cross.docker.d/build-toolchain.sh b/tests/docker/dockerfiles/debian-hexagon-cross.docker.d/build-toolchain.sh new file mode 100755 index 0000000000..19b1c9f83e --- /dev/null +++ b/tests/docker/dockerfiles/debian-hexagon-cross.docker.d/build-toolchain.sh @@ -0,0 +1,141 @@ +#!/bin/bash + +set -e + +BASE=$(readlink -f ${PWD}) + +TOOLCHAIN_INSTALL=$(readlink -f "$TOOLCHAIN_INSTALL") +ROOTFS=$(readlink -f "$ROOTFS") + +TOOLCHAIN_BIN=${TOOLCHAIN_INSTALL}/bin +HEX_SYSROOT=${TOOLCHAIN_INSTALL}/hexagon-unknown-linux-musl +HEX_TOOLS_TARGET_BASE=${HEX_SYSROOT}/usr + +function cdp() { + DIR="$1" + mkdir -p "$DIR" + cd "$DIR" +} + +function fetch() { + DIR="$1" + URL="$2" + TEMP="$(readlink -f "$PWD/tmp.tar.gz")" + wget --quiet "$URL" -O "$TEMP" + cdp "$DIR" + tar xaf "$TEMP" --strip-components=1 + rm "$TEMP" + cd - +} + +build_llvm_clang() { + fetch "$BASE/llvm-project" "$LLVM_URL" + cdp "$BASE/build-llvm" + + cmake -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=${TOOLCHAIN_INSTALL} \ + -DLLVM_ENABLE_LLD=ON \ + -DLLVM_TARGETS_TO_BUILD="Hexagon" \ + -DLLVM_ENABLE_PROJECTS="clang;lld" \ + "$BASE/llvm-project/llvm" + ninja all install + cd ${TOOLCHAIN_BIN} + ln -sf clang hexagon-unknown-linux-musl-clang + ln -sf clang++ hexagon-unknown-linux-musl-clang++ + ln -sf llvm-ar hexagon-unknown-linux-musl-ar + ln -sf llvm-objdump hexagon-unknown-linux-musl-objdump + ln -sf llvm-objcopy hexagon-unknown-linux-musl-objcopy + ln -sf llvm-readelf hexagon-unknown-linux-musl-readelf + ln -sf llvm-ranlib hexagon-unknown-linux-musl-ranlib + + # workaround for now: + cat <<EOF > hexagon-unknown-linux-musl.cfg +-G0 --sysroot=${HEX_SYSROOT} +EOF +} + +build_clang_rt() { + cdp "$BASE/build-clang_rt" + cmake -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_CONFIG_PATH="$BASE/build-llvm/bin/llvm-config" \ + -DCMAKE_ASM_FLAGS="-G0 -mlong-calls -fno-pic --target=hexagon-unknown-linux-musl " \ + -DCMAKE_SYSTEM_NAME=Linux \ + -DCMAKE_C_COMPILER="${TOOLCHAIN_BIN}/hexagon-unknown-linux-musl-clang" \ + -DCMAKE_ASM_COMPILER="${TOOLCHAIN_BIN}/hexagon-unknown-linux-musl-clang" \ + -DCMAKE_INSTALL_PREFIX=${HEX_TOOLS_TARGET_BASE} \ + -DCMAKE_CROSSCOMPILING=ON \ + -DCMAKE_C_COMPILER_FORCED=ON \ + -DCMAKE_CXX_COMPILER_FORCED=ON \ + -DCOMPILER_RT_BUILD_BUILTINS=ON \ + -DCOMPILER_RT_BUILTINS_ENABLE_PIC=OFF \ + -DCMAKE_SIZEOF_VOID_P=4 \ + -DCOMPILER_RT_OS_DIR= \ + -DCAN_TARGET_hexagon=1 \ + -DCAN_TARGET_x86_64=0 \ + -DCOMPILER_RT_SUPPORTED_ARCH=hexagon \ + -DLLVM_ENABLE_PROJECTS="compiler-rt" \ + "$BASE/llvm-project/compiler-rt" + ninja install-compiler-rt +} + +build_musl_headers() { + fetch "$BASE/musl" "$MUSL_URL" + cd "$BASE/musl" + make clean + CC=${TOOLCHAIN_BIN}/hexagon-unknown-linux-musl-clang \ + CROSS_COMPILE=hexagon-unknown-linux-musl \ + LIBCC=${HEX_TOOLS_TARGET_BASE}/lib/libclang_rt.builtins-hexagon.a \ + CROSS_CFLAGS="-G0 -O0 -mv65 -fno-builtin -fno-rounding-math --target=hexagon-unknown-linux-musl" \ + ./configure --target=hexagon --prefix=${HEX_TOOLS_TARGET_BASE} + PATH=${TOOLCHAIN_BIN}:$PATH make CROSS_COMPILE= install-headers + + cd ${HEX_SYSROOT}/.. + ln -sf hexagon-unknown-linux-musl hexagon +} + +build_kernel_headers() { + fetch "$BASE/linux" "$LINUX_URL" + mkdir -p "$BASE/build-linux" + cd "$BASE/linux" + make O=../build-linux ARCH=hexagon \ + KBUILD_CFLAGS_KERNEL="-mlong-calls" \ + CC=${TOOLCHAIN_BIN}/hexagon-unknown-linux-musl-clang \ + LD=${TOOLCHAIN_BIN}/ld.lld \ + KBUILD_VERBOSE=1 comet_defconfig + make mrproper + + cd "$BASE/build-linux" + make \ + ARCH=hexagon \ + CC=${TOOLCHAIN_BIN}/clang \ + INSTALL_HDR_PATH=${HEX_TOOLS_TARGET_BASE} \ + V=1 \ + headers_install +} + +build_musl() { + cd "$BASE/musl" + make clean + CROSS_COMPILE=hexagon-unknown-linux-musl- \ + AR=llvm-ar \ + RANLIB=llvm-ranlib \ + STRIP=llvm-strip \ + CC=clang \ + LIBCC=${HEX_TOOLS_TARGET_BASE}/lib/libclang_rt.builtins-hexagon.a \ + CFLAGS="-G0 -O0 -mv65 -fno-builtin -fno-rounding-math --target=hexagon-unknown-linux-musl" \ + ./configure --target=hexagon --prefix=${HEX_TOOLS_TARGET_BASE} + PATH=${TOOLCHAIN_BIN}/:$PATH make CROSS_COMPILE= install + cd ${HEX_TOOLS_TARGET_BASE}/lib + ln -sf libc.so ld-musl-hexagon.so + ln -sf ld-musl-hexagon.so ld-musl-hexagon.so.1 + cdp ${HEX_TOOLS_TARGET_BASE}/../lib + ln -sf ../usr/lib/ld-musl-hexagon.so.1 +} + +build_llvm_clang +build_kernel_headers +build_musl_headers +build_clang_rt +build_musl diff --git a/tests/docker/dockerfiles/debian-powerpc-cross.docker b/tests/docker/dockerfiles/debian-powerpc-cross.docker deleted file mode 100644 index 07e1789650..0000000000 --- a/tests/docker/dockerfiles/debian-powerpc-cross.docker +++ /dev/null @@ -1,12 +0,0 @@ -# -# Docker powerpc cross-compiler target -# -# This docker target builds on the debian Buster base image. -# -FROM qemu/debian10 - -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ - gcc-powerpc-linux-gnu \ - libc6-dev-powerpc-cross diff --git a/tests/docker/dockerfiles/debian-powerpc-test-cross.docker b/tests/docker/dockerfiles/debian-powerpc-test-cross.docker new file mode 100644 index 0000000000..36b336f709 --- /dev/null +++ b/tests/docker/dockerfiles/debian-powerpc-test-cross.docker @@ -0,0 +1,17 @@ +# +# Docker powerpc/ppc64/ppc64le cross-compiler target +# +# This docker target builds on the debian Bullseye base image. +# +FROM qemu/debian11 + +RUN apt update && \ + DEBIAN_FRONTEND=noninteractive eatmydata \ + apt install -y --no-install-recommends \ + gcc-powerpc-linux-gnu \ + libc6-dev-powerpc-cross \ + gcc-10-powerpc64-linux-gnu \ + libc6-dev-ppc64-cross \ + gcc-10-powerpc64le-linux-gnu \ + libc6-dev-ppc64el-cross + diff --git a/tests/docker/dockerfiles/debian-ppc64-cross.docker b/tests/docker/dockerfiles/debian-ppc64-cross.docker deleted file mode 100644 index 8efe68874e..0000000000 --- a/tests/docker/dockerfiles/debian-ppc64-cross.docker +++ /dev/null @@ -1,11 +0,0 @@ -# -# Docker ppc64 cross-compiler target -# -# This docker target builds on the debian Buster base image. -FROM qemu/debian10 - -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ - gcc-powerpc64-linux-gnu \ - libc6-dev-ppc64-cross diff --git a/tests/docker/dockerfiles/debian10.docker b/tests/docker/dockerfiles/debian10.docker index d034acbd25..63cf835ec5 100644 --- a/tests/docker/dockerfiles/debian10.docker +++ b/tests/docker/dockerfiles/debian10.docker @@ -32,6 +32,7 @@ RUN apt update && \ psmisc \ python3 \ python3-sphinx \ + python3-sphinx-rtd-theme \ $(apt-get -s build-dep --arch-only qemu | egrep ^Inst | fgrep '[all]' | cut -d\ -f2) ENV FEATURES docs diff --git a/tests/docker/dockerfiles/fedora-i386-cross.docker b/tests/docker/dockerfiles/fedora-i386-cross.docker index 966072c08e..66cdb06c19 100644 --- a/tests/docker/dockerfiles/fedora-i386-cross.docker +++ b/tests/docker/dockerfiles/fedora-i386-cross.docker @@ -1,6 +1,7 @@ FROM fedora:33 ENV PACKAGES \ bzip2 \ + ccache \ diffutils \ findutils \ gcc \ diff --git a/tests/docker/dockerfiles/fedora-win32-cross.docker b/tests/docker/dockerfiles/fedora-win32-cross.docker index 81b5659e9c..3733df63e9 100644 --- a/tests/docker/dockerfiles/fedora-win32-cross.docker +++ b/tests/docker/dockerfiles/fedora-win32-cross.docker @@ -4,6 +4,7 @@ FROM fedora:33 ENV PACKAGES \ bc \ bzip2 \ + ccache \ diffutils \ findutils \ gcc \ diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker index bcb428e724..2564ce4979 100644 --- a/tests/docker/dockerfiles/fedora-win64-cross.docker +++ b/tests/docker/dockerfiles/fedora-win64-cross.docker @@ -4,6 +4,7 @@ FROM fedora:33 ENV PACKAGES \ bc \ bzip2 \ + ccache \ diffutils \ findutils \ gcc \ diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker index 915fdc1845..0979c0e1f4 100644 --- a/tests/docker/dockerfiles/fedora.docker +++ b/tests/docker/dockerfiles/fedora.docker @@ -32,6 +32,7 @@ ENV PACKAGES \ libcurl-devel \ libepoxy-devel \ libfdt-devel \ + libbpf-devel \ libiscsi-devel \ libjpeg-devel \ libpmem-devel \ @@ -92,6 +93,7 @@ ENV PACKAGES \ python3-pillow \ python3-pip \ python3-sphinx \ + python3-sphinx_rtd_theme \ python3-virtualenv \ rdma-core-devel \ SDL2-devel \ diff --git a/tests/docker/dockerfiles/opensuse-leap.docker b/tests/docker/dockerfiles/opensuse-leap.docker index 0e64893e4a..f7e1cbfbe6 100644 --- a/tests/docker/dockerfiles/opensuse-leap.docker +++ b/tests/docker/dockerfiles/opensuse-leap.docker @@ -5,6 +5,7 @@ ENV PACKAGES \ bc \ brlapi-devel \ bzip2 \ + ccache \ cyrus-sasl-devel \ gcc \ gcc-c++ \ diff --git a/tests/docker/dockerfiles/ubuntu.docker b/tests/docker/dockerfiles/ubuntu.docker index b5ef7a8198..98a527361c 100644 --- a/tests/docker/dockerfiles/ubuntu.docker +++ b/tests/docker/dockerfiles/ubuntu.docker @@ -63,6 +63,7 @@ ENV PACKAGES \ ninja-build \ python3-yaml \ python3-sphinx \ + python3-sphinx-rtd-theme \ sparse \ xfslibs-dev RUN apt-get update && \ diff --git a/tests/docker/dockerfiles/ubuntu1804.docker b/tests/docker/dockerfiles/ubuntu1804.docker index 9b0a19ba5e..c0d3642507 100644 --- a/tests/docker/dockerfiles/ubuntu1804.docker +++ b/tests/docker/dockerfiles/ubuntu1804.docker @@ -48,6 +48,7 @@ ENV PACKAGES \ make \ python3-yaml \ python3-sphinx \ + python3-sphinx-rtd-theme \ ninja-build \ sparse \ xfslibs-dev diff --git a/tests/docker/dockerfiles/ubuntu2004.docker b/tests/docker/dockerfiles/ubuntu2004.docker index 9750016e51..f1e0ebad49 100644 --- a/tests/docker/dockerfiles/ubuntu2004.docker +++ b/tests/docker/dockerfiles/ubuntu2004.docker @@ -58,6 +58,7 @@ ENV PACKAGES flex bison \ python3-pil \ python3-pip \ python3-sphinx \ + python3-sphinx-rtd-theme \ python3-venv \ python3-yaml \ rpm2cpio \ diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c index 4ba5e1d2d4..c24baf8535 100644 --- a/tests/fp/fp-bench.c +++ b/tests/fp/fp-bench.c @@ -14,6 +14,7 @@ #include <math.h> #include <fenv.h> #include "qemu/timer.h" +#include "qemu/int128.h" #include "fpu/softfloat.h" /* amortize the computation of random inputs */ @@ -50,8 +51,10 @@ static const char * const op_names[] = { enum precision { PREC_SINGLE, PREC_DOUBLE, + PREC_QUAD, PREC_FLOAT32, PREC_FLOAT64, + PREC_FLOAT128, PREC_MAX_NR, }; @@ -89,6 +92,7 @@ union fp { double d; float32 f32; float64 f64; + float128 f128; uint64_t u64; }; @@ -113,6 +117,10 @@ struct op_desc { static uint64_t random_ops[MAX_OPERANDS] = { SEED_A, SEED_B, SEED_C, }; + +static float128 random_quad_ops[MAX_OPERANDS] = { + {SEED_A, SEED_B}, {SEED_B, SEED_C}, {SEED_C, SEED_A}, +}; static float_status soft_status; static enum precision precision; static enum op operation; @@ -141,25 +149,45 @@ static void update_random_ops(int n_ops, enum precision prec) int i; for (i = 0; i < n_ops; i++) { - uint64_t r = random_ops[i]; switch (prec) { case PREC_SINGLE: case PREC_FLOAT32: + { + uint64_t r = random_ops[i]; do { r = xorshift64star(r); } while (!float32_is_normal(r)); + random_ops[i] = r; break; + } case PREC_DOUBLE: case PREC_FLOAT64: + { + uint64_t r = random_ops[i]; do { r = xorshift64star(r); } while (!float64_is_normal(r)); + random_ops[i] = r; break; + } + case PREC_QUAD: + case PREC_FLOAT128: + { + float128 r = random_quad_ops[i]; + uint64_t hi = r.high; + uint64_t lo = r.low; + do { + hi = xorshift64star(hi); + lo = xorshift64star(lo); + r = make_float128(hi, lo); + } while (!float128_is_normal(r)); + random_quad_ops[i] = r; + break; + } default: g_assert_not_reached(); } - random_ops[i] = r; } } @@ -184,6 +212,13 @@ static void fill_random(union fp *ops, int n_ops, enum precision prec, ops[i].f64 = float64_chs(ops[i].f64); } break; + case PREC_QUAD: + case PREC_FLOAT128: + ops[i].f128 = random_quad_ops[i]; + if (no_neg && float128_is_neg(ops[i].f128)) { + ops[i].f128 = float128_chs(ops[i].f128); + } + break; default: g_assert_not_reached(); } @@ -345,6 +380,41 @@ static void bench(enum precision prec, enum op op, int n_ops, bool no_neg) } } break; + case PREC_FLOAT128: + fill_random(ops, n_ops, prec, no_neg); + t0 = get_clock(); + for (i = 0; i < OPS_PER_ITER; i++) { + float128 a = ops[0].f128; + float128 b = ops[1].f128; + float128 c = ops[2].f128; + + switch (op) { + case OP_ADD: + res.f128 = float128_add(a, b, &soft_status); + break; + case OP_SUB: + res.f128 = float128_sub(a, b, &soft_status); + break; + case OP_MUL: + res.f128 = float128_mul(a, b, &soft_status); + break; + case OP_DIV: + res.f128 = float128_div(a, b, &soft_status); + break; + case OP_FMA: + res.f128 = float128_muladd(a, b, c, 0, &soft_status); + break; + case OP_SQRT: + res.f128 = float128_sqrt(a, &soft_status); + break; + case OP_CMP: + res.u64 = float128_compare_quiet(a, b, &soft_status); + break; + default: + g_assert_not_reached(); + } + } + break; default: g_assert_not_reached(); } @@ -369,7 +439,8 @@ static void bench(enum precision prec, enum op op, int n_ops, bool no_neg) GEN_BENCH(bench_ ## opname ## _float, float, PREC_SINGLE, op, n_ops) \ GEN_BENCH(bench_ ## opname ## _double, double, PREC_DOUBLE, op, n_ops) \ GEN_BENCH(bench_ ## opname ## _float32, float32, PREC_FLOAT32, op, n_ops) \ - GEN_BENCH(bench_ ## opname ## _float64, float64, PREC_FLOAT64, op, n_ops) + GEN_BENCH(bench_ ## opname ## _float64, float64, PREC_FLOAT64, op, n_ops) \ + GEN_BENCH(bench_ ## opname ## _float128, float128, PREC_FLOAT128, op, n_ops) GEN_BENCH_ALL_TYPES(add, OP_ADD, 2) GEN_BENCH_ALL_TYPES(sub, OP_SUB, 2) @@ -383,7 +454,8 @@ GEN_BENCH_ALL_TYPES(cmp, OP_CMP, 2) GEN_BENCH_NO_NEG(bench_ ## name ## _float, float, PREC_SINGLE, op, n) \ GEN_BENCH_NO_NEG(bench_ ## name ## _double, double, PREC_DOUBLE, op, n) \ GEN_BENCH_NO_NEG(bench_ ## name ## _float32, float32, PREC_FLOAT32, op, n) \ - GEN_BENCH_NO_NEG(bench_ ## name ## _float64, float64, PREC_FLOAT64, op, n) + GEN_BENCH_NO_NEG(bench_ ## name ## _float64, float64, PREC_FLOAT64, op, n) \ + GEN_BENCH_NO_NEG(bench_ ## name ## _float128, float128, PREC_FLOAT128, op, n) GEN_BENCH_ALL_TYPES_NO_NEG(sqrt, OP_SQRT, 1) #undef GEN_BENCH_ALL_TYPES_NO_NEG @@ -397,6 +469,7 @@ GEN_BENCH_ALL_TYPES_NO_NEG(sqrt, OP_SQRT, 1) [PREC_DOUBLE] = bench_ ## opname ## _double, \ [PREC_FLOAT32] = bench_ ## opname ## _float32, \ [PREC_FLOAT64] = bench_ ## opname ## _float64, \ + [PREC_FLOAT128] = bench_ ## opname ## _float128, \ } static const bench_func_t bench_funcs[OP_MAX_NR][PREC_MAX_NR] = { @@ -445,7 +518,7 @@ static void usage_complete(int argc, char *argv[]) fprintf(stderr, " -h = show this help message.\n"); fprintf(stderr, " -o = floating point operation (%s). Default: %s\n", op_list, op_names[0]); - fprintf(stderr, " -p = floating point precision (single, double). " + fprintf(stderr, " -p = floating point precision (single, double, quad[soft only]). " "Default: single\n"); fprintf(stderr, " -r = rounding mode (even, zero, down, up, tieaway). " "Default: even\n"); @@ -565,6 +638,8 @@ static void parse_args(int argc, char *argv[]) precision = PREC_SINGLE; } else if (!strcmp(optarg, "double")) { precision = PREC_DOUBLE; + } else if (!strcmp(optarg, "quad")) { + precision = PREC_QUAD; } else { fprintf(stderr, "Unsupported precision '%s'\n", optarg); exit(EXIT_FAILURE); @@ -608,6 +683,9 @@ static void parse_args(int argc, char *argv[]) case PREC_DOUBLE: precision = PREC_FLOAT64; break; + case PREC_QUAD: + precision = PREC_FLOAT128; + break; default: g_assert_not_reached(); } diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c index 5a4cad8c8b..ff131afbde 100644 --- a/tests/fp/fp-test.c +++ b/tests/fp/fp-test.c @@ -717,7 +717,7 @@ static void do_testfloat(int op, int rmode, bool exact) test_abz_f128(true_abz_f128M, subj_abz_f128M); break; case F128_MULADD: - not_implemented(); + test_abcz_f128(slow_f128M_mulAdd, qemu_f128M_mulAdd); break; case F128_SQRT: test_az_f128(slow_f128M_sqrt, qemu_f128M_sqrt); diff --git a/tests/fp/wrap.c.inc b/tests/fp/wrap.c.inc index 0cbd20013e..cb1bb77e4c 100644 --- a/tests/fp/wrap.c.inc +++ b/tests/fp/wrap.c.inc @@ -574,6 +574,18 @@ WRAP_MULADD(qemu_f32_mulAdd, float32_muladd, float32) WRAP_MULADD(qemu_f64_mulAdd, float64_muladd, float64) #undef WRAP_MULADD +static void qemu_f128M_mulAdd(const float128_t *ap, const float128_t *bp, + const float128_t *cp, float128_t *res) +{ + float128 a, b, c, ret; + + a = soft_to_qemu128(*ap); + b = soft_to_qemu128(*bp); + c = soft_to_qemu128(*cp); + ret = float128_muladd(a, b, c, 0, &qsf); + *res = qemu_to_soft128(ret); +} + #define WRAP_CMP16(name, func, retcond) \ static bool name(float16_t a, float16_t b) \ { \ diff --git a/tests/migration/guestperf/comparison.py b/tests/migration/guestperf/comparison.py index ba2edbe546..c03b3f6d7e 100644 --- a/tests/migration/guestperf/comparison.py +++ b/tests/migration/guestperf/comparison.py @@ -121,4 +121,18 @@ COMPARISONS = [ Scenario("compr-xbzrle-cache-50", compression_xbzrle=True, compression_xbzrle_cache=50), ]), + + + # Looking at effect of multifd with + # varying numbers of channels + Comparison("compr-multifd", scenarios = [ + Scenario("compr-multifd-channels-4", + multifd=True, multifd_channels=2), + Scenario("compr-multifd-channels-8", + multifd=True, multifd_channels=8), + Scenario("compr-multifd-channels-32", + multifd=True, multifd_channels=32), + Scenario("compr-multifd-channels-64", + multifd=True, multifd_channels=64), + ]), ] diff --git a/tests/migration/guestperf/engine.py b/tests/migration/guestperf/engine.py index 6b49aed579..208e095794 100644 --- a/tests/migration/guestperf/engine.py +++ b/tests/migration/guestperf/engine.py @@ -188,6 +188,22 @@ class Engine(object): 1024 * 1024 * 1024 / 100 * scenario._compression_xbzrle_cache)) + if scenario._multifd: + resp = src.command("migrate-set-capabilities", + capabilities = [ + { "capability": "multifd", + "state": True } + ]) + resp = src.command("migrate-set-parameters", + multifd_channels=scenario._multifd_channels) + resp = dst.command("migrate-set-capabilities", + capabilities = [ + { "capability": "multifd", + "state": True } + ]) + resp = dst.command("migrate-set-parameters", + multifd_channels=scenario._multifd_channels) + resp = src.command("migrate", uri=connect_uri) post_copy = False diff --git a/tests/migration/guestperf/scenario.py b/tests/migration/guestperf/scenario.py index 28ef36c26d..de70d9b2f5 100644 --- a/tests/migration/guestperf/scenario.py +++ b/tests/migration/guestperf/scenario.py @@ -29,7 +29,8 @@ class Scenario(object): post_copy=False, post_copy_iters=5, auto_converge=False, auto_converge_step=10, compression_mt=False, compression_mt_threads=1, - compression_xbzrle=False, compression_xbzrle_cache=10): + compression_xbzrle=False, compression_xbzrle_cache=10, + multifd=False, multifd_channels=2): self._name = name @@ -56,6 +57,9 @@ class Scenario(object): self._compression_xbzrle = compression_xbzrle self._compression_xbzrle_cache = compression_xbzrle_cache # percentage of guest RAM + self._multifd = multifd + self._multifd_channels = multifd_channels + def serialize(self): return { "name": self._name, @@ -73,6 +77,8 @@ class Scenario(object): "compression_mt_threads": self._compression_mt_threads, "compression_xbzrle": self._compression_xbzrle, "compression_xbzrle_cache": self._compression_xbzrle_cache, + "multifd": self._multifd, + "multifd_channels": self._multifd_channels, } @classmethod @@ -92,4 +98,6 @@ class Scenario(object): data["compression_mt"], data["compression_mt_threads"], data["compression_xbzrle"], - data["compression_xbzrle_cache"]) + data["compression_xbzrle_cache"], + data["multifd"], + data["multifd_channels"]) diff --git a/tests/migration/guestperf/shell.py b/tests/migration/guestperf/shell.py index f838888809..8a809e3dda 100644 --- a/tests/migration/guestperf/shell.py +++ b/tests/migration/guestperf/shell.py @@ -122,6 +122,11 @@ class Shell(BaseShell): parser.add_argument("--compression-xbzrle", dest="compression_xbzrle", default=False, action="store_true") parser.add_argument("--compression-xbzrle-cache", dest="compression_xbzrle_cache", default=10, type=int) + parser.add_argument("--multifd", dest="multifd", default=False, + action="store_true") + parser.add_argument("--multifd-channels", dest="multifd_channels", + default=2, type=int) + def get_scenario(self, args): return Scenario(name="perfreport", downtime=args.downtime, @@ -142,7 +147,10 @@ class Shell(BaseShell): compression_mt_threads=args.compression_mt_threads, compression_xbzrle=args.compression_xbzrle, - compression_xbzrle_cache=args.compression_xbzrle_cache) + compression_xbzrle_cache=args.compression_xbzrle_cache, + + multifd=args.multifd, + multifd_channels=args.multifd_channels) def run(self, argv): args = self._parser.parse_args(argv) diff --git a/tests/qemu-iotests/005 b/tests/qemu-iotests/005 index 40e64a9a8f..ba377543b0 100755 --- a/tests/qemu-iotests/005 +++ b/tests/qemu-iotests/005 @@ -52,11 +52,6 @@ if [ "$IMGFMT" = "vpc" ]; then _notrun "image format $IMGFMT does not support large image sizes" fi -# sheepdog image is limited to 4TB, so we can't test it here -if [ "$IMGPROTO" = "sheepdog" ]; then - _notrun "image protocol $IMGPROTO does not support large image sizes" -fi - # Sanity check: For raw, we require a file system that permits the creation # of a HUGE (but very sparse) file. Check we can create it before continuing. if [ "$IMGFMT" = "raw" ]; then diff --git a/tests/qemu-iotests/025 b/tests/qemu-iotests/025 index da77ed3154..80686a30d5 100755 --- a/tests/qemu-iotests/025 +++ b/tests/qemu-iotests/025 @@ -39,7 +39,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.pattern _supported_fmt raw qcow2 qed luks -_supported_proto file sheepdog rbd nfs fuse +_supported_proto file rbd nfs fuse echo "=== Creating image" echo diff --git a/tests/qemu-iotests/231 b/tests/qemu-iotests/231 index 0f66d0ca36..8e6c6447c1 100755 --- a/tests/qemu-iotests/231 +++ b/tests/qemu-iotests/231 @@ -55,6 +55,10 @@ _filter_conf() $QEMU_IMG info "json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=${BOGUS_CONF}'}" 2>&1 | _filter_conf $QEMU_IMG info "json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'${BOGUS_CONF}'}" 2>&1 | _filter_conf +# Regression test: the qemu-img invocation is expected to fail, but it should +# not seg fault the parser. +$QEMU_IMG create "rbd:rbd/aa\/bb:conf=${BOGUS_CONF}" 1M 2>&1 | _filter_conf + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/231.out b/tests/qemu-iotests/231.out index 579ba11c16..a785a6e859 100644 --- a/tests/qemu-iotests/231.out +++ b/tests/qemu-iotests/231.out @@ -1,9 +1,10 @@ QA output created by 231 -qemu-img: RBD options encoded in the filename as keyvalue pairs is deprecated. Future versions may cease to parse these options in the future. +qemu-img: warning: RBD options encoded in the filename as keyvalue pairs is deprecated unable to get monitor info from DNS SRV with service name: ceph-mon -no monitors specified to connect to. qemu-img: Could not open 'json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=BOGUS_CONF'}': error connecting: No such file or directory unable to get monitor info from DNS SRV with service name: ceph-mon -no monitors specified to connect to. qemu-img: Could not open 'json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'BOGUS_CONF'}': error connecting: No such file or directory +Formatting 'rbd:rbd/aa\/bb:conf=BOGUS_CONF', fmt=raw size=1048576 +unable to get monitor info from DNS SRV with service name: ceph-mon +qemu-img: rbd:rbd/aa\/bb:conf=BOGUS_CONF: error connecting: No such file or directory *** done diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out index e0982831ae..89ed25e506 100644 --- a/tests/qemu-iotests/240.out +++ b/tests/qemu-iotests/240.out @@ -15,7 +15,7 @@ {"return": {}} {"execute": "blockdev-del", "arguments": {"node-name": "hd0"}} {"return": {}} -==Attach two SCSI disks using the same block device and the same iothread== +.==Attach two SCSI disks using the same block device and the same iothread== {"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true, "read-zeroes": true}} {"return": {}} {"execute": "object-add", "arguments": {"id": "iothread0", "qom-type": "iothread"}} @@ -32,7 +32,7 @@ {"return": {}} {"execute": "blockdev-del", "arguments": {"node-name": "hd0"}} {"return": {}} -==Attach two SCSI disks using the same block device but different iothreads== +.==Attach two SCSI disks using the same block device but different iothreads== {"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true, "read-zeroes": true}} {"return": {}} {"execute": "object-add", "arguments": {"id": "iothread0", "qom-type": "iothread"}} @@ -55,7 +55,7 @@ {"return": {}} {"execute": "blockdev-del", "arguments": {"node-name": "hd0"}} {"return": {}} -==Attach a SCSI disks using the same block device as a NBD server== +.==Attach a SCSI disks using the same block device as a NBD server== {"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true, "read-zeroes": true}} {"return": {}} {"execute": "nbd-server-start", "arguments": {"addr": {"data": {"path": "SOCK_DIR/PID-nbd.sock"}, "type": "unix"}}} @@ -68,7 +68,7 @@ {"return": {}} {"execute": "device_add", "arguments": {"drive": "hd0", "driver": "scsi-hd", "id": "scsi-hd0"}} {"return": {}} -.... +. ---------------------------------------------------------------------- Ran 4 tests diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out index 4b33dcaf5c..99c12f4f98 100644 --- a/tests/qemu-iotests/245.out +++ b/tests/qemu-iotests/245.out @@ -1,16 +1,16 @@ -{"execute": "job-finalize", "arguments": {"id": "commit0"}} +..{"execute": "job-finalize", "arguments": {"id": "commit0"}} {"return": {}} {"data": {"id": "commit0", "type": "commit"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} {"data": {"device": "commit0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} -{"execute": "job-finalize", "arguments": {"id": "stream0"}} +...{"execute": "job-finalize", "arguments": {"id": "stream0"}} {"return": {}} {"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} {"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} -{"execute": "job-finalize", "arguments": {"id": "stream0"}} +.{"execute": "job-finalize", "arguments": {"id": "stream0"}} {"return": {}} {"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} {"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} -..................... +............... ---------------------------------------------------------------------- Ran 21 tests diff --git a/tests/qemu-iotests/264 b/tests/qemu-iotests/264 index 4f96825a22..bc431d1a19 100755 --- a/tests/qemu-iotests/264 +++ b/tests/qemu-iotests/264 @@ -95,7 +95,7 @@ class TestNbdReconnect(iotests.QMPTestCase): self.assert_qmp(result, 'return', {}) def cancel_job(self): - result = self.vm.qmp('block-job-cancel', device='drive0') + result = self.vm.qmp('block-job-cancel', device='drive0', force=True) self.assert_qmp(result, 'return', {}) start_t = time.time() diff --git a/tests/qemu-iotests/295.out b/tests/qemu-iotests/295.out index ad34b2ca2c..5ff91f116c 100644 --- a/tests/qemu-iotests/295.out +++ b/tests/qemu-iotests/295.out @@ -4,7 +4,7 @@ {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}} {"return": {}} -{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}} +.{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}} {"return": {}} @@ -13,7 +13,7 @@ Job failed: Invalid password, cannot unlock any keyslot {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job_add_key"}} {"return": {}} -{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}} +.{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job_add_key"}} {"return": {}} @@ -33,7 +33,7 @@ Job failed: All the active keyslots match the (old) password that was given and {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}} {"return": {}} -... +. ---------------------------------------------------------------------- Ran 3 tests diff --git a/tests/qemu-iotests/296.out b/tests/qemu-iotests/296.out index cb2859a15c..6c69735604 100644 --- a/tests/qemu-iotests/296.out +++ b/tests/qemu-iotests/296.out @@ -13,7 +13,7 @@ Job failed: Failed to get shared "consistent read" lock qemu-img: Failed to get shared "consistent read" lock Is another process using the image [TEST_DIR/test.img]? -Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10 +.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10 Job failed: Block node is read-only {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -26,15 +26,15 @@ Job failed: Failed to get shared "consistent read" lock {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10 +.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10 {"return": {}} {"error": {"class": "GenericError", "desc": "Failed to get \"write\" lock"}} -Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10 +.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10 {"return": {}} {"return": {}} -.... +. ---------------------------------------------------------------------- Ran 4 tests diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check index d1c87ceaf1..2dd529eb75 100755 --- a/tests/qemu-iotests/check +++ b/tests/qemu-iotests/check @@ -19,6 +19,9 @@ import os import sys import argparse +import shutil +from pathlib import Path + from findtests import TestFinder from testenv import TestEnv from testrunner import TestRunner @@ -65,8 +68,7 @@ def make_argparser() -> argparse.ArgumentParser: mg.add_argument('-' + fmt, dest='imgfmt', action='store_const', const=fmt, help=f'test {fmt}') - protocol_list = ['file', 'rbd', 'sheepdog', 'nbd', 'ssh', 'nfs', - 'fuse'] + protocol_list = ['file', 'rbd', 'nbd', 'ssh', 'nfs', 'fuse'] g_prt = p.add_argument_group( ' image protocol options', 'The following options set the IMGPROTO environment variable. ' @@ -101,7 +103,7 @@ def make_argparser() -> argparse.ArgumentParser: 'rerun failed ./check command, starting from the ' 'middle of the process.') g_sel.add_argument('tests', metavar='TEST_FILES', nargs='*', - help='tests to run') + help='tests to run, or "--" followed by a command') return p @@ -114,6 +116,20 @@ if __name__ == '__main__': imgopts=args.imgopts, misalign=args.misalign, debug=args.debug, valgrind=args.valgrind) + if len(sys.argv) > 1 and sys.argv[-len(args.tests)-1] == '--': + if not args.tests: + sys.exit("missing command after '--'") + cmd = args.tests + env.print_env() + exec_pathstr = shutil.which(cmd[0]) + if exec_pathstr is None: + sys.exit('command not found: ' + cmd[0]) + exec_path = Path(exec_pathstr).resolve() + cmd[0] = str(exec_path) + full_env = env.prepare_subprocess(cmd) + os.chdir(exec_path.parent) + os.execve(cmd[0], cmd, full_env) + testfinder = TestFinder(test_dir=env.source_iotests) groups = args.groups.split(',') if args.groups else None diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index 7f49c9716d..cbbf6d7c7f 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -641,10 +641,6 @@ _cleanup_test_img() rbd --no-progress rm "$TEST_DIR/t.$IMGFMT" > /dev/null ;; - sheepdog) - collie vdi delete "$TEST_DIR/t.$IMGFMT" - ;; - esac } diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 5af0182895..777fa2ec0e 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -20,7 +20,6 @@ import atexit import bz2 from collections import OrderedDict import faulthandler -import io import json import logging import os @@ -32,7 +31,7 @@ import subprocess import sys import time from typing import (Any, Callable, Dict, Iterable, - List, Optional, Sequence, Tuple, TypeVar) + List, Optional, Sequence, TextIO, Tuple, Type, TypeVar) import unittest from contextlib import contextmanager @@ -113,15 +112,14 @@ def qemu_tool_pipe_and_status(tool: str, args: Sequence[str], Run a tool and return both its output and its exit code """ stderr = subprocess.STDOUT if connect_stderr else None - subp = subprocess.Popen(args, - stdout=subprocess.PIPE, - stderr=stderr, - universal_newlines=True) - output = subp.communicate()[0] - if subp.returncode < 0: - cmd = ' '.join(args) - sys.stderr.write(f'{tool} received signal {-subp.returncode}: {cmd}\n') - return (output, subp.returncode) + with subprocess.Popen(args, stdout=subprocess.PIPE, + stderr=stderr, universal_newlines=True) as subp: + output = subp.communicate()[0] + if subp.returncode < 0: + cmd = ' '.join(args) + sys.stderr.write(f'{tool} received signal \ + {-subp.returncode}: {cmd}\n') + return (output, subp.returncode) def qemu_img_pipe_and_status(*args: str) -> Tuple[str, int]: """ @@ -237,6 +235,9 @@ def qemu_io_silent_check(*args): class QemuIoInteractive: def __init__(self, *args): self.args = qemu_io_args_no_fmt + list(args) + # We need to keep the Popen objext around, and not + # close it immediately. Therefore, disable the pylint check: + # pylint: disable=consider-using-with self._p = subprocess.Popen(self.args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, @@ -310,22 +311,22 @@ def qemu_nbd_popen(*args): cmd.extend(args) log('Start NBD server') - p = subprocess.Popen(cmd) - try: - while not os.path.exists(pid_file): - if p.poll() is not None: - raise RuntimeError( - "qemu-nbd terminated with exit code {}: {}" - .format(p.returncode, ' '.join(cmd))) - - time.sleep(0.01) - yield - finally: - if os.path.exists(pid_file): - os.remove(pid_file) - log('Kill NBD server') - p.kill() - p.wait() + with subprocess.Popen(cmd) as p: + try: + while not os.path.exists(pid_file): + if p.poll() is not None: + raise RuntimeError( + "qemu-nbd terminated with exit code {}: {}" + .format(p.returncode, ' '.join(cmd))) + + time.sleep(0.01) + yield + finally: + if os.path.exists(pid_file): + os.remove(pid_file) + log('Kill NBD server') + p.kill() + p.wait() def compare_images(img1, img2, fmt1=imgfmt, fmt2=imgfmt): '''Return True if two image files are identical''' @@ -334,13 +335,12 @@ def compare_images(img1, img2, fmt1=imgfmt, fmt2=imgfmt): def create_image(name, size): '''Create a fully-allocated raw image with sector markers''' - file = open(name, 'wb') - i = 0 - while i < size: - sector = struct.pack('>l504xl', i // 512, i // 512) - file.write(sector) - i = i + 512 - file.close() + with open(name, 'wb') as file: + i = 0 + while i < size: + sector = struct.pack('>l504xl', i // 512, i // 512) + file.write(sector) + i = i + 512 def image_size(img): '''Return image's virtual size''' @@ -1271,37 +1271,54 @@ def skip_if_user_is_root(func): return func(*args, **kwargs) return func_wrapper -def execute_unittest(debug=False): +# We need to filter out the time taken from the output so that +# qemu-iotest can reliably diff the results against master output, +# and hide skipped tests from the reference output. + +class ReproducibleTestResult(unittest.TextTestResult): + def addSkip(self, test, reason): + # Same as TextTestResult, but print dot instead of "s" + unittest.TestResult.addSkip(self, test, reason) + if self.showAll: + self.stream.writeln("skipped {0!r}".format(reason)) + elif self.dots: + self.stream.write(".") + self.stream.flush() + +class ReproducibleStreamWrapper: + def __init__(self, stream: TextIO): + self.stream = stream + + def __getattr__(self, attr): + if attr in ('stream', '__getstate__'): + raise AttributeError(attr) + return getattr(self.stream, attr) + + def write(self, arg=None): + arg = re.sub(r'Ran (\d+) tests? in [\d.]+s', r'Ran \1 tests', arg) + arg = re.sub(r' \(skipped=\d+\)', r'', arg) + self.stream.write(arg) + +class ReproducibleTestRunner(unittest.TextTestRunner): + def __init__(self, stream: Optional[TextIO] = None, + resultclass: Type[unittest.TestResult] = ReproducibleTestResult, + **kwargs: Any) -> None: + rstream = ReproducibleStreamWrapper(stream or sys.stdout) + super().__init__(stream=rstream, # type: ignore + descriptions=True, + resultclass=resultclass, + **kwargs) + +def execute_unittest(argv: List[str], debug: bool = False) -> None: """Executes unittests within the calling module.""" - verbosity = 2 if debug else 1 - - if debug: - output = sys.stdout - else: - # We need to filter out the time taken from the output so that - # qemu-iotest can reliably diff the results against master output. - output = io.StringIO() - - runner = unittest.TextTestRunner(stream=output, descriptions=True, - verbosity=verbosity) - try: - # unittest.main() will use sys.exit(); so expect a SystemExit - # exception - unittest.main(testRunner=runner) - finally: - # We need to filter out the time taken from the output so that - # qemu-iotest can reliably diff the results against master output. - if not debug: - out = output.getvalue() - out = re.sub(r'Ran (\d+) tests? in [\d.]+s', r'Ran \1 tests', out) - - # Hide skipped tests from the reference output - out = re.sub(r'OK \(skipped=\d+\)', 'OK', out) - out_first_line, out_rest = out.split('\n', 1) - out = out_first_line.replace('s', '.') + '\n' + out_rest - - sys.stderr.write(out) + # Some tests have warnings, especially ResourceWarnings for unclosed + # files and sockets. Ignore them for now to ensure reproducibility of + # the test output. + unittest.main(argv=argv, + testRunner=ReproducibleTestRunner, + verbosity=2 if debug else 1, + warnings=None if sys.warnoptions else 'ignore') def execute_setup_common(supported_fmts: Sequence[str] = (), supported_platforms: Sequence[str] = (), @@ -1338,7 +1355,7 @@ def execute_test(*args, test_function=None, **kwargs): debug = execute_setup_common(*args, **kwargs) if not test_function: - execute_unittest(debug) + execute_unittest(sys.argv, debug) else: test_function() diff --git a/tests/qemu-iotests/pylintrc b/tests/qemu-iotests/pylintrc index 7a6c0a9474..f2c0b522ac 100644 --- a/tests/qemu-iotests/pylintrc +++ b/tests/qemu-iotests/pylintrc @@ -19,6 +19,9 @@ disable=invalid-name, too-many-public-methods, # pylint warns about Optional[] etc. as unsubscriptable in 3.9 unsubscriptable-object, + # Sometimes we need to disable a newly introduced pylint warning. + # Doing so should not produce a warning in older versions of pylint. + bad-option-value, # These are temporary, and should be removed: missing-docstring, too-many-return-statements, diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py index 6d27712617..0c3fe75636 100644 --- a/tests/qemu-iotests/testenv.py +++ b/tests/qemu-iotests/testenv.py @@ -25,7 +25,7 @@ import collections import random import subprocess import glob -from typing import Dict, Any, Optional, ContextManager +from typing import List, Dict, Any, Optional, ContextManager def isxfile(path: str) -> bool: @@ -74,6 +74,21 @@ class TestEnv(ContextManager['TestEnv']): 'CACHEMODE_IS_DEFAULT', 'IMGFMT_GENERIC', 'IMGOPTSSYNTAX', 'IMGKEYSECRET', 'QEMU_DEFAULT_MACHINE', 'MALLOC_PERTURB_'] + def prepare_subprocess(self, args: List[str]) -> Dict[str, str]: + if self.debug: + args.append('-d') + + with open(args[0], encoding="utf-8") as f: + try: + if f.readline().rstrip() == '#!/usr/bin/env python3': + args.insert(0, self.python) + except UnicodeDecodeError: # binary test? for future. + pass + + os_env = os.environ.copy() + os_env.update(self.get_env()) + return os_env + def get_env(self) -> Dict[str, str]: env = {} for v in self.env_variables: @@ -105,7 +120,7 @@ class TestEnv(ContextManager['TestEnv']): try: self.sock_dir = os.environ['SOCK_DIR'] self.tmp_sock_dir = False - Path(self.test_dir).mkdir(parents=True, exist_ok=True) + Path(self.sock_dir).mkdir(parents=True, exist_ok=True) except KeyError: self.sock_dir = tempfile.mkdtemp() self.tmp_sock_dir = True @@ -269,7 +284,8 @@ IMGPROTO -- {IMGPROTO} PLATFORM -- {platform} TEST_DIR -- {TEST_DIR} SOCK_DIR -- {SOCK_DIR} -SOCKET_SCM_HELPER -- {SOCKET_SCM_HELPER}""" +SOCKET_SCM_HELPER -- {SOCKET_SCM_HELPER} +""" args = collections.defaultdict(str, self.get_env()) diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py index 1fc61fcaa3..4a6ec421ed 100644 --- a/tests/qemu-iotests/testrunner.py +++ b/tests/qemu-iotests/testrunner.py @@ -129,7 +129,6 @@ class TestRunner(ContextManager['TestRunner']): def __init__(self, env: TestEnv, makecheck: bool = False, color: str = 'auto') -> None: self.env = env - self.test_run_env = self.env.get_env() self.makecheck = makecheck self.last_elapsed = LastElapsedTime('.last-elapsed-cache', env) @@ -243,32 +242,21 @@ class TestRunner(ContextManager['TestRunner']): silent_unlink(p) args = [str(f_test.resolve())] - if self.env.debug: - args.append('-d') - - with f_test.open(encoding="utf-8") as f: - try: - if f.readline().rstrip() == '#!/usr/bin/env python3': - args.insert(0, self.env.python) - except UnicodeDecodeError: # binary test? for future. - pass - - env = os.environ.copy() - env.update(self.test_run_env) + env = self.env.prepare_subprocess(args) t0 = time.time() with f_bad.open('w', encoding="utf-8") as f: - proc = subprocess.Popen(args, cwd=str(f_test.parent), env=env, - stdout=f, stderr=subprocess.STDOUT) - try: - proc.wait() - except KeyboardInterrupt: - proc.terminate() - proc.wait() - return TestResult(status='not run', - description='Interrupted by user', - interrupted=True) - ret = proc.returncode + with subprocess.Popen(args, cwd=str(f_test.parent), env=env, + stdout=f, stderr=subprocess.STDOUT) as proc: + try: + proc.wait() + except KeyboardInterrupt: + proc.terminate() + proc.wait() + return TestResult(status='not run', + description='Interrupted by user', + interrupted=True) + ret = proc.returncode elapsed = round(time.time() - t0, 1) @@ -328,7 +316,6 @@ class TestRunner(ContextManager['TestRunner']): if not self.makecheck: self.env.print_env() - print() test_field_width = max(len(os.path.basename(t)) for t in tests) + 2 diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c index 5e1954852e..8073ccc205 100644 --- a/tests/qtest/ahci-test.c +++ b/tests/qtest/ahci-test.c @@ -1491,14 +1491,14 @@ static void ahci_test_cdrom(int nsectors, bool dma, uint8_t cmd, char *iso; int fd; AHCIOpts opts = { - .size = (ATAPI_SECTOR_SIZE * nsectors), + .size = ((uint64_t)ATAPI_SECTOR_SIZE * nsectors), .atapi = true, .atapi_dma = dma, .post_cb = ahci_cb_cmp_buff, .set_bcl = override_bcl, .bcl = bcl, }; - uint64_t iso_size = ATAPI_SECTOR_SIZE * (nsectors + 1); + uint64_t iso_size = (uint64_t)ATAPI_SECTOR_SIZE * (nsectors + 1); /* Prepare ISO and fill 'tx' buffer */ fd = prepare_iso(iso_size, &tx, &iso); diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c index d74509b1c5..d40adddafa 100644 --- a/tests/qtest/boot-serial-test.c +++ b/tests/qtest/boot-serial-test.c @@ -61,13 +61,6 @@ static const uint8_t kernel_plml605[] = { 0xfc, 0xff, 0x00, 0xb8 /* bri -4 loop */ }; -static const uint8_t bios_moxiesim[] = { - 0x20, 0x10, 0x00, 0x00, 0x03, 0xf8, /* ldi.s r1,0x3f8 */ - 0x1b, 0x20, 0x00, 0x00, 0x00, 0x54, /* ldi.b r2,'T' */ - 0x1e, 0x12, /* st.b r1,r2 */ - 0x1a, 0x00, 0x00, 0x00, 0x10, 0x00 /* jmpa 0x1000 */ -}; - static const uint8_t bios_raspi2[] = { 0x08, 0x30, 0x9f, 0xe5, /* ldr r3,[pc,#8] Get base */ 0x54, 0x20, 0xa0, 0xe3, /* mov r2,#'T' */ @@ -145,7 +138,6 @@ static testdef_t tests[] = { sizeof(kernel_pls3adsp1800), kernel_pls3adsp1800 }, { "microblazeel", "petalogix-ml605", "", "TT", sizeof(kernel_plml605), kernel_plml605 }, - { "moxie", "moxiesim", "", "TT", sizeof(bios_moxiesim), 0, bios_moxiesim }, { "arm", "raspi2", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 }, /* For hppa, force bios to output to serial by disabling graphics. */ { "hppa", "hppa", "-vga none", "SeaBIOS wants SYSTEM HALT" }, diff --git a/tests/qtest/ipmi-bt-test.c b/tests/qtest/ipmi-bt-test.c index a42207d416..8492f02a9c 100644 --- a/tests/qtest/ipmi-bt-test.c +++ b/tests/qtest/ipmi-bt-test.c @@ -98,7 +98,8 @@ static void bt_wait_b_busy(void) { unsigned int count = 1000; while (IPMI_BT_CTLREG_GET_B_BUSY() != 0) { - g_assert(--count != 0); + --count; + g_assert(count != 0); usleep(100); } } @@ -107,7 +108,8 @@ static void bt_wait_b2h_atn(void) { unsigned int count = 1000; while (IPMI_BT_CTLREG_GET_B2H_ATN() == 0) { - g_assert(--count != 0); + --count; + g_assert(count != 0); usleep(100); } } diff --git a/tests/qtest/ipmi-kcs-test.c b/tests/qtest/ipmi-kcs-test.c index fc0a918c8d..afc24dd3e4 100644 --- a/tests/qtest/ipmi-kcs-test.c +++ b/tests/qtest/ipmi-kcs-test.c @@ -73,7 +73,8 @@ static void kcs_wait_ibf(void) { unsigned int count = 1000; while (IPMI_KCS_CMDREG_GET_IBF() != 0) { - g_assert(--count != 0); + --count; + g_assert(count != 0); } } diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build index 1cddf5bdaa..1f5c8f1053 100644 --- a/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build @@ -32,6 +32,7 @@ libqos_srcs = files('../libqtest.c', 'virtio-9p.c', 'virtio-balloon.c', 'virtio-blk.c', + 'vhost-user-blk.c', 'virtio-mmio.c', 'virtio-net.c', 'virtio-pci.c', diff --git a/tests/qtest/libqos/qgraph.c b/tests/qtest/libqos/qgraph.c index b3b1a31f81..d1dc491930 100644 --- a/tests/qtest/libqos/qgraph.c +++ b/tests/qtest/libqos/qgraph.c @@ -844,7 +844,7 @@ void qos_dump_graph(void) } qos_printf_literal("type=%d cmd_line='%s' [%s]\n", node->type, node->command_line, - node->available ? "available" : "UNAVAILBLE" + node->available ? "available" : "UNAVAILABLE" ); } g_list_free(keys); diff --git a/tests/qtest/libqos/vhost-user-blk.c b/tests/qtest/libqos/vhost-user-blk.c new file mode 100644 index 0000000000..568c3426ed --- /dev/null +++ b/tests/qtest/libqos/vhost-user-blk.c @@ -0,0 +1,130 @@ +/* + * libqos driver framework + * + * Based on tests/qtest/libqos/virtio-blk.c + * + * Copyright (c) 2020 Coiby Xu <coiby.xu@gmail.com> + * + * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. + * + * 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 "libqtest.h" +#include "qemu/module.h" +#include "standard-headers/linux/virtio_blk.h" +#include "vhost-user-blk.h" + +#define PCI_SLOT 0x04 +#define PCI_FN 0x00 + +/* virtio-blk-device */ +static void *qvhost_user_blk_get_driver(QVhostUserBlk *v_blk, + const char *interface) +{ + if (!g_strcmp0(interface, "vhost-user-blk")) { + return v_blk; + } + if (!g_strcmp0(interface, "virtio")) { + return v_blk->vdev; + } + + fprintf(stderr, "%s not present in vhost-user-blk-device\n", interface); + g_assert_not_reached(); +} + +static void *qvhost_user_blk_device_get_driver(void *object, + const char *interface) +{ + QVhostUserBlkDevice *v_blk = object; + return qvhost_user_blk_get_driver(&v_blk->blk, interface); +} + +static void *vhost_user_blk_device_create(void *virtio_dev, + QGuestAllocator *t_alloc, + void *addr) +{ + QVhostUserBlkDevice *vhost_user_blk = g_new0(QVhostUserBlkDevice, 1); + QVhostUserBlk *interface = &vhost_user_blk->blk; + + interface->vdev = virtio_dev; + + vhost_user_blk->obj.get_driver = qvhost_user_blk_device_get_driver; + + return &vhost_user_blk->obj; +} + +/* virtio-blk-pci */ +static void *qvhost_user_blk_pci_get_driver(void *object, const char *interface) +{ + QVhostUserBlkPCI *v_blk = object; + if (!g_strcmp0(interface, "pci-device")) { + return v_blk->pci_vdev.pdev; + } + return qvhost_user_blk_get_driver(&v_blk->blk, interface); +} + +static void *vhost_user_blk_pci_create(void *pci_bus, QGuestAllocator *t_alloc, + void *addr) +{ + QVhostUserBlkPCI *vhost_user_blk = g_new0(QVhostUserBlkPCI, 1); + QVhostUserBlk *interface = &vhost_user_blk->blk; + QOSGraphObject *obj = &vhost_user_blk->pci_vdev.obj; + + virtio_pci_init(&vhost_user_blk->pci_vdev, pci_bus, addr); + interface->vdev = &vhost_user_blk->pci_vdev.vdev; + + g_assert_cmphex(interface->vdev->device_type, ==, VIRTIO_ID_BLOCK); + + obj->get_driver = qvhost_user_blk_pci_get_driver; + + return obj; +} + +static void vhost_user_blk_register_nodes(void) +{ + /* + * FIXME: every test using these two nodes needs to setup a + * -drive,id=drive0 otherwise QEMU is not going to start. + * Therefore, we do not include "produces" edge for virtio + * and pci-device yet. + */ + + char *arg = g_strdup_printf("id=drv0,chardev=char1,addr=%x.%x", + PCI_SLOT, PCI_FN); + + QPCIAddress addr = { + .devfn = QPCI_DEVFN(PCI_SLOT, PCI_FN), + }; + + QOSGraphEdgeOptions opts = { }; + + /* virtio-blk-device */ + /** opts.extra_device_opts = "drive=drive0"; */ + qos_node_create_driver("vhost-user-blk-device", + vhost_user_blk_device_create); + qos_node_consumes("vhost-user-blk-device", "virtio-bus", &opts); + qos_node_produces("vhost-user-blk-device", "vhost-user-blk"); + + /* virtio-blk-pci */ + opts.extra_device_opts = arg; + add_qpci_address(&opts, &addr); + qos_node_create_driver("vhost-user-blk-pci", vhost_user_blk_pci_create); + qos_node_consumes("vhost-user-blk-pci", "pci-bus", &opts); + qos_node_produces("vhost-user-blk-pci", "vhost-user-blk"); + + g_free(arg); +} + +libqos_init(vhost_user_blk_register_nodes); diff --git a/tests/qtest/libqos/vhost-user-blk.h b/tests/qtest/libqos/vhost-user-blk.h new file mode 100644 index 0000000000..2a03456a45 --- /dev/null +++ b/tests/qtest/libqos/vhost-user-blk.h @@ -0,0 +1,48 @@ +/* + * libqos driver framework + * + * Based on tests/qtest/libqos/virtio-blk.c + * + * Copyright (c) 2020 Coiby Xu <coiby.xu@gmail.com> + * + * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2 as published by the Free Software Foundation. + * + * 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/> + */ + +#ifndef TESTS_LIBQOS_VHOST_USER_BLK_H +#define TESTS_LIBQOS_VHOST_USER_BLK_H + +#include "qgraph.h" +#include "virtio.h" +#include "virtio-pci.h" + +typedef struct QVhostUserBlk QVhostUserBlk; +typedef struct QVhostUserBlkPCI QVhostUserBlkPCI; +typedef struct QVhostUserBlkDevice QVhostUserBlkDevice; + +struct QVhostUserBlk { + QVirtioDevice *vdev; +}; + +struct QVhostUserBlkPCI { + QVirtioPCIDevice pci_vdev; + QVhostUserBlk blk; +}; + +struct QVhostUserBlkDevice { + QOSGraphObject obj; + QVhostUserBlk blk; +}; + +#endif diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index 71e359efcd..825b13a44c 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -907,7 +907,14 @@ const char *qtest_get_arch(void) if (!end) { fprintf(stderr, "Can't determine architecture from binary name.\n"); - abort(); + exit(1); + } + + if (!strstr(qemu, "-system-")) { + fprintf(stderr, "QTEST_QEMU_BINARY must end with *-system-<arch> " + "where 'arch' is the target\narchitecture (x86_64, aarch64, " + "etc).\n"); + exit(1); } return end + 1; diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-test.c index aab06b9fc2..138101b46a 100644 --- a/tests/qtest/machine-none-test.c +++ b/tests/qtest/machine-none-test.c @@ -32,7 +32,6 @@ static struct arch2cpu cpus_map[] = { { "i386", "qemu32,apic-id=0" }, { "alpha", "ev67" }, { "cris", "crisv32" }, - { "lm32", "lm32-full" }, { "m68k", "m5206" }, { "microblaze", "any" }, { "microblazeel", "any" }, @@ -40,7 +39,6 @@ static struct arch2cpu cpus_map[] = { { "mipsel", "I7200" }, { "mips64", "20Kc" }, { "mips64el", "I6500" }, - { "moxie", "MoxieLite" }, { "nios2", "FIXME" }, { "or1k", "or1200" }, { "ppc", "604" }, @@ -51,7 +49,6 @@ static struct arch2cpu cpus_map[] = { { "sparc", "LEON2" }, { "sparc64", "Fujitsu Sparc64" }, { "tricore", "tc1796" }, - { "unicore32", "UniCore-II" }, { "xtensa", "dc233c" }, { "xtensaeb", "fsf" }, { "hppa", "hppa" }, diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 966bc93efa..c3a223a83d 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -126,8 +126,6 @@ qtests_mips64el = \ (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \ (config_all_devices.has_key('CONFIG_VGA') ? ['display-vga-test'] : []) -qtests_moxie = [ 'boot-serial-test' ] - qtests_ppc = \ (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \ (config_all_devices.has_key('CONFIG_M48T59') ? ['m48t59-test'] : []) + \ @@ -233,6 +231,9 @@ if have_virtfs qos_test_ss.add(files('virtio-9p-test.c')) endif qos_test_ss.add(when: 'CONFIG_VHOST_USER', if_true: files('vhost-user-test.c')) +if have_tools and have_vhost_user_blk_server + qos_test_ss.add(files('vhost-user-blk-test.c')) +endif tpmemu_files = ['tpm-emu.c', 'tpm-util.c', 'tpm-tests.c'] @@ -271,6 +272,7 @@ foreach dir : target_dirs endif qtest_env.set('G_TEST_DBUS_DAEMON', meson.source_root() / 'tests/dbus-vmstate-daemon.sh') qtest_env.set('QTEST_QEMU_BINARY', './qemu-system-' + target_base) + qtest_env.set('QTEST_QEMU_STORAGE_DAEMON_BINARY', './storage-daemon/qemu-storage-daemon') foreach test : target_qtests # Executables are shared across targets, declare them only the first time we diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index 3a711bb492..2b028df687 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -110,13 +110,12 @@ static void init_bootfile(const char *bootpath, void *content, size_t len) */ static void wait_for_serial(const char *side) { - char *serialpath = g_strdup_printf("%s/%s", tmpfs, side); + g_autofree char *serialpath = g_strdup_printf("%s/%s", tmpfs, side); FILE *serialfile = fopen(serialpath, "r"); const char *arch = qtest_get_arch(); int started = (strcmp(side, "src_serial") == 0 && strcmp(arch, "ppc64") == 0) ? 0 : 1; - g_free(serialpath); do { int readvalue = fgetc(serialfile); @@ -274,10 +273,9 @@ static void check_guests_ram(QTestState *who) static void cleanup(const char *filename) { - char *path = g_strdup_printf("%s/%s", tmpfs, filename); + g_autofree char *path = g_strdup_printf("%s/%s", tmpfs, filename); unlink(path); - g_free(path); } static char *SocketAddress_to_str(SocketAddress *addr) @@ -374,11 +372,8 @@ static char *migrate_get_parameter_str(QTestState *who, static void migrate_check_parameter_str(QTestState *who, const char *parameter, const char *value) { - char *result; - - result = migrate_get_parameter_str(who, parameter); + g_autofree char *result = migrate_get_parameter_str(who, parameter); g_assert_cmpstr(result, ==, value); - g_free(result); } static void migrate_set_parameter_str(QTestState *who, const char *parameter, @@ -495,12 +490,14 @@ static void migrate_start_destroy(MigrateStart *args) static int test_migrate_start(QTestState **from, QTestState **to, const char *uri, MigrateStart *args) { - gchar *arch_source, *arch_target; - gchar *cmd_source, *cmd_target; + g_autofree gchar *arch_source = NULL; + g_autofree gchar *arch_target = NULL; + g_autofree gchar *cmd_source = NULL; + g_autofree gchar *cmd_target = NULL; const gchar *ignore_stderr; - char *bootpath = NULL; - char *shmem_opts; - char *shmem_path; + g_autofree char *bootpath = NULL; + g_autofree char *shmem_opts = NULL; + g_autofree char *shmem_path = NULL; const char *arch = qtest_get_arch(); const char *machine_opts = NULL; const char *memory_size; @@ -559,8 +556,6 @@ static int test_migrate_start(QTestState **from, QTestState **to, g_assert_not_reached(); } - g_free(bootpath); - if (!getenv("QTEST_LOG") && args->hide_stderr) { ignore_stderr = "2>/dev/null"; } else { @@ -588,11 +583,9 @@ static int test_migrate_start(QTestState **from, QTestState **to, memory_size, tmpfs, arch_source, shmem_opts, args->opts_source, ignore_stderr); - g_free(arch_source); if (!args->only_target) { *from = qtest_init(cmd_source); } - g_free(cmd_source); cmd_target = g_strdup_printf("-accel kvm -accel tcg%s%s " "-name target,debug-threads=on " @@ -605,18 +598,14 @@ static int test_migrate_start(QTestState **from, QTestState **to, memory_size, tmpfs, uri, arch_target, shmem_opts, args->opts_target, ignore_stderr); - g_free(arch_target); *to = qtest_init(cmd_target); - g_free(cmd_target); - g_free(shmem_opts); /* * Remove shmem file immediately to avoid memory leak in test failed case. * It's valid becase QEMU has already opened this file */ if (args->use_shmem) { unlink(shmem_path); - g_free(shmem_path); } out: @@ -662,7 +651,7 @@ static int migrate_postcopy_prepare(QTestState **from_ptr, QTestState **to_ptr, MigrateStart *args) { - char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); + g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); QTestState *from, *to; if (test_migrate_start(&from, &to, uri, args)) { @@ -684,7 +673,6 @@ static int migrate_postcopy_prepare(QTestState **from_ptr, wait_for_serial("src_serial"); migrate_qmp(from, uri, "{}"); - g_free(uri); wait_for_migration_pass(from); @@ -724,7 +712,7 @@ static void test_postcopy_recovery(void) { MigrateStart *args = migrate_start_new(); QTestState *from, *to; - char *uri; + g_autofree char *uri = NULL; args->hide_stderr = true; @@ -775,7 +763,6 @@ static void test_postcopy_recovery(void) (const char * []) { "failed", "active", "completed", NULL }); migrate_qmp(from, uri, "{'resume': true}"); - g_free(uri); /* Restore the postcopy bandwidth to unlimited */ migrate_set_parameter_int(from, "max-postcopy-bandwidth", 0); @@ -800,7 +787,7 @@ static void test_baddest(void) static void test_precopy_unix(void) { - char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); + g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); MigrateStart *args = migrate_start_new(); QTestState *from, *to; @@ -836,14 +823,13 @@ static void test_precopy_unix(void) wait_for_migration_complete(from); test_migrate_end(from, to, true); - g_free(uri); } #if 0 /* Currently upset on aarch64 TCG */ static void test_ignore_shared(void) { - char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); + g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); QTestState *from, *to; if (test_migrate_start(&from, &to, uri, false, true, NULL, NULL)) { @@ -873,7 +859,6 @@ static void test_ignore_shared(void) g_assert_cmpint(read_ram_property_int(from, "transferred"), <, 1024 * 1024); test_migrate_end(from, to, true); - g_free(uri); } #endif @@ -898,8 +883,8 @@ static void test_xbzrle(const char *uri) migrate_set_parameter_int(from, "xbzrle-cache-size", 33554432); - migrate_set_capability(from, "xbzrle", "true"); - migrate_set_capability(to, "xbzrle", "true"); + migrate_set_capability(from, "xbzrle", true); + migrate_set_capability(to, "xbzrle", true); /* Wait for the first serial output from the source */ wait_for_serial("src_serial"); @@ -925,16 +910,15 @@ static void test_xbzrle(const char *uri) static void test_xbzrle_unix(void) { - char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); + g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); test_xbzrle(uri); - g_free(uri); } static void test_precopy_tcp(void) { MigrateStart *args = migrate_start_new(); - char *uri; + g_autofree char *uri = NULL; QTestState *from, *to; if (test_migrate_start(&from, &to, "tcp:127.0.0.1:0", args)) { @@ -971,7 +955,6 @@ static void test_precopy_tcp(void) wait_for_migration_complete(from); test_migrate_end(from, to, true); - g_free(uri); } static void test_migrate_fd_proto(void) @@ -1060,7 +1043,7 @@ static void test_migrate_fd_proto(void) static void do_test_validate_uuid(MigrateStart *args, bool should_fail) { - char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); + g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); QTestState *from, *to; if (test_migrate_start(&from, &to, uri, args)) { @@ -1088,7 +1071,6 @@ static void do_test_validate_uuid(MigrateStart *args, bool should_fail) } test_migrate_end(from, to, false); - g_free(uri); } static void test_validate_uuid(void) @@ -1136,7 +1118,7 @@ static void test_validate_uuid_dst_not_set(void) static void test_migrate_auto_converge(void) { - char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); + g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); MigrateStart *args = migrate_start_new(); QTestState *from, *to; int64_t remaining, percentage; @@ -1214,7 +1196,6 @@ static void test_migrate_auto_converge(void) wait_for_serial("dest_serial"); wait_for_migration_complete(from); - g_free(uri); test_migrate_end(from, to, true); } @@ -1224,7 +1205,7 @@ static void test_multifd_tcp(const char *method) MigrateStart *args = migrate_start_new(); QTestState *from, *to; QDict *rsp; - char *uri; + g_autofree char *uri = NULL; if (test_migrate_start(&from, &to, "defer", args)) { return; @@ -1246,8 +1227,8 @@ static void test_multifd_tcp(const char *method) migrate_set_parameter_str(from, "multifd-compression", method); migrate_set_parameter_str(to, "multifd-compression", method); - migrate_set_capability(from, "multifd", "true"); - migrate_set_capability(to, "multifd", "true"); + migrate_set_capability(from, "multifd", true); + migrate_set_capability(to, "multifd", true); /* Start incoming migration from the 1st socket */ rsp = wait_command(to, "{ 'execute': 'migrate-incoming'," @@ -1273,7 +1254,6 @@ static void test_multifd_tcp(const char *method) wait_for_serial("dest_serial"); wait_for_migration_complete(from); test_migrate_end(from, to, true); - g_free(uri); } static void test_multifd_tcp_none(void) @@ -1309,7 +1289,7 @@ static void test_multifd_tcp_cancel(void) MigrateStart *args = migrate_start_new(); QTestState *from, *to, *to2; QDict *rsp; - char *uri; + g_autofree char *uri = NULL; args->hide_stderr = true; @@ -1330,8 +1310,8 @@ static void test_multifd_tcp_cancel(void) migrate_set_parameter_int(from, "multifd-channels", 16); migrate_set_parameter_int(to, "multifd-channels", 16); - migrate_set_capability(from, "multifd", "true"); - migrate_set_capability(to, "multifd", "true"); + migrate_set_capability(from, "multifd", true); + migrate_set_capability(to, "multifd", true); /* Start incoming migration from the 1st socket */ rsp = wait_command(to, "{ 'execute': 'migrate-incoming'," @@ -1358,7 +1338,7 @@ static void test_multifd_tcp_cancel(void) migrate_set_parameter_int(to2, "multifd-channels", 16); - migrate_set_capability(to2, "multifd", "true"); + migrate_set_capability(to2, "multifd", true); /* Start incoming migration from the 1st socket */ rsp = wait_command(to2, "{ 'execute': 'migrate-incoming'," @@ -1387,7 +1367,6 @@ static void test_multifd_tcp_cancel(void) wait_for_serial("dest_serial"); wait_for_migration_complete(from); test_migrate_end(from, to2, true); - g_free(uri); } int main(int argc, char **argv) diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c index bd15a1c294..a54fd70d27 100644 --- a/tests/qtest/npcm7xx_pwm-test.c +++ b/tests/qtest/npcm7xx_pwm-test.c @@ -201,7 +201,7 @@ static int pwm_module_index(const PWMModule *module) { ptrdiff_t diff = module - pwm_module_list; - g_assert_true(diff >= 0 && diff < ARRAY_SIZE(pwm_module_list)); + g_assert(diff >= 0 && diff < ARRAY_SIZE(pwm_module_list)); return diff; } @@ -211,7 +211,7 @@ static int pwm_index(const PWM *pwm) { ptrdiff_t diff = pwm - pwm_list; - g_assert_true(diff >= 0 && diff < ARRAY_SIZE(pwm_list)); + g_assert(diff >= 0 && diff < ARRAY_SIZE(pwm_list)); return diff; } diff --git a/tests/qtest/rtc-test.c b/tests/qtest/rtc-test.c index 402ce2c609..8126ab1bdb 100644 --- a/tests/qtest/rtc-test.c +++ b/tests/qtest/rtc-test.c @@ -686,7 +686,7 @@ static void periodic_timer(void) int main(int argc, char **argv) { - QTestState *s = NULL; + QTestState *s; int ret; g_test_init(&argc, &argv, NULL); @@ -712,9 +712,7 @@ int main(int argc, char **argv) ret = g_test_run(); - if (s) { - qtest_quit(s); - } + qtest_quit(s); return ret; } diff --git a/tests/qtest/tpm-util.c b/tests/qtest/tpm-util.c index b70cc32d60..3a40ff3f96 100644 --- a/tests/qtest/tpm-util.c +++ b/tests/qtest/tpm-util.c @@ -289,6 +289,6 @@ void tpm_util_migration_start_qemu(QTestState **src_qemu, *dst_qemu = qtest_init(dst_qemu_args); - free(src_qemu_args); - free(dst_qemu_args); + g_free(src_qemu_args); + g_free(dst_qemu_args); } diff --git a/tests/qtest/vhost-user-blk-test.c b/tests/qtest/vhost-user-blk-test.c new file mode 100644 index 0000000000..8796c74ca4 --- /dev/null +++ b/tests/qtest/vhost-user-blk-test.c @@ -0,0 +1,989 @@ +/* + * QTest testcase for Vhost-user Block Device + * + * Based on tests/qtest//virtio-blk-test.c + + * Copyright (c) 2014 SUSE LINUX Products GmbH + * Copyright (c) 2014 Marc Marà + * Copyright (c) 2020 Coiby Xu + * + * 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 "libqtest-single.h" +#include "qemu/bswap.h" +#include "qemu/module.h" +#include "standard-headers/linux/virtio_blk.h" +#include "standard-headers/linux/virtio_pci.h" +#include "libqos/qgraph.h" +#include "libqos/vhost-user-blk.h" +#include "libqos/libqos-pc.h" + +#define TEST_IMAGE_SIZE (64 * 1024 * 1024) +#define QVIRTIO_BLK_TIMEOUT_US (30 * 1000 * 1000) +#define PCI_SLOT_HP 0x06 + +typedef struct { + pid_t pid; +} QemuStorageDaemonState; + +typedef struct QVirtioBlkReq { + uint32_t type; + uint32_t ioprio; + uint64_t sector; + char *data; + uint8_t status; +} QVirtioBlkReq; + +#ifdef HOST_WORDS_BIGENDIAN +static const bool host_is_big_endian = true; +#else +static const bool host_is_big_endian; /* false */ +#endif + +static inline void virtio_blk_fix_request(QVirtioDevice *d, QVirtioBlkReq *req) +{ + if (qvirtio_is_big_endian(d) != host_is_big_endian) { + req->type = bswap32(req->type); + req->ioprio = bswap32(req->ioprio); + req->sector = bswap64(req->sector); + } +} + +static inline void virtio_blk_fix_dwz_hdr(QVirtioDevice *d, + struct virtio_blk_discard_write_zeroes *dwz_hdr) +{ + if (qvirtio_is_big_endian(d) != host_is_big_endian) { + dwz_hdr->sector = bswap64(dwz_hdr->sector); + dwz_hdr->num_sectors = bswap32(dwz_hdr->num_sectors); + dwz_hdr->flags = bswap32(dwz_hdr->flags); + } +} + +static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioDevice *d, + QVirtioBlkReq *req, uint64_t data_size) +{ + uint64_t addr; + uint8_t status = 0xFF; + QTestState *qts = global_qtest; + + switch (req->type) { + case VIRTIO_BLK_T_IN: + case VIRTIO_BLK_T_OUT: + g_assert_cmpuint(data_size % 512, ==, 0); + break; + case VIRTIO_BLK_T_DISCARD: + case VIRTIO_BLK_T_WRITE_ZEROES: + g_assert_cmpuint(data_size % + sizeof(struct virtio_blk_discard_write_zeroes), ==, 0); + break; + default: + g_assert_cmpuint(data_size, ==, 0); + } + + addr = guest_alloc(alloc, sizeof(*req) + data_size); + + virtio_blk_fix_request(d, req); + + qtest_memwrite(qts, addr, req, 16); + qtest_memwrite(qts, addr + 16, req->data, data_size); + qtest_memwrite(qts, addr + 16 + data_size, &status, sizeof(status)); + + return addr; +} + +static void test_invalid_discard_write_zeroes(QVirtioDevice *dev, + QGuestAllocator *alloc, + QTestState *qts, + QVirtQueue *vq, + uint32_t type) +{ + QVirtioBlkReq req; + struct virtio_blk_discard_write_zeroes dwz_hdr; + struct virtio_blk_discard_write_zeroes dwz_hdr2[2]; + uint64_t req_addr; + uint32_t free_head; + uint8_t status; + + /* More than one dwz is not supported */ + req.type = type; + req.data = (char *) dwz_hdr2; + dwz_hdr2[0].sector = 0; + dwz_hdr2[0].num_sectors = 1; + dwz_hdr2[0].flags = 0; + dwz_hdr2[1].sector = 1; + dwz_hdr2[1].num_sectors = 1; + dwz_hdr2[1].flags = 0; + + virtio_blk_fix_dwz_hdr(dev, &dwz_hdr2[0]); + virtio_blk_fix_dwz_hdr(dev, &dwz_hdr2[1]); + + req_addr = virtio_blk_request(alloc, dev, &req, sizeof(dwz_hdr2)); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, sizeof(dwz_hdr2), false, true); + qvirtqueue_add(qts, vq, req_addr + 16 + sizeof(dwz_hdr2), 1, true, + false); + + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 16 + sizeof(dwz_hdr2)); + g_assert_cmpint(status, ==, VIRTIO_BLK_S_UNSUPP); + + guest_free(alloc, req_addr); + + /* num_sectors must be less than config->max_write_zeroes_sectors */ + req.type = type; + req.data = (char *) &dwz_hdr; + dwz_hdr.sector = 0; + dwz_hdr.num_sectors = 0xffffffff; + dwz_hdr.flags = 0; + + virtio_blk_fix_dwz_hdr(dev, &dwz_hdr); + + req_addr = virtio_blk_request(alloc, dev, &req, sizeof(dwz_hdr)); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, sizeof(dwz_hdr), false, true); + qvirtqueue_add(qts, vq, req_addr + 16 + sizeof(dwz_hdr), 1, true, + false); + + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 16 + sizeof(dwz_hdr)); + g_assert_cmpint(status, ==, VIRTIO_BLK_S_IOERR); + + guest_free(alloc, req_addr); + + /* sector must be less than the device capacity */ + req.type = type; + req.data = (char *) &dwz_hdr; + dwz_hdr.sector = TEST_IMAGE_SIZE / 512 + 1; + dwz_hdr.num_sectors = 1; + dwz_hdr.flags = 0; + + virtio_blk_fix_dwz_hdr(dev, &dwz_hdr); + + req_addr = virtio_blk_request(alloc, dev, &req, sizeof(dwz_hdr)); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, sizeof(dwz_hdr), false, true); + qvirtqueue_add(qts, vq, req_addr + 16 + sizeof(dwz_hdr), 1, true, + false); + + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 16 + sizeof(dwz_hdr)); + g_assert_cmpint(status, ==, VIRTIO_BLK_S_IOERR); + + guest_free(alloc, req_addr); + + /* reserved flag bits must be zero */ + req.type = type; + req.data = (char *) &dwz_hdr; + dwz_hdr.sector = 0; + dwz_hdr.num_sectors = 1; + dwz_hdr.flags = ~VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP; + + virtio_blk_fix_dwz_hdr(dev, &dwz_hdr); + + req_addr = virtio_blk_request(alloc, dev, &req, sizeof(dwz_hdr)); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, sizeof(dwz_hdr), false, true); + qvirtqueue_add(qts, vq, req_addr + 16 + sizeof(dwz_hdr), 1, true, + false); + + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 16 + sizeof(dwz_hdr)); + g_assert_cmpint(status, ==, VIRTIO_BLK_S_UNSUPP); + + guest_free(alloc, req_addr); +} + +/* Returns the request virtqueue so the caller can perform further tests */ +static QVirtQueue *test_basic(QVirtioDevice *dev, QGuestAllocator *alloc) +{ + QVirtioBlkReq req; + uint64_t req_addr; + uint64_t capacity; + uint64_t features; + uint32_t free_head; + uint8_t status; + char *data; + QTestState *qts = global_qtest; + QVirtQueue *vq; + + features = qvirtio_get_features(dev); + features = features & ~(QVIRTIO_F_BAD_FEATURE | + (1u << VIRTIO_RING_F_INDIRECT_DESC) | + (1u << VIRTIO_RING_F_EVENT_IDX) | + (1u << VIRTIO_BLK_F_SCSI)); + qvirtio_set_features(dev, features); + + capacity = qvirtio_config_readq(dev, 0); + g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); + + vq = qvirtqueue_setup(dev, alloc, 0); + + qvirtio_set_driver_ok(dev); + + /* Write and read with 3 descriptor layout */ + /* Write request */ + req.type = VIRTIO_BLK_T_OUT; + req.ioprio = 1; + req.sector = 0; + req.data = g_malloc0(512); + strcpy(req.data, "TEST"); + + req_addr = virtio_blk_request(alloc, dev, &req, 512); + + g_free(req.data); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, 512, false, true); + qvirtqueue_add(qts, vq, req_addr + 528, 1, true, false); + + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 528); + g_assert_cmpint(status, ==, 0); + + guest_free(alloc, req_addr); + + /* Read request */ + req.type = VIRTIO_BLK_T_IN; + req.ioprio = 1; + req.sector = 0; + req.data = g_malloc0(512); + + req_addr = virtio_blk_request(alloc, dev, &req, 512); + + g_free(req.data); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, 512, true, true); + qvirtqueue_add(qts, vq, req_addr + 528, 1, true, false); + + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 528); + g_assert_cmpint(status, ==, 0); + + data = g_malloc0(512); + qtest_memread(qts, req_addr + 16, data, 512); + g_assert_cmpstr(data, ==, "TEST"); + g_free(data); + + guest_free(alloc, req_addr); + + if (features & (1u << VIRTIO_BLK_F_WRITE_ZEROES)) { + struct virtio_blk_discard_write_zeroes dwz_hdr; + void *expected; + + /* + * WRITE_ZEROES request on the same sector of previous test where + * we wrote "TEST". + */ + req.type = VIRTIO_BLK_T_WRITE_ZEROES; + req.data = (char *) &dwz_hdr; + dwz_hdr.sector = 0; + dwz_hdr.num_sectors = 1; + dwz_hdr.flags = 0; + + virtio_blk_fix_dwz_hdr(dev, &dwz_hdr); + + req_addr = virtio_blk_request(alloc, dev, &req, sizeof(dwz_hdr)); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, sizeof(dwz_hdr), false, true); + qvirtqueue_add(qts, vq, req_addr + 16 + sizeof(dwz_hdr), 1, true, + false); + + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 16 + sizeof(dwz_hdr)); + g_assert_cmpint(status, ==, 0); + + guest_free(alloc, req_addr); + + /* Read request to check if the sector contains all zeroes */ + req.type = VIRTIO_BLK_T_IN; + req.ioprio = 1; + req.sector = 0; + req.data = g_malloc0(512); + + req_addr = virtio_blk_request(alloc, dev, &req, 512); + + g_free(req.data); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, 512, true, true); + qvirtqueue_add(qts, vq, req_addr + 528, 1, true, false); + + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 528); + g_assert_cmpint(status, ==, 0); + + data = g_malloc(512); + expected = g_malloc0(512); + qtest_memread(qts, req_addr + 16, data, 512); + g_assert_cmpmem(data, 512, expected, 512); + g_free(expected); + g_free(data); + + guest_free(alloc, req_addr); + + test_invalid_discard_write_zeroes(dev, alloc, qts, vq, + VIRTIO_BLK_T_WRITE_ZEROES); + } + + if (features & (1u << VIRTIO_BLK_F_DISCARD)) { + struct virtio_blk_discard_write_zeroes dwz_hdr; + + req.type = VIRTIO_BLK_T_DISCARD; + req.data = (char *) &dwz_hdr; + dwz_hdr.sector = 0; + dwz_hdr.num_sectors = 1; + dwz_hdr.flags = 0; + + virtio_blk_fix_dwz_hdr(dev, &dwz_hdr); + + req_addr = virtio_blk_request(alloc, dev, &req, sizeof(dwz_hdr)); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, sizeof(dwz_hdr), false, true); + qvirtqueue_add(qts, vq, req_addr + 16 + sizeof(dwz_hdr), + 1, true, false); + + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 16 + sizeof(dwz_hdr)); + g_assert_cmpint(status, ==, 0); + + guest_free(alloc, req_addr); + + test_invalid_discard_write_zeroes(dev, alloc, qts, vq, + VIRTIO_BLK_T_DISCARD); + } + + if (features & (1u << VIRTIO_F_ANY_LAYOUT)) { + /* Write and read with 2 descriptor layout */ + /* Write request */ + req.type = VIRTIO_BLK_T_OUT; + req.ioprio = 1; + req.sector = 1; + req.data = g_malloc0(512); + strcpy(req.data, "TEST"); + + req_addr = virtio_blk_request(alloc, dev, &req, 512); + + g_free(req.data); + + free_head = qvirtqueue_add(qts, vq, req_addr, 528, false, true); + qvirtqueue_add(qts, vq, req_addr + 528, 1, true, false); + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 528); + g_assert_cmpint(status, ==, 0); + + guest_free(alloc, req_addr); + + /* Read request */ + req.type = VIRTIO_BLK_T_IN; + req.ioprio = 1; + req.sector = 1; + req.data = g_malloc0(512); + + req_addr = virtio_blk_request(alloc, dev, &req, 512); + + g_free(req.data); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, 513, true, false); + + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 528); + g_assert_cmpint(status, ==, 0); + + data = g_malloc0(512); + qtest_memread(qts, req_addr + 16, data, 512); + g_assert_cmpstr(data, ==, "TEST"); + g_free(data); + + guest_free(alloc, req_addr); + } + + return vq; +} + +static void basic(void *obj, void *data, QGuestAllocator *t_alloc) +{ + QVhostUserBlk *blk_if = obj; + QVirtQueue *vq; + + vq = test_basic(blk_if->vdev, t_alloc); + qvirtqueue_cleanup(blk_if->vdev->bus, vq, t_alloc); + +} + +static void indirect(void *obj, void *u_data, QGuestAllocator *t_alloc) +{ + QVirtQueue *vq; + QVhostUserBlk *blk_if = obj; + QVirtioDevice *dev = blk_if->vdev; + QVirtioBlkReq req; + QVRingIndirectDesc *indirect; + uint64_t req_addr; + uint64_t capacity; + uint64_t features; + uint32_t free_head; + uint8_t status; + char *data; + QTestState *qts = global_qtest; + + features = qvirtio_get_features(dev); + g_assert_cmphex(features & (1u << VIRTIO_RING_F_INDIRECT_DESC), !=, 0); + features = features & ~(QVIRTIO_F_BAD_FEATURE | + (1u << VIRTIO_RING_F_EVENT_IDX) | + (1u << VIRTIO_BLK_F_SCSI)); + qvirtio_set_features(dev, features); + + capacity = qvirtio_config_readq(dev, 0); + g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); + + vq = qvirtqueue_setup(dev, t_alloc, 0); + qvirtio_set_driver_ok(dev); + + /* Write request */ + req.type = VIRTIO_BLK_T_OUT; + req.ioprio = 1; + req.sector = 0; + req.data = g_malloc0(512); + strcpy(req.data, "TEST"); + + req_addr = virtio_blk_request(t_alloc, dev, &req, 512); + + g_free(req.data); + + indirect = qvring_indirect_desc_setup(qts, dev, t_alloc, 2); + qvring_indirect_desc_add(dev, qts, indirect, req_addr, 528, false); + qvring_indirect_desc_add(dev, qts, indirect, req_addr + 528, 1, true); + free_head = qvirtqueue_add_indirect(qts, vq, indirect); + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 528); + g_assert_cmpint(status, ==, 0); + + g_free(indirect); + guest_free(t_alloc, req_addr); + + /* Read request */ + req.type = VIRTIO_BLK_T_IN; + req.ioprio = 1; + req.sector = 0; + req.data = g_malloc0(512); + strcpy(req.data, "TEST"); + + req_addr = virtio_blk_request(t_alloc, dev, &req, 512); + + g_free(req.data); + + indirect = qvring_indirect_desc_setup(qts, dev, t_alloc, 2); + qvring_indirect_desc_add(dev, qts, indirect, req_addr, 16, false); + qvring_indirect_desc_add(dev, qts, indirect, req_addr + 16, 513, true); + free_head = qvirtqueue_add_indirect(qts, vq, indirect); + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + status = readb(req_addr + 528); + g_assert_cmpint(status, ==, 0); + + data = g_malloc0(512); + qtest_memread(qts, req_addr + 16, data, 512); + g_assert_cmpstr(data, ==, "TEST"); + g_free(data); + + g_free(indirect); + guest_free(t_alloc, req_addr); + qvirtqueue_cleanup(dev->bus, vq, t_alloc); +} + +static void idx(void *obj, void *u_data, QGuestAllocator *t_alloc) +{ + QVirtQueue *vq; + QVhostUserBlkPCI *blk = obj; + QVirtioPCIDevice *pdev = &blk->pci_vdev; + QVirtioDevice *dev = &pdev->vdev; + QVirtioBlkReq req; + uint64_t req_addr; + uint64_t capacity; + uint64_t features; + uint32_t free_head; + uint32_t write_head; + uint32_t desc_idx; + uint8_t status; + char *data; + QOSGraphObject *blk_object = obj; + QPCIDevice *pci_dev = blk_object->get_driver(blk_object, "pci-device"); + QTestState *qts = global_qtest; + + if (qpci_check_buggy_msi(pci_dev)) { + return; + } + + qpci_msix_enable(pdev->pdev); + qvirtio_pci_set_msix_configuration_vector(pdev, t_alloc, 0); + + features = qvirtio_get_features(dev); + features = features & ~(QVIRTIO_F_BAD_FEATURE | + (1u << VIRTIO_RING_F_INDIRECT_DESC) | + (1u << VIRTIO_F_NOTIFY_ON_EMPTY) | + (1u << VIRTIO_BLK_F_SCSI)); + qvirtio_set_features(dev, features); + + capacity = qvirtio_config_readq(dev, 0); + g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); + + vq = qvirtqueue_setup(dev, t_alloc, 0); + qvirtqueue_pci_msix_setup(pdev, (QVirtQueuePCI *)vq, t_alloc, 1); + + qvirtio_set_driver_ok(dev); + + /* + * libvhost-user signals the call fd in VHOST_USER_SET_VRING_CALL, make + * sure to wait for the isr here so we don't race and confuse it later on. + */ + qvirtio_wait_queue_isr(qts, dev, vq, QVIRTIO_BLK_TIMEOUT_US); + + /* Write request */ + req.type = VIRTIO_BLK_T_OUT; + req.ioprio = 1; + req.sector = 0; + req.data = g_malloc0(512); + strcpy(req.data, "TEST"); + + req_addr = virtio_blk_request(t_alloc, dev, &req, 512); + + g_free(req.data); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, 512, false, true); + qvirtqueue_add(qts, vq, req_addr + 528, 1, true, false); + qvirtqueue_kick(qts, dev, vq, free_head); + + qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + + /* Write request */ + req.type = VIRTIO_BLK_T_OUT; + req.ioprio = 1; + req.sector = 1; + req.data = g_malloc0(512); + strcpy(req.data, "TEST"); + + req_addr = virtio_blk_request(t_alloc, dev, &req, 512); + + g_free(req.data); + + /* Notify after processing the third request */ + qvirtqueue_set_used_event(qts, vq, 2); + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, 512, false, true); + qvirtqueue_add(qts, vq, req_addr + 528, 1, true, false); + qvirtqueue_kick(qts, dev, vq, free_head); + write_head = free_head; + + /* No notification expected */ + status = qvirtio_wait_status_byte_no_isr(qts, dev, + vq, req_addr + 528, + QVIRTIO_BLK_TIMEOUT_US); + g_assert_cmpint(status, ==, 0); + + guest_free(t_alloc, req_addr); + + /* Read request */ + req.type = VIRTIO_BLK_T_IN; + req.ioprio = 1; + req.sector = 1; + req.data = g_malloc0(512); + + req_addr = virtio_blk_request(t_alloc, dev, &req, 512); + + g_free(req.data); + + free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true); + qvirtqueue_add(qts, vq, req_addr + 16, 512, true, true); + qvirtqueue_add(qts, vq, req_addr + 528, 1, true, false); + + qvirtqueue_kick(qts, dev, vq, free_head); + + /* We get just one notification for both requests */ + qvirtio_wait_used_elem(qts, dev, vq, write_head, NULL, + QVIRTIO_BLK_TIMEOUT_US); + g_assert(qvirtqueue_get_buf(qts, vq, &desc_idx, NULL)); + g_assert_cmpint(desc_idx, ==, free_head); + + status = readb(req_addr + 528); + g_assert_cmpint(status, ==, 0); + + data = g_malloc0(512); + qtest_memread(qts, req_addr + 16, data, 512); + g_assert_cmpstr(data, ==, "TEST"); + g_free(data); + + guest_free(t_alloc, req_addr); + + /* End test */ + qpci_msix_disable(pdev->pdev); + + qvirtqueue_cleanup(dev->bus, vq, t_alloc); +} + +static void pci_hotplug(void *obj, void *data, QGuestAllocator *t_alloc) +{ + QVirtioPCIDevice *dev1 = obj; + QVirtioPCIDevice *dev; + QTestState *qts = dev1->pdev->bus->qts; + + /* plug secondary disk */ + qtest_qmp_device_add(qts, "vhost-user-blk-pci", "drv1", + "{'addr': %s, 'chardev': 'char2'}", + stringify(PCI_SLOT_HP) ".0"); + + dev = virtio_pci_new(dev1->pdev->bus, + &(QPCIAddress) { .devfn = QPCI_DEVFN(PCI_SLOT_HP, 0) + }); + g_assert_nonnull(dev); + g_assert_cmpint(dev->vdev.device_type, ==, VIRTIO_ID_BLOCK); + qvirtio_pci_device_disable(dev); + qos_object_destroy((QOSGraphObject *)dev); + + /* unplug secondary disk */ + qpci_unplug_acpi_device_test(qts, "drv1", PCI_SLOT_HP); +} + +static void multiqueue(void *obj, void *data, QGuestAllocator *t_alloc) +{ + QVirtioPCIDevice *pdev1 = obj; + QVirtioDevice *dev1 = &pdev1->vdev; + QVirtioPCIDevice *pdev8; + QVirtioDevice *dev8; + QTestState *qts = pdev1->pdev->bus->qts; + uint64_t features; + uint16_t num_queues; + + /* + * The primary device has 1 queue and VIRTIO_BLK_F_MQ is not enabled. The + * VIRTIO specification allows VIRTIO_BLK_F_MQ to be enabled when there is + * only 1 virtqueue, but --device vhost-user-blk-pci doesn't do this (which + * is also spec-compliant). + */ + features = qvirtio_get_features(dev1); + g_assert_cmpint(features & (1u << VIRTIO_BLK_F_MQ), ==, 0); + features = features & ~(QVIRTIO_F_BAD_FEATURE | + (1u << VIRTIO_RING_F_INDIRECT_DESC) | + (1u << VIRTIO_F_NOTIFY_ON_EMPTY) | + (1u << VIRTIO_BLK_F_SCSI)); + qvirtio_set_features(dev1, features); + + /* Hotplug a secondary device with 8 queues */ + qtest_qmp_device_add(qts, "vhost-user-blk-pci", "drv1", + "{'addr': %s, 'chardev': 'char2', 'num-queues': 8}", + stringify(PCI_SLOT_HP) ".0"); + + pdev8 = virtio_pci_new(pdev1->pdev->bus, + &(QPCIAddress) { + .devfn = QPCI_DEVFN(PCI_SLOT_HP, 0) + }); + g_assert_nonnull(pdev8); + g_assert_cmpint(pdev8->vdev.device_type, ==, VIRTIO_ID_BLOCK); + + qos_object_start_hw(&pdev8->obj); + + dev8 = &pdev8->vdev; + features = qvirtio_get_features(dev8); + g_assert_cmpint(features & (1u << VIRTIO_BLK_F_MQ), + ==, + (1u << VIRTIO_BLK_F_MQ)); + features = features & ~(QVIRTIO_F_BAD_FEATURE | + (1u << VIRTIO_RING_F_INDIRECT_DESC) | + (1u << VIRTIO_F_NOTIFY_ON_EMPTY) | + (1u << VIRTIO_BLK_F_SCSI) | + (1u << VIRTIO_BLK_F_MQ)); + qvirtio_set_features(dev8, features); + + num_queues = qvirtio_config_readw(dev8, + offsetof(struct virtio_blk_config, num_queues)); + g_assert_cmpint(num_queues, ==, 8); + + qvirtio_pci_device_disable(pdev8); + qos_object_destroy(&pdev8->obj); + + /* unplug secondary disk */ + qpci_unplug_acpi_device_test(qts, "drv1", PCI_SLOT_HP); +} + +/* + * Check that setting the vring addr on a non-existent virtqueue does + * not crash. + */ +static void test_nonexistent_virtqueue(void *obj, void *data, + QGuestAllocator *t_alloc) +{ + QVhostUserBlkPCI *blk = obj; + QVirtioPCIDevice *pdev = &blk->pci_vdev; + QPCIBar bar0; + QPCIDevice *dev; + + dev = qpci_device_find(pdev->pdev->bus, QPCI_DEVFN(4, 0)); + g_assert(dev != NULL); + qpci_device_enable(dev); + + bar0 = qpci_iomap(dev, 0, NULL); + + qpci_io_writeb(dev, bar0, VIRTIO_PCI_QUEUE_SEL, 2); + qpci_io_writel(dev, bar0, VIRTIO_PCI_QUEUE_PFN, 1); + + g_free(dev); +} + +static const char *qtest_qemu_storage_daemon_binary(void) +{ + const char *qemu_storage_daemon_bin; + + qemu_storage_daemon_bin = getenv("QTEST_QEMU_STORAGE_DAEMON_BINARY"); + if (!qemu_storage_daemon_bin) { + fprintf(stderr, "Environment variable " + "QTEST_QEMU_STORAGE_DAEMON_BINARY required\n"); + exit(0); + } + + return qemu_storage_daemon_bin; +} + +/* g_test_queue_destroy() cleanup function for files */ +static void destroy_file(void *path) +{ + unlink(path); + g_free(path); + qos_invalidate_command_line(); +} + +static char *drive_create(void) +{ + int fd, ret; + /** vhost-user-blk won't recognize drive located in /tmp */ + char *t_path = g_strdup("qtest.XXXXXX"); + + /** Create a temporary raw image */ + fd = mkstemp(t_path); + g_assert_cmpint(fd, >=, 0); + ret = ftruncate(fd, TEST_IMAGE_SIZE); + g_assert_cmpint(ret, ==, 0); + close(fd); + + g_test_queue_destroy(destroy_file, t_path); + return t_path; +} + +static char *create_listen_socket(int *fd) +{ + int tmp_fd; + char *path; + + /* No race because our pid makes the path unique */ + path = g_strdup_printf("/tmp/qtest-%d-sock.XXXXXX", getpid()); + tmp_fd = mkstemp(path); + g_assert_cmpint(tmp_fd, >=, 0); + close(tmp_fd); + unlink(path); + + *fd = qtest_socket_server(path); + g_test_queue_destroy(destroy_file, path); + return path; +} + +/* + * g_test_queue_destroy() and qtest_add_abrt_handler() cleanup function for + * qemu-storage-daemon. + */ +static void quit_storage_daemon(void *data) +{ + QemuStorageDaemonState *qsd = data; + int wstatus; + pid_t pid; + + /* + * If we were invoked as a g_test_queue_destroy() cleanup function we need + * to remove the abrt handler to avoid being called again if the code below + * aborts. Also, we must not leave the abrt handler installed after + * cleanup. + */ + qtest_remove_abrt_handler(data); + + /* Before quitting storage-daemon, quit qemu to avoid dubious messages */ + qtest_kill_qemu(global_qtest); + + kill(qsd->pid, SIGTERM); + pid = waitpid(qsd->pid, &wstatus, 0); + g_assert_cmpint(pid, ==, qsd->pid); + if (!WIFEXITED(wstatus)) { + fprintf(stderr, "%s: expected qemu-storage-daemon to exit\n", + __func__); + abort(); + } + if (WEXITSTATUS(wstatus) != 0) { + fprintf(stderr, "%s: expected qemu-storage-daemon to exit " + "successfully, got %d\n", + __func__, WEXITSTATUS(wstatus)); + abort(); + } + + g_free(data); +} + +static void start_vhost_user_blk(GString *cmd_line, int vus_instances, + int num_queues) +{ + const char *vhost_user_blk_bin = qtest_qemu_storage_daemon_binary(); + int i; + gchar *img_path; + GString *storage_daemon_command = g_string_new(NULL); + QemuStorageDaemonState *qsd; + + g_string_append_printf(storage_daemon_command, + "exec %s ", + vhost_user_blk_bin); + + g_string_append_printf(cmd_line, + " -object memory-backend-memfd,id=mem,size=256M,share=on " + " -M memory-backend=mem -m 256M "); + + for (i = 0; i < vus_instances; i++) { + int fd; + char *sock_path = create_listen_socket(&fd); + + /* create image file */ + img_path = drive_create(); + g_string_append_printf(storage_daemon_command, + "--blockdev driver=file,node-name=disk%d,filename=%s " + "--export type=vhost-user-blk,id=disk%d,addr.type=unix,addr.path=%s," + "node-name=disk%i,writable=on,num-queues=%d ", + i, img_path, i, sock_path, i, num_queues); + + g_string_append_printf(cmd_line, "-chardev socket,id=char%d,path=%s ", + i + 1, sock_path); + } + + g_test_message("starting vhost-user backend: %s", + storage_daemon_command->str); + pid_t pid = fork(); + if (pid == 0) { + /* + * Close standard file descriptors so tap-driver.pl pipe detects when + * our parent terminates. + */ + close(0); + close(1); + open("/dev/null", O_RDONLY); + open("/dev/null", O_WRONLY); + + execlp("/bin/sh", "sh", "-c", storage_daemon_command->str, NULL); + exit(1); + } + g_string_free(storage_daemon_command, true); + + qsd = g_new(QemuStorageDaemonState, 1); + qsd->pid = pid; + + /* Make sure qemu-storage-daemon is stopped */ + qtest_add_abrt_handler(quit_storage_daemon, qsd); + g_test_queue_destroy(quit_storage_daemon, qsd); +} + +static void *vhost_user_blk_test_setup(GString *cmd_line, void *arg) +{ + start_vhost_user_blk(cmd_line, 1, 1); + return arg; +} + +/* + * Setup for hotplug. + * + * Since vhost-user server only serves one vhost-user client one time, + * another exprot + * + */ +static void *vhost_user_blk_hotplug_test_setup(GString *cmd_line, void *arg) +{ + /* "-chardev socket,id=char2" is used for pci_hotplug*/ + start_vhost_user_blk(cmd_line, 2, 1); + return arg; +} + +static void *vhost_user_blk_multiqueue_test_setup(GString *cmd_line, void *arg) +{ + start_vhost_user_blk(cmd_line, 2, 8); + return arg; +} + +static void register_vhost_user_blk_test(void) +{ + QOSGraphTestOptions opts = { + .before = vhost_user_blk_test_setup, + }; + + /* + * tests for vhost-user-blk and vhost-user-blk-pci + * The tests are borrowed from tests/virtio-blk-test.c. But some tests + * regarding block_resize don't work for vhost-user-blk. + * vhost-user-blk device doesn't have -drive, so tests containing + * block_resize are also abandoned, + * - config + * - resize + */ + qos_add_test("basic", "vhost-user-blk", basic, &opts); + qos_add_test("indirect", "vhost-user-blk", indirect, &opts); + qos_add_test("idx", "vhost-user-blk-pci", idx, &opts); + qos_add_test("nxvirtq", "vhost-user-blk-pci", + test_nonexistent_virtqueue, &opts); + + opts.before = vhost_user_blk_hotplug_test_setup; + qos_add_test("hotplug", "vhost-user-blk-pci", pci_hotplug, &opts); + + opts.before = vhost_user_blk_multiqueue_test_setup; + qos_add_test("multiqueue", "vhost-user-blk-pci", multiqueue, &opts); +} + +libqos_init(register_vhost_user_blk_test); diff --git a/tests/tcg/Makefile.qemu b/tests/tcg/Makefile.qemu index a56564660c..84c8543878 100644 --- a/tests/tcg/Makefile.qemu +++ b/tests/tcg/Makefile.qemu @@ -22,6 +22,8 @@ quiet-@ = $(if $(V),,@) quiet-command = $(quiet-@)$(call quiet-command-run,$1,$2,$3) CROSS_CC_GUEST:= +CROSS_AS_GUEST:= +CROSS_LD_GUEST:= DOCKER_IMAGE:= -include tests/tcg/config-$(TARGET).mak @@ -42,6 +44,8 @@ cross-build-guest-tests: $(call quiet-command, \ (mkdir -p tests/tcg/$(TARGET) && cd tests/tcg/$(TARGET) && \ $(MAKE) -f $(TCG_MAKE) TARGET="$(TARGET)" CC="$(CROSS_CC_GUEST)" \ + $(if $(CROSS_AS_GUEST),AS="$(CROSS_AS_GUEST)") \ + $(if $(CROSS_LD_GUEST),LD="$(CROSS_LD_GUEST)") \ SRC_PATH="$(SRC_PATH)" BUILD_STATIC=$(CROSS_CC_GUEST_STATIC) \ EXTRA_CFLAGS="$(CROSS_CC_GUEST_CFLAGS)"), \ "BUILD","$(TARGET) guest-tests with $(CROSS_CC_GUEST)") @@ -59,11 +63,24 @@ DOCKER_COMPILE_CMD="$(DOCKER_SCRIPT) cc \ -i qemu/$(DOCKER_IMAGE) \ -s $(SRC_PATH) -- " +DOCKER_AS_CMD=$(if $(DOCKER_CROSS_AS_GUEST),"$(DOCKER_SCRIPT) cc \ + --cc $(DOCKER_CROSS_AS_GUEST) \ + -i qemu/$(DOCKER_IMAGE) \ + -s $(SRC_PATH) -- ") + +DOCKER_LD_CMD=$(if $(DOCKER_CROSS_LD_GUEST),"$(DOCKER_SCRIPT) cc \ + --cc $(DOCKER_CROSS_LD_GUEST) \ + -i qemu/$(DOCKER_IMAGE) \ + -s $(SRC_PATH) -- ") + + .PHONY: docker-build-guest-tests docker-build-guest-tests: docker-image-$(DOCKER_IMAGE) $(call quiet-command, \ (mkdir -p tests/tcg/$(TARGET) && cd tests/tcg/$(TARGET) && \ $(MAKE) -f $(TCG_MAKE) TARGET="$(TARGET)" CC=$(DOCKER_COMPILE_CMD) \ + $(if $(DOCKER_AS_CMD),AS=$(DOCKER_AS_CMD)) \ + $(if $(DOCKER_LD_CMD),LD=$(DOCKER_LD_CMD)) \ SRC_PATH="$(SRC_PATH)" BUILD_STATIC=y \ EXTRA_CFLAGS="$(CROSS_CC_GUEST_CFLAGS)"), \ "BUILD","$(TARGET) guest-tests with docker qemu/$(DOCKER_IMAGE)") diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target index cab8c6b3a2..b29fae4630 100644 --- a/tests/tcg/Makefile.target +++ b/tests/tcg/Makefile.target @@ -43,9 +43,10 @@ quiet-command = $(if $(V),$1,$(if $(2),@printf " %-7s %s\n" $2 $3 && $1, @$1)) # $1 = test name, $2 = cmd, $3 = desc ifdef CONFIG_USER_ONLY -run-test = $(call quiet-command, timeout $(TIMEOUT) $2 > $1.out,"TEST",$3) +run-test = $(call quiet-command, timeout --foreground $(TIMEOUT) $2 > $1.out, \ + "TEST",$3) else -run-test = $(call quiet-command, timeout $(TIMEOUT) $2,"TEST",$3) +run-test = $(call quiet-command, timeout --foreground $(TIMEOUT) $2,"TEST",$3) endif # $1 = test name, $2 = reference diff --git a/tests/tcg/README b/tests/tcg/README index 2a58f9a058..706bb185b4 100644 --- a/tests/tcg/README +++ b/tests/tcg/README @@ -7,9 +7,3 @@ CRIS ==== The testsuite for CRIS is in tests/tcg/cris. You can run it with "make test-cris". - -LM32 -==== -The testsuite for LM32 is in tests/tcg/lm32. You can run it -with "make test-lm32". - diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh index fa1a4261a4..ed6492ce59 100755 --- a/tests/tcg/configure.sh +++ b/tests/tcg/configure.sh @@ -74,37 +74,17 @@ fi for target in $target_list; do arch=${target%%-*} - case $arch in - arm|armeb) - arches=arm - ;; - aarch64|aarch64_be) - arches="aarch64 arm" - ;; - mips*) - arches=mips - ;; - ppc*) - arches=ppc - ;; - sh4|sh4eb) - arches=sh4 - ;; - x86_64) - arches="x86_64 i386" - ;; - xtensa|xtensaeb) - arches=xtensa - ;; - alpha|cris|hexagon|hppa|i386|lm32|microblaze|microblazeel|m68k|openrisc|riscv64|s390x|sh4|sparc64) - arches=$target - ;; - *) - continue - ;; - esac + # reset all container fields container_image= + container_hosts= + container_cross_cc= + container_cross_as= + container_cross_ld= + + # suppress clang + supress_clang= + case $target in aarch64-*) # We don't have any bigendian build tools so we only use this for AArch64 @@ -128,6 +108,11 @@ for target in $target_list; do container_image=fedora-cris-cross container_cross_cc=cris-linux-gnu-gcc ;; + hexagon-*) + container_hosts=x86_64 + container_image=debian-hexagon-cross + container_cross_cc=hexagon-unknown-linux-musl-clang + ;; hppa-*) container_hosts=x86_64 container_image=debian-hppa-cross @@ -137,6 +122,7 @@ for target in $target_list; do container_hosts=x86_64 container_image=fedora-i386-cross container_cross_cc=gcc + supress_clang=yes ;; m68k-*) container_hosts=x86_64 @@ -165,18 +151,14 @@ for target in $target_list; do ;; ppc-*|ppc64abi32-*) container_hosts=x86_64 - container_image=debian-powerpc-cross - container_cross_cc=powerpc-linux-gnu-gcc - ;; - ppc64-*) - container_hosts=x86_64 - container_image=debian-ppc64-cross - container_cross_cc=powerpc64-linux-gnu-gcc + container_image=debian-powerpc-test-cross + container_cross_cc=powerpc-linux-gnu-gcc-10 ;; - ppc64le-*) + ppc64-*|ppc64le-*) container_hosts=x86_64 - container_image=debian-ppc64el-cross - container_cross_cc=powerpc64le-linux-gnu-gcc + container_image=debian-powerpc-test-cross + container_cross_cc=${target%%-*}-linux-gnu-gcc-10 + container_cross_cc=powerpc${container_cross_cc#ppc} ;; riscv64-*) container_hosts=x86_64 @@ -198,10 +180,17 @@ for target in $target_list; do container_image=debian-sparc64-cross container_cross_cc=sparc64-linux-gnu-gcc ;; + tricore-softmmu) + container_hosts=x86_64 + container_image=debian-tricore-cross + container_cross_as=tricore-as + container_cross_ld=tricore-ld + ;; x86_64-*) container_hosts="aarch64 ppc64el x86_64" container_image=debian-amd64-cross container_cross_cc=x86_64-linux-gnu-gcc + supress_clang=yes ;; xtensa*-softmmu) container_hosts=x86_64 @@ -216,6 +205,7 @@ for target in $target_list; do echo "# Automatically generated by configure - do not modify" > $config_target_mak echo "TARGET_NAME=$arch" >> $config_target_mak + echo "target=$target" >> $config_target_mak case $target in *-linux-user | *-bsd-user) echo "CONFIG_USER_ONLY=y" >> $config_target_mak @@ -231,74 +221,91 @@ for target in $target_list; do echo "CROSS_CC_GUEST_CFLAGS=$target_compiler_cflags" >> $config_target_mak got_cross_cc=no - for i in $arch $arches; do - if eval test "x\${cross_cc_$i+yes}" != xyes; then - continue - fi - eval "target_compiler=\${cross_cc_$i}" - if ! has $target_compiler; then - continue - fi - write_c_skeleton - if ! do_compiler "$target_compiler" $target_compiler_cflags -o $TMPE $TMPC -static ; then - # For host systems we might get away with building without -static - if ! do_compiler "$target_compiler" $target_compiler_cflags -o $TMPE $TMPC ; then - continue - fi - echo "CROSS_CC_GUEST_STATIC=y" >> $config_target_mak - else - echo "CROSS_CC_GUEST_STATIC=y" >> $config_target_mak - fi - echo "CROSS_CC_GUEST=$target_compiler" >> $config_target_mak + if eval test "x\${cross_cc_$arch}" != xyes; then + eval "target_compiler=\${cross_cc_$arch}" - # Test for compiler features for optional tests. We only do this - # for cross compilers because ensuring the docker containers based - # compilers is a requirememt for adding a new test that needs a - # compiler feature. - case $target in - aarch64-*) - if do_compiler "$target_compiler" $target_compiler_cflags \ - -march=armv8.1-a+sve -o $TMPE $TMPC; then - echo "CROSS_CC_HAS_SVE=y" >> $config_target_mak - fi - if do_compiler "$target_compiler" $target_compiler_cflags \ - -march=armv8.3-a -o $TMPE $TMPC; then - echo "CROSS_CC_HAS_ARMV8_3=y" >> $config_target_mak - fi - if do_compiler "$target_compiler" $target_compiler_cflags \ - -mbranch-protection=standard -o $TMPE $TMPC; then - echo "CROSS_CC_HAS_ARMV8_BTI=y" >> $config_target_mak - fi - if do_compiler "$target_compiler" $target_compiler_cflags \ - -march=armv8.5-a+memtag -o $TMPE $TMPC; then - echo "CROSS_CC_HAS_ARMV8_MTE=y" >> $config_target_mak - fi - ;; - ppc*) - if do_compiler "$target_compiler" $target_compiler_cflags \ - -mpower8-vector -o $TMPE $TMPC; then - echo "CROSS_CC_HAS_POWER8_VECTOR=y" >> $config_target_mak - fi - ;; - i386-linux-user) - if do_compiler "$target_compiler" $target_compiler_cflags \ - -Werror -fno-pie -o $TMPE $TMPC; then - echo "CROSS_CC_HAS_I386_NOPIE=y" >> $config_target_mak - fi - ;; - esac + if has "$target_compiler"; then + if test "$supress_clang" = yes && + $target_compiler --version | grep -qi "clang"; then + got_cross_cc=no + else + write_c_skeleton + if ! do_compiler "$target_compiler" $target_compiler_cflags \ + -o $TMPE $TMPC -static ; then + # For host systems we might get away with building without -static + if do_compiler "$target_compiler" $target_compiler_cflags \ + -o $TMPE $TMPC ; then + got_cross_cc=yes + echo "CROSS_CC_GUEST_STATIC=y" >> $config_target_mak + echo "CROSS_CC_GUEST=$target_compiler" >> $config_target_mak + fi + else + got_cross_cc=yes + echo "CROSS_CC_GUEST_STATIC=y" >> $config_target_mak + echo "CROSS_CC_GUEST=$target_compiler" >> $config_target_mak + fi + fi + fi + fi - enabled_cross_compilers="$enabled_cross_compilers $target_compiler" - got_cross_cc=yes - break - done + if test $got_cross_cc = yes; then + # Test for compiler features for optional tests. We only do this + # for cross compilers because ensuring the docker containers based + # compilers is a requirememt for adding a new test that needs a + # compiler feature. - if test $got_cross_cc = no && test "$container" != no && test -n "$container_image"; then + case $target in + aarch64-*) + if do_compiler "$target_compiler" $target_compiler_cflags \ + -march=armv8.1-a+sve -o $TMPE $TMPC; then + echo "CROSS_CC_HAS_SVE=y" >> $config_target_mak + fi + if do_compiler "$target_compiler" $target_compiler_cflags \ + -march=armv8.3-a -o $TMPE $TMPC; then + echo "CROSS_CC_HAS_ARMV8_3=y" >> $config_target_mak + fi + if do_compiler "$target_compiler" $target_compiler_cflags \ + -mbranch-protection=standard -o $TMPE $TMPC; then + echo "CROSS_CC_HAS_ARMV8_BTI=y" >> $config_target_mak + fi + if do_compiler "$target_compiler" $target_compiler_cflags \ + -march=armv8.5-a+memtag -o $TMPE $TMPC; then + echo "CROSS_CC_HAS_ARMV8_MTE=y" >> $config_target_mak + fi + ;; + ppc*) + if do_compiler "$target_compiler" $target_compiler_cflags \ + -mpower8-vector -o $TMPE $TMPC; then + echo "CROSS_CC_HAS_POWER8_VECTOR=y" >> $config_target_mak + fi + if do_compiler "$target_compiler" $target_compiler_cflags \ + -mpower10 -o $TMPE $TMPC; then + echo "CROSS_CC_HAS_POWER10=y" >> $config_target_mak + fi + ;; + i386-linux-user) + if do_compiler "$target_compiler" $target_compiler_cflags \ + -Werror -fno-pie -o $TMPE $TMPC; then + echo "CROSS_CC_HAS_I386_NOPIE=y" >> $config_target_mak + fi + ;; + esac + elif test $got_cross_cc = no && test "$container" != no && \ + test -n "$container_image"; then for host in $container_hosts; do if test "$host" = "$ARCH"; then echo "DOCKER_IMAGE=$container_image" >> $config_target_mak - echo "DOCKER_CROSS_CC_GUEST=$container_cross_cc" >> $config_target_mak + echo "DOCKER_CROSS_CC_GUEST=$container_cross_cc" >> \ + $config_target_mak + if test -n "$container_cross_as"; then + echo "DOCKER_CROSS_AS_GUEST=$container_cross_as" >> \ + $config_target_mak + fi + if test -n "$container_cross_ld"; then + echo "DOCKER_CROSS_LD_GUEST=$container_cross_ld" >> \ + $config_target_mak + fi fi done fi diff --git a/tests/tcg/lm32/Makefile b/tests/tcg/lm32/Makefile deleted file mode 100644 index 57e7363b2c..0000000000 --- a/tests/tcg/lm32/Makefile +++ /dev/null @@ -1,106 +0,0 @@ --include ../../../config-host.mak - -CROSS=lm32-elf- - -SIM = qemu-system-lm32 -SIMFLAGS = -M lm32-evr -nographic -semihosting -net none -kernel - -CC = $(CROSS)gcc -AS = $(CROSS)as -AS = $(CC) -x assembler -SIZE = $(CROSS)size -LD = $(CC) -OBJCOPY = $(CROSS)objcopy - -TSRC_PATH = $(SRC_PATH)/tests/tcg/lm32 - -LDFLAGS = -T$(TSRC_PATH)/linker.ld -ASFLAGS += -Wa,-I,$(TSRC_PATH)/ - -CRT = crt.o -HELPER = helper.o -TESTCASES += test_add.tst -TESTCASES += test_addi.tst -TESTCASES += test_and.tst -TESTCASES += test_andhi.tst -TESTCASES += test_andi.tst -TESTCASES += test_b.tst -TESTCASES += test_be.tst -TESTCASES += test_bg.tst -TESTCASES += test_bge.tst -TESTCASES += test_bgeu.tst -TESTCASES += test_bgu.tst -TESTCASES += test_bi.tst -TESTCASES += test_bne.tst -TESTCASES += test_break.tst -TESTCASES += test_bret.tst -TESTCASES += test_call.tst -TESTCASES += test_calli.tst -TESTCASES += test_cmpe.tst -TESTCASES += test_cmpei.tst -TESTCASES += test_cmpg.tst -TESTCASES += test_cmpgi.tst -TESTCASES += test_cmpge.tst -TESTCASES += test_cmpgei.tst -TESTCASES += test_cmpgeu.tst -TESTCASES += test_cmpgeui.tst -TESTCASES += test_cmpgu.tst -TESTCASES += test_cmpgui.tst -TESTCASES += test_cmpne.tst -TESTCASES += test_cmpnei.tst -TESTCASES += test_divu.tst -TESTCASES += test_eret.tst -TESTCASES += test_lb.tst -TESTCASES += test_lbu.tst -TESTCASES += test_lh.tst -TESTCASES += test_lhu.tst -TESTCASES += test_lw.tst -TESTCASES += test_modu.tst -TESTCASES += test_mul.tst -TESTCASES += test_muli.tst -TESTCASES += test_nor.tst -TESTCASES += test_nori.tst -TESTCASES += test_or.tst -TESTCASES += test_ori.tst -TESTCASES += test_orhi.tst -#TESTCASES += test_rcsr.tst -TESTCASES += test_ret.tst -TESTCASES += test_sb.tst -TESTCASES += test_scall.tst -TESTCASES += test_sextb.tst -TESTCASES += test_sexth.tst -TESTCASES += test_sh.tst -TESTCASES += test_sl.tst -TESTCASES += test_sli.tst -TESTCASES += test_sr.tst -TESTCASES += test_sri.tst -TESTCASES += test_sru.tst -TESTCASES += test_srui.tst -TESTCASES += test_sub.tst -TESTCASES += test_sw.tst -#TESTCASES += test_wcsr.tst -TESTCASES += test_xnor.tst -TESTCASES += test_xnori.tst -TESTCASES += test_xor.tst -TESTCASES += test_xori.tst - -all: build - -%.o: $(TSRC_PATH)/%.c - $(CC) $(CFLAGS) -c $< -o $@ - -%.o: $(TSRC_PATH)/%.S - $(AS) $(ASFLAGS) -c $< -o $@ - -%.tst: %.o $(TSRC_PATH)/macros.inc $(CRT) $(HELPER) - $(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $(HELPER) $< -o $@ - -build: $(TESTCASES) - -check: $(TESTCASES:test_%.tst=check_%) - -check_%: test_%.tst - @$(SIM) $(SIMFLAGS) $< - -clean: - $(RM) -fr $(TESTCASES) $(CRT) $(HELPER) diff --git a/tests/tcg/lm32/crt.S b/tests/tcg/lm32/crt.S deleted file mode 100644 index fc437a3de1..0000000000 --- a/tests/tcg/lm32/crt.S +++ /dev/null @@ -1,84 +0,0 @@ -.text -.global _start - -_start: -_reset_handler: - xor r0, r0, r0 - mvhi r1, hi(_start) - ori r1, r1, lo(_start) - wcsr eba, r1 - wcsr deba, r1 - mvhi sp, hi(_fstack) - ori sp, sp, lo(_fstack) - bi _main - -_breakpoint_handler: - ori r25, r25, 1 - addi ra, ba, 4 - ret - nop - nop - nop - nop - nop - -_instruction_bus_error_handler: - ori r25, r25, 2 - addi ra, ea, 4 - ret - nop - nop - nop - nop - nop - -_watchpoint_handler: - ori r25, r25, 4 - addi ra, ba, 4 - ret - nop - nop - nop - nop - nop - -_data_bus_error_handler: - ori r25, r25, 8 - addi ra, ea, 4 - ret - nop - nop - nop - nop - nop - -_divide_by_zero_handler: - ori r25, r25, 16 - addi ra, ea, 4 - ret - nop - nop - nop - nop - nop - -_interrupt_handler: - ori r25, r25, 32 - addi ra, ea, 4 - ret - nop - nop - nop - nop - nop - -_system_call_handler: - ori r25, r25, 64 - addi ra, ea, 4 - ret - nop - nop - nop - nop - nop - diff --git a/tests/tcg/lm32/helper.S b/tests/tcg/lm32/helper.S deleted file mode 100644 index 3351d41e84..0000000000 --- a/tests/tcg/lm32/helper.S +++ /dev/null @@ -1,65 +0,0 @@ -.text -.global _start, _write, _exit -.global _tc_fail, _tc_pass - -_write: - addi sp, sp, -4 - sw (sp+4), r8 - mvi r8, 5 - scall - lw r8, (sp+4) - addi sp, sp, 4 - ret - -_exit: - mvi r8, 1 - scall -1: - bi 1b - -_tc_pass: -.data -1: - .ascii "OK\n" -2: -.text - addi sp, sp, -16 - sw (sp+4), ra - sw (sp+8), r1 - sw (sp+12), r2 - sw (sp+16), r3 - mvi r1, 1 - mvhi r2, hi(1b) - ori r2, r2, lo(1b) - mvi r3, (2b - 1b) - calli _write - lw r3, (sp+16) - lw r2, (sp+12) - lw r1, (sp+8) - lw ra, (sp+4) - addi sp, sp, 16 - ret - -_tc_fail: -.data -1: - .ascii "FAILED\n" -2: -.text - addi sp, sp, -16 - sw (sp+4), ra - sw (sp+8), r1 - sw (sp+12), r2 - sw (sp+16), r3 - sw (sp+4), ra - mvi r1, 1 - mvhi r2, hi(1b) - ori r2, r2, lo(1b) - mvi r3, (2b - 1b) - calli _write - lw r3, (sp+16) - lw r2, (sp+12) - lw r1, (sp+8) - lw ra, (sp+4) - addi sp, sp, 16 - ret diff --git a/tests/tcg/lm32/linker.ld b/tests/tcg/lm32/linker.ld deleted file mode 100644 index 52d43a4c74..0000000000 --- a/tests/tcg/lm32/linker.ld +++ /dev/null @@ -1,55 +0,0 @@ -OUTPUT_FORMAT("elf32-lm32") -ENTRY(_start) - -__DYNAMIC = 0; - -MEMORY { - ram : ORIGIN = 0x08000000, LENGTH = 0x04000000 /* 64M */ -} - -SECTIONS -{ - .text : - { - _ftext = .; - *(.text .stub .text.* .gnu.linkonce.t.*) - _etext = .; - } > ram - - .rodata : - { - . = ALIGN(4); - _frodata = .; - *(.rodata .rodata.* .gnu.linkonce.r.*) - *(.rodata1) - _erodata = .; - } > ram - - .data : - { - . = ALIGN(4); - _fdata = .; - *(.data .data.* .gnu.linkonce.d.*) - *(.data1) - _gp = ALIGN(16); - *(.sdata .sdata.* .gnu.linkonce.s.*) - _edata = .; - } > ram - - .bss : - { - . = ALIGN(4); - _fbss = .; - *(.dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - _ebss = .; - _end = .; - } > ram -} - -PROVIDE(_fstack = ORIGIN(ram) + LENGTH(ram) - 4); - diff --git a/tests/tcg/lm32/macros.inc b/tests/tcg/lm32/macros.inc deleted file mode 100644 index 360ad53c9f..0000000000 --- a/tests/tcg/lm32/macros.inc +++ /dev/null @@ -1,90 +0,0 @@ - -.equ MAX_TESTNAME_LEN, 32 -.macro test_name name - .data -tn_\name: - .ascii "\name" - .space MAX_TESTNAME_LEN - (. - tn_\name), ' ' - .text - .global \name -\name: - addi sp, sp, -12 - sw (sp+4), r1 - sw (sp+8), r2 - sw (sp+12), r3 - mvi r1, 1 - mvhi r2, hi(tn_\name) - ori r2, r2, lo(tn_\name) - mvi r3, MAX_TESTNAME_LEN - calli _write - lw r3, (sp+12) - lw r2, (sp+8) - lw r1, (sp+4) - addi sp, sp, 12 -.endm - -.macro load reg val - mvhi \reg, hi(\val) - ori \reg, \reg, lo(\val) -.endm - -.macro tc_pass - calli _tc_pass -.endm - -.macro tc_fail - addi r12, r12, 1 - calli _tc_fail -.endm - -.macro check_r3 val - mvhi r13, hi(\val) - ori r13, r13, lo(\val) - be r3, r13, 1f - tc_fail - bi 2f -1: - tc_pass -2: -.endm - -.macro check_mem adr val - mvhi r13, hi(\adr) - ori r13, r13, lo(\adr) - mvhi r14, hi(\val) - ori r14, r14, lo(\val) - lw r13, (r13+0) - be r13, r14, 1f - tc_fail - bi 2f -1: - tc_pass -2: -.endm - -.macro check_excp excp - andi r13, r25, \excp - bne r13, r0, 1f - tc_fail - bi 2f -1: - tc_pass -2: -.endm - -.macro start - .global _main - .text -_main: - mvi r12, 0 -.endm - -.macro end - mv r1, r12 - calli _exit -.endm - -# base + -# 0 ctrl -# 4 pass/fail -# 8 ptr to test name diff --git a/tests/tcg/lm32/test_add.S b/tests/tcg/lm32/test_add.S deleted file mode 100644 index 030ad197bb..0000000000 --- a/tests/tcg/lm32/test_add.S +++ /dev/null @@ -1,75 +0,0 @@ -.include "macros.inc" - -start - -test_name ADD_1 -mvi r1, 0 -mvi r2, 0 -add r3, r1, r2 -check_r3 0 - -test_name ADD_2 -mvi r1, 0 -mvi r2, 1 -add r3, r1, r2 -check_r3 1 - -test_name ADD_3 -mvi r1, 1 -mvi r2, 0 -add r3, r1, r2 -check_r3 1 - -test_name ADD_4 -mvi r1, 1 -mvi r2, -1 -add r3, r1, r2 -check_r3 0 - -test_name ADD_5 -mvi r1, -1 -mvi r2, 1 -add r3, r1, r2 -check_r3 0 - -test_name ADD_6 -mvi r1, -1 -mvi r2, 0 -add r3, r1, r2 -check_r3 -1 - -test_name ADD_7 -mvi r1, 0 -mvi r2, -1 -add r3, r1, r2 -check_r3 -1 - -test_name ADD_8 -mvi r3, 2 -add r3, r3, r3 -check_r3 4 - -test_name ADD_9 -mvi r1, 4 -mvi r3, 2 -add r3, r1, r3 -check_r3 6 - -test_name ADD_10 -mvi r1, 4 -mvi r3, 2 -add r3, r3, r1 -check_r3 6 - -test_name ADD_11 -mvi r1, 4 -add r3, r1, r1 -check_r3 8 - -test_name ADD_12 -load r1 0x12345678 -load r2 0xabcdef97 -add r3, r1, r2 -check_r3 0xbe02460f - -end diff --git a/tests/tcg/lm32/test_addi.S b/tests/tcg/lm32/test_addi.S deleted file mode 100644 index 68e766d1e5..0000000000 --- a/tests/tcg/lm32/test_addi.S +++ /dev/null @@ -1,56 +0,0 @@ -.include "macros.inc" - -start - -test_name ADDI_1 -mvi r1, 0 -addi r3, r1, 0 -check_r3 0 - -test_name ADDI_2 -mvi r1, 0 -addi r3, r1, 1 -check_r3 1 - -test_name ADDI_3 -mvi r1, 1 -addi r3, r1, 0 -check_r3 1 - -test_name ADDI_4 -mvi r1, 1 -addi r3, r1, -1 -check_r3 0 - -test_name ADDI_5 -mvi r1, -1 -addi r3, r1, 1 -check_r3 0 - -test_name ADDI_6 -mvi r1, -1 -addi r3, r1, 0 -check_r3 -1 - -test_name ADDI_7 -mvi r1, 0 -addi r3, r1, -1 -check_r3 -1 - -test_name ADDI_8 -mvi r3, 4 -addi r3, r3, 4 -check_r3 8 - -test_name ADDI_9 -mvi r3, 4 -addi r3, r3, -4 -check_r3 0 - -test_name ADDI_10 -mvi r3, 4 -addi r3, r3, -5 -check_r3 -1 - -end - diff --git a/tests/tcg/lm32/test_and.S b/tests/tcg/lm32/test_and.S deleted file mode 100644 index 80962ce7a2..0000000000 --- a/tests/tcg/lm32/test_and.S +++ /dev/null @@ -1,45 +0,0 @@ -.include "macros.inc" - -start - -test_name AND_1 -mvi r1, 0 -mvi r2, 0 -and r3, r1, r2 -check_r3 0 - -test_name AND_2 -mvi r1, 0 -mvi r2, 1 -and r3, r1, r2 -check_r3 0 - -test_name AND_3 -mvi r1, 1 -mvi r2, 1 -and r3, r1, r2 -check_r3 1 - -test_name AND_4 -mvi r3, 7 -and r3, r3, r3 -check_r3 7 - -test_name AND_5 -mvi r1, 7 -and r3, r1, r1 -check_r3 7 - -test_name AND_6 -mvi r1, 7 -mvi r3, 0 -and r3, r1, r3 -check_r3 0 - -test_name AND_7 -load r1 0xaa55aa55 -load r2 0x55aa55aa -and r3, r1, r2 -check_r3 0 - -end diff --git a/tests/tcg/lm32/test_andhi.S b/tests/tcg/lm32/test_andhi.S deleted file mode 100644 index 4f73af550b..0000000000 --- a/tests/tcg/lm32/test_andhi.S +++ /dev/null @@ -1,35 +0,0 @@ -.include "macros.inc" - -start - -test_name ANDHI_1 -mvi r1, 0 -andhi r3, r1, 0 -check_r3 0 - -test_name ANDHI_2 -mvi r1, 1 -andhi r3, r1, 1 -check_r3 0 - -test_name ANDHI_3 -load r1 0x000f0000 -andhi r3, r1, 1 -check_r3 0x00010000 - -test_name ANDHI_4 -load r1 0xffffffff -andhi r3, r1, 0xffff -check_r3 0xffff0000 - -test_name ANDHI_5 -load r1 0xffffffff -andhi r3, r1, 0 -check_r3 0 - -test_name ANDHI_6 -load r3 0x55aaffff -andhi r3, r3, 0xaaaa -check_r3 0x00aa0000 - -end diff --git a/tests/tcg/lm32/test_andi.S b/tests/tcg/lm32/test_andi.S deleted file mode 100644 index da1b0a32f7..0000000000 --- a/tests/tcg/lm32/test_andi.S +++ /dev/null @@ -1,35 +0,0 @@ -.include "macros.inc" - -start - -test_name ANDI_1 -mvi r1, 0 -andi r3, r1, 0 -check_r3 0 - -test_name ANDI_2 -mvi r1, 1 -andi r3, r1, 1 -check_r3 1 - -test_name ANDI_3 -load r1 0x000f0000 -andi r3, r1, 1 -check_r3 0 - -test_name ANDI_4 -load r1 0xffffffff -andi r3, r1, 0xffff -check_r3 0xffff - -test_name ANDI_5 -load r1 0xffffffff -andi r3, r1, 0 -check_r3 0 - -test_name ANDI_6 -load r3 0xffff55aa -andi r3, r3, 0xaaaa -check_r3 0x000000aa - -end diff --git a/tests/tcg/lm32/test_b.S b/tests/tcg/lm32/test_b.S deleted file mode 100644 index 98172d8a95..0000000000 --- a/tests/tcg/lm32/test_b.S +++ /dev/null @@ -1,13 +0,0 @@ -.include "macros.inc" - -start - -test_name B_1 -load r1 jump -b r1 -tc_fail -end - -jump: -tc_pass -end diff --git a/tests/tcg/lm32/test_be.S b/tests/tcg/lm32/test_be.S deleted file mode 100644 index 635cabacad..0000000000 --- a/tests/tcg/lm32/test_be.S +++ /dev/null @@ -1,48 +0,0 @@ -.include "macros.inc" - -start - -test_name BE_1 -mvi r1, 0 -mvi r2, 0 -be r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BE_2 -mvi r1, 1 -mvi r2, 0 -be r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BE_3 -mvi r1, 0 -mvi r2, 1 -be r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -bi 2f -1: -tc_pass -bi 3f -2: -test_name BE_4 -mvi r1, 1 -mvi r2, 1 -be r1, r2, 1b -tc_fail -3: - -end - diff --git a/tests/tcg/lm32/test_bg.S b/tests/tcg/lm32/test_bg.S deleted file mode 100644 index 81823c2304..0000000000 --- a/tests/tcg/lm32/test_bg.S +++ /dev/null @@ -1,78 +0,0 @@ -.include "macros.inc" - -start - -test_name BG_1 -mvi r1, 0 -mvi r2, 0 -bg r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BG_2 -mvi r1, 1 -mvi r2, 0 -bg r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BG_3 -mvi r1, 0 -mvi r2, 1 -bg r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BG_4 -mvi r1, 0 -mvi r2, -1 -bg r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BG_5 -mvi r1, -1 -mvi r2, 0 -bg r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BG_6 -mvi r1, -1 -mvi r2, -1 -bg r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -bi 2f -1: -tc_pass -bi 3f -2: -test_name BG_7 -mvi r1, 1 -mvi r2, 0 -bg r1, r2, 1b -tc_fail -3: - -end - diff --git a/tests/tcg/lm32/test_bge.S b/tests/tcg/lm32/test_bge.S deleted file mode 100644 index 6684d15a55..0000000000 --- a/tests/tcg/lm32/test_bge.S +++ /dev/null @@ -1,78 +0,0 @@ -.include "macros.inc" - -start - -test_name BGE_1 -mvi r1, 0 -mvi r2, 0 -bge r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BGE_2 -mvi r1, 1 -mvi r2, 0 -bge r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BGE_3 -mvi r1, 0 -mvi r2, 1 -bge r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BGE_4 -mvi r1, 0 -mvi r2, -1 -bge r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BGE_5 -mvi r1, -1 -mvi r2, 0 -bge r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BGE_6 -mvi r1, -1 -mvi r2, -1 -bge r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -bi 2f -1: -tc_pass -bi 3f -2: -test_name BGE_7 -mvi r1, 1 -mvi r2, 0 -bge r1, r2, 1b -tc_fail -3: - -end - diff --git a/tests/tcg/lm32/test_bgeu.S b/tests/tcg/lm32/test_bgeu.S deleted file mode 100644 index be440308fd..0000000000 --- a/tests/tcg/lm32/test_bgeu.S +++ /dev/null @@ -1,78 +0,0 @@ -.include "macros.inc" - -start - -test_name BGEU_1 -mvi r1, 0 -mvi r2, 0 -bgeu r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BGEU_2 -mvi r1, 1 -mvi r2, 0 -bgeu r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BGEU_3 -mvi r1, 0 -mvi r2, 1 -bgeu r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BGEU_4 -mvi r1, 0 -mvi r2, -1 -bgeu r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BGEU_5 -mvi r1, -1 -mvi r2, 0 -bgeu r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BGEU_6 -mvi r1, -1 -mvi r2, -1 -bgeu r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -bi 2f -1: -tc_pass -bi 3f -2: -test_name BGEU_7 -mvi r1, 1 -mvi r2, 0 -bgeu r1, r2, 1b -tc_fail -3: - -end - diff --git a/tests/tcg/lm32/test_bgu.S b/tests/tcg/lm32/test_bgu.S deleted file mode 100644 index 8cc695b310..0000000000 --- a/tests/tcg/lm32/test_bgu.S +++ /dev/null @@ -1,78 +0,0 @@ -.include "macros.inc" - -start - -test_name BGU_1 -mvi r1, 0 -mvi r2, 0 -bgu r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BGU_2 -mvi r1, 1 -mvi r2, 0 -bgu r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BGU_3 -mvi r1, 0 -mvi r2, 1 -bgu r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BGU_4 -mvi r1, 0 -mvi r2, -1 -bgu r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BGU_5 -mvi r1, -1 -mvi r2, 0 -bgu r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BGU_6 -mvi r1, -1 -mvi r2, -1 -bgu r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -bi 2f -1: -tc_pass -bi 3f -2: -test_name BGU_7 -mvi r1, 1 -mvi r2, 0 -bgu r1, r2, 1b -tc_fail -3: - -end - diff --git a/tests/tcg/lm32/test_bi.S b/tests/tcg/lm32/test_bi.S deleted file mode 100644 index a1fbd6fc07..0000000000 --- a/tests/tcg/lm32/test_bi.S +++ /dev/null @@ -1,23 +0,0 @@ -.include "macros.inc" - -start - -test_name BI_1 -bi jump -tc_fail -end - -jump_back: -tc_pass -end - -jump: -tc_pass - -test_name BI_2 -bi jump_back -tc_fail - -end - - diff --git a/tests/tcg/lm32/test_bne.S b/tests/tcg/lm32/test_bne.S deleted file mode 100644 index 871a006755..0000000000 --- a/tests/tcg/lm32/test_bne.S +++ /dev/null @@ -1,48 +0,0 @@ -.include "macros.inc" - -start - -test_name BNE_1 -mvi r1, 0 -mvi r2, 0 -bne r1, r2, 1f -tc_pass -bi 2f -1: -tc_fail -2: - -test_name BNE_2 -mvi r1, 1 -mvi r2, 0 -bne r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -test_name BNE_3 -mvi r1, 0 -mvi r2, 1 -bne r1, r2, 1f -tc_fail -bi 2f -1: -tc_pass -2: - -bi 2f -1: -tc_fail -bi 3f -2: -test_name BNE_4 -mvi r1, 1 -mvi r2, 1 -bne r1, r2, 1b -tc_pass -3: - -end - diff --git a/tests/tcg/lm32/test_break.S b/tests/tcg/lm32/test_break.S deleted file mode 100644 index 0384fc6128..0000000000 --- a/tests/tcg/lm32/test_break.S +++ /dev/null @@ -1,20 +0,0 @@ -.include "macros.inc" - -start - -test_name BREAK_1 -mvi r1, 1 -wcsr IE, r1 -insn: -break -check_excp 1 - -test_name BREAK_2 -mv r3, ba -check_r3 insn - -test_name BREAK_3 -rcsr r3, IE -check_r3 4 - -end diff --git a/tests/tcg/lm32/test_bret.S b/tests/tcg/lm32/test_bret.S deleted file mode 100644 index 645210e434..0000000000 --- a/tests/tcg/lm32/test_bret.S +++ /dev/null @@ -1,38 +0,0 @@ -.include "macros.inc" - -start - -test_name BRET_1 -mvi r1, 4 -wcsr IE, r1 -load ba mark -bret -tc_fail -bi 1f - -mark: -tc_pass - -1: -test_name BRET_2 -rcsr r3, IE -check_r3 5 - -test_name BRET_3 -mvi r1, 0 -wcsr IE, r1 -load ba mark2 -bret -tc_fail -bi 1f - -mark2: -tc_pass - -1: -test_name BRET_4 -rcsr r3, IE -check_r3 0 - -end - diff --git a/tests/tcg/lm32/test_call.S b/tests/tcg/lm32/test_call.S deleted file mode 100644 index 1b91a5f2be..0000000000 --- a/tests/tcg/lm32/test_call.S +++ /dev/null @@ -1,16 +0,0 @@ -.include "macros.inc" - -start - -test_name CALL_1 -load r1 mark -call r1 -return: - -tc_fail -end - -mark: -mv r3, ra -check_r3 return -end diff --git a/tests/tcg/lm32/test_calli.S b/tests/tcg/lm32/test_calli.S deleted file mode 100644 index 1d87ae6e21..0000000000 --- a/tests/tcg/lm32/test_calli.S +++ /dev/null @@ -1,15 +0,0 @@ -.include "macros.inc" - -start - -test_name CALLI_1 -calli mark -return: - -tc_fail -end - -mark: -mv r3, ra -check_r3 return -end diff --git a/tests/tcg/lm32/test_cmpe.S b/tests/tcg/lm32/test_cmpe.S deleted file mode 100644 index 60a885500b..0000000000 --- a/tests/tcg/lm32/test_cmpe.S +++ /dev/null @@ -1,40 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPE_1 -mvi r1, 0 -mvi r2, 0 -cmpe r3, r1, r2 -check_r3 1 - -test_name CMPE_2 -mvi r1, 0 -mvi r2, 1 -cmpe r3, r1, r2 -check_r3 0 - -test_name CMPE_3 -mvi r1, 1 -mvi r2, 0 -cmpe r3, r1, r2 -check_r3 0 - -test_name CMPE_4 -mvi r3, 0 -mvi r2, 1 -cmpe r3, r3, r2 -check_r3 0 - -test_name CMPE_5 -mvi r3, 0 -mvi r2, 0 -cmpe r3, r3, r2 -check_r3 1 - -test_name CMPE_6 -mvi r3, 0 -cmpe r3, r3, r3 -check_r3 1 - -end diff --git a/tests/tcg/lm32/test_cmpei.S b/tests/tcg/lm32/test_cmpei.S deleted file mode 100644 index c3d3566ad3..0000000000 --- a/tests/tcg/lm32/test_cmpei.S +++ /dev/null @@ -1,35 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPEI_1 -mvi r1, 0 -cmpei r3, r1, 0 -check_r3 1 - -test_name CMPEI_2 -mvi r1, 0 -cmpei r3, r1, 1 -check_r3 0 - -test_name CMPEI_3 -mvi r1, 1 -cmpei r3, r1, 0 -check_r3 0 - -test_name CMPEI_4 -load r1 0xffffffff -cmpei r3, r1, -1 -check_r3 1 - -test_name CMPEI_5 -mvi r3, 0 -cmpei r3, r3, 0 -check_r3 1 - -test_name CMPEI_6 -mvi r3, 0 -cmpei r3, r3, 1 -check_r3 0 - -end diff --git a/tests/tcg/lm32/test_cmpg.S b/tests/tcg/lm32/test_cmpg.S deleted file mode 100644 index 012407874c..0000000000 --- a/tests/tcg/lm32/test_cmpg.S +++ /dev/null @@ -1,64 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPG_1 -mvi r1, 0 -mvi r2, 0 -cmpg r3, r1, r2 -check_r3 0 - -test_name CMPG_2 -mvi r1, 0 -mvi r2, 1 -cmpg r3, r1, r2 -check_r3 0 - -test_name CMPG_3 -mvi r1, 1 -mvi r2, 0 -cmpg r3, r1, r2 -check_r3 1 - -test_name CMPG_4 -mvi r1, 1 -mvi r2, 1 -cmpg r3, r1, r2 -check_r3 0 - -test_name CMPG_5 -mvi r1, 0 -mvi r2, -1 -cmpg r3, r1, r2 -check_r3 1 - -test_name CMPG_6 -mvi r1, -1 -mvi r2, 0 -cmpg r3, r1, r2 -check_r3 0 - -test_name CMPG_7 -mvi r1, -1 -mvi r2, -1 -cmpg r3, r1, r2 -check_r3 0 - -test_name CMPG_8 -mvi r3, 0 -mvi r2, 1 -cmpg r3, r3, r2 -check_r3 0 - -test_name CMPG_9 -mvi r3, 1 -mvi r2, 0 -cmpg r3, r3, r2 -check_r3 1 - -test_name CMPG_10 -mvi r3, 0 -cmpg r3, r3, r3 -check_r3 0 - -end diff --git a/tests/tcg/lm32/test_cmpge.S b/tests/tcg/lm32/test_cmpge.S deleted file mode 100644 index 84620a00e3..0000000000 --- a/tests/tcg/lm32/test_cmpge.S +++ /dev/null @@ -1,64 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPGE_1 -mvi r1, 0 -mvi r2, 0 -cmpge r3, r1, r2 -check_r3 1 - -test_name CMPGE_2 -mvi r1, 0 -mvi r2, 1 -cmpge r3, r1, r2 -check_r3 0 - -test_name CMPGE_3 -mvi r1, 1 -mvi r2, 0 -cmpge r3, r1, r2 -check_r3 1 - -test_name CMPGE_4 -mvi r1, 1 -mvi r2, 1 -cmpge r3, r1, r2 -check_r3 1 - -test_name CMPGE_5 -mvi r1, 0 -mvi r2, -1 -cmpge r3, r1, r2 -check_r3 1 - -test_name CMPGE_6 -mvi r1, -1 -mvi r2, 0 -cmpge r3, r1, r2 -check_r3 0 - -test_name CMPGE_7 -mvi r1, -1 -mvi r2, -1 -cmpge r3, r1, r2 -check_r3 1 - -test_name CMPGE_8 -mvi r3, 0 -mvi r2, 1 -cmpge r3, r3, r2 -check_r3 0 - -test_name CMPGE_9 -mvi r3, 1 -mvi r2, 0 -cmpge r3, r3, r2 -check_r3 1 - -test_name CMPGE_10 -mvi r3, 0 -cmpge r3, r3, r3 -check_r3 1 - -end diff --git a/tests/tcg/lm32/test_cmpgei.S b/tests/tcg/lm32/test_cmpgei.S deleted file mode 100644 index 6e388a2a35..0000000000 --- a/tests/tcg/lm32/test_cmpgei.S +++ /dev/null @@ -1,70 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPGEI_1 -mvi r1, 0 -cmpgei r3, r1, 0 -check_r3 1 - -test_name CMPGEI_2 -mvi r1, 0 -cmpgei r3, r1, 1 -check_r3 0 - -test_name CMPGEI_3 -mvi r1, 1 -cmpgei r3, r1, 0 -check_r3 1 - -test_name CMPGEI_4 -mvi r1, 1 -cmpgei r3, r1, 1 -check_r3 1 - -test_name CMPGEI_5 -mvi r1, 0 -cmpgei r3, r1, -1 -check_r3 1 - -test_name CMPGEI_6 -mvi r1, -1 -cmpgei r3, r1, 0 -check_r3 0 - -test_name CMPGEI_7 -mvi r1, -1 -cmpgei r3, r1, -1 -check_r3 1 - -test_name CMPGEI_8 -mvi r3, 0 -cmpgei r3, r3, 1 -check_r3 0 - -test_name CMPGEI_9 -mvi r3, 1 -cmpgei r3, r3, 0 -check_r3 1 - -test_name CMPGEI_10 -mvi r3, 0 -cmpgei r3, r3, 0 -check_r3 1 - -test_name CMPGEI_11 -mvi r1, 0 -cmpgei r3, r1, -32768 -check_r3 1 - -test_name CMPGEI_12 -mvi r1, -1 -cmpgei r3, r1, -32768 -check_r3 1 - -test_name CMPGEI_13 -mvi r1, -32768 -cmpgei r3, r1, -32768 -check_r3 1 - -end diff --git a/tests/tcg/lm32/test_cmpgeu.S b/tests/tcg/lm32/test_cmpgeu.S deleted file mode 100644 index 2110ccb6b7..0000000000 --- a/tests/tcg/lm32/test_cmpgeu.S +++ /dev/null @@ -1,64 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPGEU_1 -mvi r1, 0 -mvi r2, 0 -cmpgeu r3, r1, r2 -check_r3 1 - -test_name CMPGEU_2 -mvi r1, 0 -mvi r2, 1 -cmpgeu r3, r1, r2 -check_r3 0 - -test_name CMPGEU_3 -mvi r1, 1 -mvi r2, 0 -cmpgeu r3, r1, r2 -check_r3 1 - -test_name CMPGEU_4 -mvi r1, 1 -mvi r2, 1 -cmpgeu r3, r1, r2 -check_r3 1 - -test_name CMPGEU_5 -mvi r1, 0 -mvi r2, -1 -cmpgeu r3, r1, r2 -check_r3 0 - -test_name CMPGEU_6 -mvi r1, -1 -mvi r2, 0 -cmpgeu r3, r1, r2 -check_r3 1 - -test_name CMPGEU_7 -mvi r1, -1 -mvi r2, -1 -cmpgeu r3, r1, r2 -check_r3 1 - -test_name CMPGEU_8 -mvi r3, 0 -mvi r2, 1 -cmpgeu r3, r3, r2 -check_r3 0 - -test_name CMPGEU_9 -mvi r3, 1 -mvi r2, 0 -cmpgeu r3, r3, r2 -check_r3 1 - -test_name CMPGEU_10 -mvi r3, 0 -cmpgeu r3, r3, r3 -check_r3 1 - -end diff --git a/tests/tcg/lm32/test_cmpgeui.S b/tests/tcg/lm32/test_cmpgeui.S deleted file mode 100644 index 3866d96cb7..0000000000 --- a/tests/tcg/lm32/test_cmpgeui.S +++ /dev/null @@ -1,70 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPGEUI_1 -mvi r1, 0 -cmpgeui r3, r1, 0 -check_r3 1 - -test_name CMPGEUI_2 -mvi r1, 0 -cmpgeui r3, r1, 1 -check_r3 0 - -test_name CMPGEUI_3 -mvi r1, 1 -cmpgeui r3, r1, 0 -check_r3 1 - -test_name CMPGEUI_4 -mvi r1, 1 -cmpgeui r3, r1, 1 -check_r3 1 - -test_name CMPGEUI_5 -mvi r1, 0 -cmpgeui r3, r1, 0xffff -check_r3 0 - -test_name CMPGEUI_6 -mvi r1, -1 -cmpgeui r3, r1, 0 -check_r3 1 - -test_name CMPGEUI_7 -mvi r1, -1 -cmpgeui r3, r1, 0xffff -check_r3 1 - -test_name CMPGEUI_8 -mvi r3, 0 -cmpgeui r3, r3, 1 -check_r3 0 - -test_name CMPGEUI_9 -mvi r3, 1 -cmpgeui r3, r3, 0 -check_r3 1 - -test_name CMPGEUI_10 -mvi r3, 0 -cmpgeui r3, r3, 0 -check_r3 1 - -test_name CMPGEUI_11 -mvi r1, 0 -cmpgeui r3, r1, 0x8000 -check_r3 0 - -test_name CMPGEUI_12 -mvi r1, -1 -cmpgeui r3, r1, 0x8000 -check_r3 1 - -test_name CMPGEUI_13 -ori r1, r0, 0x8000 -cmpgeui r3, r1, 0x8000 -check_r3 1 - -end diff --git a/tests/tcg/lm32/test_cmpgi.S b/tests/tcg/lm32/test_cmpgi.S deleted file mode 100644 index 21695f97ab..0000000000 --- a/tests/tcg/lm32/test_cmpgi.S +++ /dev/null @@ -1,70 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPGI_1 -mvi r1, 0 -cmpgi r3, r1, 0 -check_r3 0 - -test_name CMPGI_2 -mvi r1, 0 -cmpgi r3, r1, 1 -check_r3 0 - -test_name CMPGI_3 -mvi r1, 1 -cmpgi r3, r1, 0 -check_r3 1 - -test_name CMPGI_4 -mvi r1, 1 -cmpgi r3, r1, 1 -check_r3 0 - -test_name CMPGI_5 -mvi r1, 0 -cmpgi r3, r1, -1 -check_r3 1 - -test_name CMPGI_6 -mvi r1, -1 -cmpgi r3, r1, 0 -check_r3 0 - -test_name CMPGI_7 -mvi r1, -1 -cmpgi r3, r1, -1 -check_r3 0 - -test_name CMPGI_8 -mvi r3, 0 -cmpgi r3, r3, 1 -check_r3 0 - -test_name CMPGI_9 -mvi r3, 1 -cmpgi r3, r3, 0 -check_r3 1 - -test_name CMPGI_10 -mvi r3, 0 -cmpgi r3, r3, 0 -check_r3 0 - -test_name CMPGI_11 -mvi r1, 0 -cmpgi r3, r1, -32768 -check_r3 1 - -test_name CMPGI_12 -mvi r1, -1 -cmpgi r3, r1, -32768 -check_r3 1 - -test_name CMPGI_13 -mvi r1, -32768 -cmpgi r3, r1, -32768 -check_r3 0 - -end diff --git a/tests/tcg/lm32/test_cmpgu.S b/tests/tcg/lm32/test_cmpgu.S deleted file mode 100644 index dd465471ea..0000000000 --- a/tests/tcg/lm32/test_cmpgu.S +++ /dev/null @@ -1,64 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPGU_1 -mvi r1, 0 -mvi r2, 0 -cmpgu r3, r1, r2 -check_r3 0 - -test_name CMPGU_2 -mvi r1, 0 -mvi r2, 1 -cmpgu r3, r1, r2 -check_r3 0 - -test_name CMPGU_3 -mvi r1, 1 -mvi r2, 0 -cmpgu r3, r1, r2 -check_r3 1 - -test_name CMPGU_4 -mvi r1, 1 -mvi r2, 1 -cmpgu r3, r1, r2 -check_r3 0 - -test_name CMPGU_5 -mvi r1, 0 -mvi r2, -1 -cmpgu r3, r1, r2 -check_r3 0 - -test_name CMPGU_6 -mvi r1, -1 -mvi r2, 0 -cmpgu r3, r1, r2 -check_r3 1 - -test_name CMPGU_7 -mvi r1, -1 -mvi r2, -1 -cmpgu r3, r1, r2 -check_r3 0 - -test_name CMPGU_8 -mvi r3, 0 -mvi r2, 1 -cmpgu r3, r3, r2 -check_r3 0 - -test_name CMPGU_9 -mvi r3, 1 -mvi r2, 0 -cmpgu r3, r3, r2 -check_r3 1 - -test_name CMPGU_10 -mvi r3, 0 -cmpgu r3, r3, r3 -check_r3 0 - -end diff --git a/tests/tcg/lm32/test_cmpgui.S b/tests/tcg/lm32/test_cmpgui.S deleted file mode 100644 index dd94001492..0000000000 --- a/tests/tcg/lm32/test_cmpgui.S +++ /dev/null @@ -1,70 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPGUI_1 -mvi r1, 0 -cmpgui r3, r1, 0 -check_r3 0 - -test_name CMPGUI_2 -mvi r1, 0 -cmpgui r3, r1, 1 -check_r3 0 - -test_name CMPGUI_3 -mvi r1, 1 -cmpgui r3, r1, 0 -check_r3 1 - -test_name CMPGUI_4 -mvi r1, 1 -cmpgui r3, r1, 1 -check_r3 0 - -test_name CMPGUI_5 -mvi r1, 0 -cmpgui r3, r1, 0xffff -check_r3 0 - -test_name CMPGUI_6 -mvi r1, -1 -cmpgui r3, r1, 0 -check_r3 1 - -test_name CMPGUI_7 -mvi r1, -1 -cmpgui r3, r1, 0xffff -check_r3 1 - -test_name CMPGUI_8 -mvi r3, 0 -cmpgui r3, r3, 1 -check_r3 0 - -test_name CMPGUI_9 -mvi r3, 1 -cmpgui r3, r3, 0 -check_r3 1 - -test_name CMPGUI_10 -mvi r3, 0 -cmpgui r3, r3, 0 -check_r3 0 - -test_name CMPGUI_11 -mvi r1, 0 -cmpgui r3, r1, 0x8000 -check_r3 0 - -test_name CMPGUI_12 -mvi r1, -1 -cmpgui r3, r1, 0x8000 -check_r3 1 - -test_name CMPGUI_13 -ori r1, r0, 0x8000 -cmpgui r3, r1, 0x8000 -check_r3 0 - -end diff --git a/tests/tcg/lm32/test_cmpne.S b/tests/tcg/lm32/test_cmpne.S deleted file mode 100644 index 0f1078114c..0000000000 --- a/tests/tcg/lm32/test_cmpne.S +++ /dev/null @@ -1,40 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPNE_1 -mvi r1, 0 -mvi r2, 0 -cmpne r3, r1, r2 -check_r3 0 - -test_name CMPNE_2 -mvi r1, 0 -mvi r2, 1 -cmpne r3, r1, r2 -check_r3 1 - -test_name CMPNE_3 -mvi r1, 1 -mvi r2, 0 -cmpne r3, r1, r2 -check_r3 1 - -test_name CMPNE_4 -mvi r3, 0 -mvi r2, 1 -cmpne r3, r3, r2 -check_r3 1 - -test_name CMPNE_5 -mvi r3, 0 -mvi r2, 0 -cmpne r3, r3, r2 -check_r3 0 - -test_name CMPNE_6 -mvi r3, 0 -cmpne r3, r3, r3 -check_r3 0 - -end diff --git a/tests/tcg/lm32/test_cmpnei.S b/tests/tcg/lm32/test_cmpnei.S deleted file mode 100644 index 060dd9d394..0000000000 --- a/tests/tcg/lm32/test_cmpnei.S +++ /dev/null @@ -1,35 +0,0 @@ -.include "macros.inc" - -start - -test_name CMPNEI_1 -mvi r1, 0 -cmpnei r3, r1, 0 -check_r3 0 - -test_name CMPNEI_2 -mvi r1, 0 -cmpnei r3, r1, 1 -check_r3 1 - -test_name CMPNEI_3 -mvi r1, 1 -cmpnei r3, r1, 0 -check_r3 1 - -test_name CMPNEI_4 -load r1 0xffffffff -cmpnei r3, r1, -1 -check_r3 0 - -test_name CMPNEI_5 -mvi r3, 0 -cmpnei r3, r3, 0 -check_r3 0 - -test_name CMPNEI_6 -mvi r3, 0 -cmpnei r3, r3, 1 -check_r3 1 - -end diff --git a/tests/tcg/lm32/test_divu.S b/tests/tcg/lm32/test_divu.S deleted file mode 100644 index f381d095c5..0000000000 --- a/tests/tcg/lm32/test_divu.S +++ /dev/null @@ -1,29 +0,0 @@ -.include "macros.inc" - -start - -test_name DIVU_1 -mvi r1, 0 -mvi r2, 1 -divu r3, r1, r2 -check_r3 0 - -test_name DIVU_2 -mvi r1, 1 -mvi r2, 1 -divu r3, r1, r2 -check_r3 1 - -test_name DIVU_3 -mvi r1, 0 -mvi r2, 0 -divu r3, r1, r2 -check_excp 16 - -test_name DIVU_4 -load r1 0xabcdef12 -load r2 0x12345 -divu r3, r1, r2 -check_r3 0x9700 - -end diff --git a/tests/tcg/lm32/test_eret.S b/tests/tcg/lm32/test_eret.S deleted file mode 100644 index 6830bd1abf..0000000000 --- a/tests/tcg/lm32/test_eret.S +++ /dev/null @@ -1,38 +0,0 @@ -.include "macros.inc" - -start - -test_name ERET_1 -mvi r1, 2 -wcsr IE, r1 -load ea mark -eret -tc_fail -bi 1f - -mark: -tc_pass - -1: -test_name ERET_2 -rcsr r3, IE -check_r3 3 - -test_name ERET_3 -mvi r1, 0 -wcsr IE, r1 -load ea mark2 -eret -tc_fail -bi 1f - -mark2: -tc_pass - -1: -test_name ERET_4 -rcsr r3, IE -check_r3 0 - -end - diff --git a/tests/tcg/lm32/test_lb.S b/tests/tcg/lm32/test_lb.S deleted file mode 100644 index d677eea4c4..0000000000 --- a/tests/tcg/lm32/test_lb.S +++ /dev/null @@ -1,49 +0,0 @@ -.include "macros.inc" - -start - -test_name LB_1 -load r1 data -lb r3, (r1+0) -check_r3 0x7e - -test_name LB_2 -load r1 data -lb r3, (r1+1) -check_r3 0x7f - -test_name LB_3 -load r1 data -lb r3, (r1+-1) -check_r3 0x7d - -test_name LB_4 -load r1 data_msb -lb r3, (r1+0) -check_r3 0xfffffffe - -test_name LB_5 -load r1 data_msb -lb r3, (r1+1) -check_r3 0xffffffff - -test_name LB_6 -load r1 data_msb -lb r3, (r1+-1) -check_r3 0xfffffffd - -test_name LB_7 -load r3 data -lb r3, (r3+0) -check_r3 0x7e - -end - -.data - .align 4 - .byte 0x7a, 0x7b, 0x7c, 0x7d -data: - .byte 0x7e, 0x7f, 0x70, 0x71 - .byte 0xfa, 0xfb, 0xfc, 0xfd -data_msb: - .byte 0xfe, 0xff, 0xf0, 0xf1 diff --git a/tests/tcg/lm32/test_lbu.S b/tests/tcg/lm32/test_lbu.S deleted file mode 100644 index dc5d5f67d3..0000000000 --- a/tests/tcg/lm32/test_lbu.S +++ /dev/null @@ -1,49 +0,0 @@ -.include "macros.inc" - -start - -test_name LBU_1 -load r1 data -lbu r3, (r1+0) -check_r3 0x7e - -test_name LBU_2 -load r1 data -lbu r3, (r1+1) -check_r3 0x7f - -test_name LBU_3 -load r1 data -lbu r3, (r1+-1) -check_r3 0x7d - -test_name LBU_4 -load r1 data_msb -lbu r3, (r1+0) -check_r3 0xfe - -test_name LBU_5 -load r1 data_msb -lbu r3, (r1+1) -check_r3 0xff - -test_name LBU_6 -load r1 data_msb -lbu r3, (r1+-1) -check_r3 0xfd - -test_name LBU_7 -load r3 data -lbu r3, (r3+0) -check_r3 0x7e - -end - -.data - .align 4 - .byte 0x7a, 0x7b, 0x7c, 0x7d -data: - .byte 0x7e, 0x7f, 0x70, 0x71 - .byte 0xfa, 0xfb, 0xfc, 0xfd -data_msb: - .byte 0xfe, 0xff, 0xf0, 0xf1 diff --git a/tests/tcg/lm32/test_lh.S b/tests/tcg/lm32/test_lh.S deleted file mode 100644 index 397996bddd..0000000000 --- a/tests/tcg/lm32/test_lh.S +++ /dev/null @@ -1,49 +0,0 @@ -.include "macros.inc" - -start - -test_name LH_1 -load r1 data -lh r3, (r1+0) -check_r3 0x7e7f - -test_name LH_2 -load r1 data -lh r3, (r1+2) -check_r3 0x7071 - -test_name LH_3 -load r1 data -lh r3, (r1+-2) -check_r3 0x7c7d - -test_name LH_4 -load r1 data_msb -lh r3, (r1+0) -check_r3 0xfffffeff - -test_name LH_5 -load r1 data_msb -lh r3, (r1+2) -check_r3 0xfffff0f1 - -test_name LH_6 -load r1 data_msb -lh r3, (r1+-2) -check_r3 0xfffffcfd - -test_name LH_7 -load r3 data -lh r3, (r3+0) -check_r3 0x7e7f - -end - -.data - .align 4 - .byte 0x7a, 0x7b, 0x7c, 0x7d -data: - .byte 0x7e, 0x7f, 0x70, 0x71 - .byte 0xfa, 0xfb, 0xfc, 0xfd -data_msb: - .byte 0xfe, 0xff, 0xf0, 0xf1 diff --git a/tests/tcg/lm32/test_lhu.S b/tests/tcg/lm32/test_lhu.S deleted file mode 100644 index 8de7c52560..0000000000 --- a/tests/tcg/lm32/test_lhu.S +++ /dev/null @@ -1,49 +0,0 @@ -.include "macros.inc" - -start - -test_name LHU_1 -load r1 data -lhu r3, (r1+0) -check_r3 0x7e7f - -test_name LHU_2 -load r1 data -lhu r3, (r1+2) -check_r3 0x7071 - -test_name LHU_3 -load r1 data -lhu r3, (r1+-2) -check_r3 0x7c7d - -test_name LHU_4 -load r1 data_msb -lhu r3, (r1+0) -check_r3 0xfeff - -test_name LHU_5 -load r1 data_msb -lhu r3, (r1+2) -check_r3 0xf0f1 - -test_name LHU_6 -load r1 data_msb -lhu r3, (r1+-2) -check_r3 0xfcfd - -test_name LHU_7 -load r3 data -lhu r3, (r3+0) -check_r3 0x7e7f - -end - -.data - .align 4 - .byte 0x7a, 0x7b, 0x7c, 0x7d -data: - .byte 0x7e, 0x7f, 0x70, 0x71 - .byte 0xfa, 0xfb, 0xfc, 0xfd -data_msb: - .byte 0xfe, 0xff, 0xf0, 0xf1 diff --git a/tests/tcg/lm32/test_lw.S b/tests/tcg/lm32/test_lw.S deleted file mode 100644 index 996e5f8c88..0000000000 --- a/tests/tcg/lm32/test_lw.S +++ /dev/null @@ -1,32 +0,0 @@ -.include "macros.inc" - -start - -test_name LW_1 -load r1 data -lw r3, (r1+0) -check_r3 0x7e7f7071 - -test_name LW_2 -load r1 data -lw r3, (r1+4) -check_r3 0x72737475 - -test_name LW_3 -load r1 data -lw r3, (r1+-4) -check_r3 0x7a7b7c7d - -test_name LW_4 -load r3 data -lw r3, (r3+0) -check_r3 0x7e7f7071 - -end - -.data - .align 4 - .byte 0x7a, 0x7b, 0x7c, 0x7d -data: - .byte 0x7e, 0x7f, 0x70, 0x71 - .byte 0x72, 0x73, 0x74, 0x75 diff --git a/tests/tcg/lm32/test_modu.S b/tests/tcg/lm32/test_modu.S deleted file mode 100644 index 42486900b4..0000000000 --- a/tests/tcg/lm32/test_modu.S +++ /dev/null @@ -1,35 +0,0 @@ -.include "macros.inc" - -start - -test_name MODU_1 -mvi r1, 0 -mvi r2, 1 -modu r3, r1, r2 -check_r3 0 - -test_name MODU_2 -mvi r1, 1 -mvi r2, 1 -modu r3, r1, r2 -check_r3 0 - -test_name MODU_3 -mvi r1, 3 -mvi r2, 2 -modu r3, r1, r2 -check_r3 1 - -test_name MODU_4 -mvi r1, 0 -mvi r2, 0 -modu r3, r1, r2 -check_excp 16 - -test_name MODU_5 -load r1 0xabcdef12 -load r2 0x12345 -modu r3, r1, r2 -check_r3 0x3c12 - -end diff --git a/tests/tcg/lm32/test_mul.S b/tests/tcg/lm32/test_mul.S deleted file mode 100644 index e9b937e648..0000000000 --- a/tests/tcg/lm32/test_mul.S +++ /dev/null @@ -1,70 +0,0 @@ -.include "macros.inc" - -start - -test_name MUL_1 -mvi r1, 0 -mvi r2, 0 -mul r3, r1, r2 -check_r3 0 - -test_name MUL_2 -mvi r1, 1 -mvi r2, 0 -mul r3, r1, r2 -check_r3 0 - -test_name MUL_3 -mvi r1, 0 -mvi r2, 1 -mul r3, r1, r2 -check_r3 0 - -test_name MUL_4 -mvi r1, 1 -mvi r2, 1 -mul r3, r1, r2 -check_r3 1 - -test_name MUL_5 -mvi r1, 2 -mvi r2, -1 -mul r3, r1, r2 -check_r3 -2 - -test_name MUL_6 -mvi r1, -2 -mvi r2, -1 -mul r3, r1, r2 -check_r3 2 - -test_name MUL_7 -mvi r1, 0x1234 -mvi r2, 0x789 -mul r3, r1, r2 -check_r3 0x8929d4 - -test_name MUL_8 -mvi r3, 4 -mul r3, r3, r3 -check_r3 16 - -test_name MUL_9 -mvi r2, 2 -mvi r3, 4 -mul r3, r3, r2 -check_r3 8 - -test_name MUL_10 -load r1 0x12345678 -load r2 0x7bcdef12 -mul r3, r1, r2 -check_r3 0xa801c70 - -test_name MUL_11 -load r1 0x12345678 -load r2 0xabcdef12 -mul r3, r1, r2 -check_r3 0x8a801c70 - -end diff --git a/tests/tcg/lm32/test_muli.S b/tests/tcg/lm32/test_muli.S deleted file mode 100644 index d6dd4a0f7e..0000000000 --- a/tests/tcg/lm32/test_muli.S +++ /dev/null @@ -1,45 +0,0 @@ -.include "macros.inc" - -start - -test_name MULI_1 -mvi r1, 0 -muli r3, r1, 0 -check_r3 0 - -test_name MULI_2 -mvi r1, 1 -muli r3, r1, 0 -check_r3 0 - -test_name MULI_3 -mvi r1, 0 -muli r3, r1, 1 -check_r3 0 - -test_name MULI_4 -mvi r1, 1 -muli r3, r1, 1 -check_r3 1 - -test_name MULI_5 -mvi r1, 2 -muli r3, r1, -1 -check_r3 -2 - -test_name MULI_6 -mvi r1, -2 -muli r3, r1, -1 -check_r3 2 - -test_name MULI_7 -mvi r1, 0x1234 -muli r3, r1, 0x789 -check_r3 0x8929d4 - -test_name MULI_8 -mvi r3, 4 -muli r3, r3, 4 -check_r3 16 - -end diff --git a/tests/tcg/lm32/test_nor.S b/tests/tcg/lm32/test_nor.S deleted file mode 100644 index 74d7592565..0000000000 --- a/tests/tcg/lm32/test_nor.S +++ /dev/null @@ -1,51 +0,0 @@ -.include "macros.inc" - -start - -test_name NOR_1 -mvi r1, 0 -mvi r2, 0 -nor r3, r1, r2 -check_r3 0xffffffff - -test_name NOR_2 -mvi r1, 0 -mvi r2, 1 -nor r3, r1, r2 -check_r3 0xfffffffe - -test_name NOR_3 -mvi r1, 1 -mvi r2, 1 -nor r3, r1, r2 -check_r3 0xfffffffe - -test_name NOR_4 -mvi r1, 1 -mvi r2, 0 -nor r3, r1, r2 -check_r3 0xfffffffe - -test_name NOR_5 -load r1 0xaa55aa55 -load r2 0x55aa55aa -nor r3, r1, r2 -check_r3 0 - -test_name NOR_6 -load r1 0xaa550000 -load r2 0x0000aa55 -nor r3, r1, r2 -check_r3 0x55aa55aa - -test_name NOR_7 -load r1 0xaa55aa55 -nor r3, r1, r1 -check_r3 0x55aa55aa - -test_name NOR_8 -load r3 0xaa55aa55 -nor r3, r3, r3 -check_r3 0x55aa55aa - -end diff --git a/tests/tcg/lm32/test_nori.S b/tests/tcg/lm32/test_nori.S deleted file mode 100644 index d00309c73e..0000000000 --- a/tests/tcg/lm32/test_nori.S +++ /dev/null @@ -1,35 +0,0 @@ -.include "macros.inc" - -start - -test_name NORI_1 -mvi r1, 0 -nori r3, r1, 0 -check_r3 0xffffffff - -test_name NORI_2 -mvi r1, 0 -nori r3, r1, 1 -check_r3 0xfffffffe - -test_name NORI_3 -mvi r1, 1 -nori r3, r1, 1 -check_r3 0xfffffffe - -test_name NORI_4 -mvi r1, 1 -nori r3, r1, 0 -check_r3 0xfffffffe - -test_name NORI_5 -load r1 0xaa55aa55 -nori r3, r1, 0x55aa -check_r3 0x55aa0000 - -test_name NORI_6 -load r3 0xaa55aa55 -nori r3, r3, 0x55aa -check_r3 0x55aa0000 - -end diff --git a/tests/tcg/lm32/test_or.S b/tests/tcg/lm32/test_or.S deleted file mode 100644 index 4ed292330e..0000000000 --- a/tests/tcg/lm32/test_or.S +++ /dev/null @@ -1,51 +0,0 @@ -.include "macros.inc" - -start - -test_name OR_1 -mvi r1, 0 -mvi r2, 0 -or r3, r1, r2 -check_r3 0 - -test_name OR_2 -mvi r1, 0 -mvi r2, 1 -or r3, r1, r2 -check_r3 1 - -test_name OR_3 -mvi r1, 1 -mvi r2, 1 -or r3, r1, r2 -check_r3 1 - -test_name OR_4 -mvi r1, 1 -mvi r2, 0 -or r3, r1, r2 -check_r3 1 - -test_name OR_5 -load r1 0xaa55aa55 -load r2 0x55aa55aa -or r3, r1, r2 -check_r3 0xffffffff - -test_name OR_6 -load r1 0xaa550000 -load r2 0x0000aa55 -or r3, r1, r2 -check_r3 0xaa55aa55 - -test_name OR_7 -load r1 0xaa55aa55 -or r3, r1, r1 -check_r3 0xaa55aa55 - -test_name OR_8 -load r3 0xaa55aa55 -or r3, r3, r3 -check_r3 0xaa55aa55 - -end diff --git a/tests/tcg/lm32/test_orhi.S b/tests/tcg/lm32/test_orhi.S deleted file mode 100644 index 78b7600e03..0000000000 --- a/tests/tcg/lm32/test_orhi.S +++ /dev/null @@ -1,35 +0,0 @@ -.include "macros.inc" - -start - -test_name ORHI_1 -mvi r1, 0 -orhi r3, r1, 0 -check_r3 0 - -test_name ORHI_2 -mvi r1, 0 -orhi r3, r1, 1 -check_r3 0x00010000 - -test_name ORHI_3 -load r1 0x00010000 -orhi r3, r1, 1 -check_r3 0x00010000 - -test_name ORHI_4 -mvi r1, 1 -orhi r3, r1, 0 -check_r3 1 - -test_name ORHI_5 -load r1 0xaa55aa55 -orhi r3, r1, 0x55aa -check_r3 0xffffaa55 - -test_name ORHI_6 -load r3 0xaa55aa55 -orhi r3, r3, 0x55aa -check_r3 0xffffaa55 - -end diff --git a/tests/tcg/lm32/test_ori.S b/tests/tcg/lm32/test_ori.S deleted file mode 100644 index 3d576cdb8b..0000000000 --- a/tests/tcg/lm32/test_ori.S +++ /dev/null @@ -1,35 +0,0 @@ -.include "macros.inc" - -start - -test_name ORI_1 -mvi r1, 0 -ori r3, r1, 0 -check_r3 0 - -test_name ORI_2 -mvi r1, 0 -ori r3, r1, 1 -check_r3 1 - -test_name ORI_3 -mvi r1, 1 -ori r3, r1, 1 -check_r3 1 - -test_name ORI_4 -mvi r1, 1 -ori r3, r1, 0 -check_r3 1 - -test_name ORI_5 -load r1 0xaa55aa55 -ori r3, r1, 0x55aa -check_r3 0xaa55ffff - -test_name ORI_6 -load r3 0xaa55aa55 -ori r3, r3, 0x55aa -check_r3 0xaa55ffff - -end diff --git a/tests/tcg/lm32/test_ret.S b/tests/tcg/lm32/test_ret.S deleted file mode 100644 index 320264f148..0000000000 --- a/tests/tcg/lm32/test_ret.S +++ /dev/null @@ -1,14 +0,0 @@ -.include "macros.inc" - -start - -test_name RET_1 -load ra mark -ret - -tc_fail -end - -mark: -tc_pass -end diff --git a/tests/tcg/lm32/test_sb.S b/tests/tcg/lm32/test_sb.S deleted file mode 100644 index b15a89d342..0000000000 --- a/tests/tcg/lm32/test_sb.S +++ /dev/null @@ -1,32 +0,0 @@ -.include "macros.inc" - -start - -test_name SB_1 -load r1 data -load r2 0xf0f1f2aa -sb (r1+0), r2 -check_mem data 0xaa000000 - -test_name SB_2 -load r1 data -load r2 0xf0f1f2bb -sb (r1+1), r2 -check_mem data 0xaabb0000 - -test_name SB_3 -load r1 data -load r2 0xf0f1f2cc -sb (r1+-1), r2 -check_mem data0 0x000000cc - -end - -.data - .align 4 -data0: - .byte 0, 0, 0, 0 -data: - .byte 0, 0, 0, 0 -data1: - .byte 0, 0, 0, 0 diff --git a/tests/tcg/lm32/test_scall.S b/tests/tcg/lm32/test_scall.S deleted file mode 100644 index 46032f841d..0000000000 --- a/tests/tcg/lm32/test_scall.S +++ /dev/null @@ -1,24 +0,0 @@ -.include "macros.inc" - -start - -test_name SCALL_1 -mvi r1, 1 -wcsr IE, r1 -# we are running in a semi hosted environment -# therefore we have to set r8 to some unused system -# call -mvi r8, 0 -insn: -scall -check_excp 64 - -test_name SCALL_2 -mv r3, ea -check_r3 insn - -test_name SCALL_3 -rcsr r3, IE -check_r3 2 - -end diff --git a/tests/tcg/lm32/test_sextb.S b/tests/tcg/lm32/test_sextb.S deleted file mode 100644 index 58db8ee8b9..0000000000 --- a/tests/tcg/lm32/test_sextb.S +++ /dev/null @@ -1,20 +0,0 @@ -.include "macros.inc" - -start - -test_name SEXTB_1 -mvi r1, 0 -sextb r3, r1 -check_r3 0 - -test_name SEXTB_2 -mvi r1, 0x7f -sextb r3, r1 -check_r3 0x0000007f - -test_name SEXTB_3 -mvi r1, 0x80 -sextb r3, r1 -check_r3 0xffffff80 - -end diff --git a/tests/tcg/lm32/test_sexth.S b/tests/tcg/lm32/test_sexth.S deleted file mode 100644 index a059ec3ee6..0000000000 --- a/tests/tcg/lm32/test_sexth.S +++ /dev/null @@ -1,20 +0,0 @@ -.include "macros.inc" - -start - -test_name SEXTH_1 -mvi r1, 0 -sexth r3, r1 -check_r3 0 - -test_name SEXTH_2 -load r1 0x7fff -sexth r3, r1 -check_r3 0x00007fff - -test_name SEXTH_3 -load r1 0x8000 -sexth r3, r1 -check_r3 0xffff8000 - -end diff --git a/tests/tcg/lm32/test_sh.S b/tests/tcg/lm32/test_sh.S deleted file mode 100644 index bba10224f6..0000000000 --- a/tests/tcg/lm32/test_sh.S +++ /dev/null @@ -1,32 +0,0 @@ -.include "macros.inc" - -start - -test_name SH_1 -load r1 data -load r2 0xf0f1aaaa -sh (r1+0), r2 -check_mem data 0xaaaa0000 - -test_name SH_2 -load r1 data -load r2 0xf0f1bbbb -sh (r1+2), r2 -check_mem data 0xaaaabbbb - -test_name SH_3 -load r1 data -load r2 0xf0f1cccc -sh (r1+-2), r2 -check_mem data0 0x0000cccc - -end - -.data - .align 4 -data0: - .byte 0, 0, 0, 0 -data: - .byte 0, 0, 0, 0 -data1: - .byte 0, 0, 0, 0 diff --git a/tests/tcg/lm32/test_sl.S b/tests/tcg/lm32/test_sl.S deleted file mode 100644 index 0aee17fdb8..0000000000 --- a/tests/tcg/lm32/test_sl.S +++ /dev/null @@ -1,45 +0,0 @@ -.include "macros.inc" - -start - -test_name SL_1 -mvi r1, 1 -mvi r2, 0 -sl r3, r1, r2 -check_r3 1 - -test_name SL_2 -mvi r1, 0 -mvi r2, 1 -sl r3, r1, r2 -check_r3 0 - -test_name SL_3 -mvi r1, 1 -mvi r2, 31 -sl r3, r1, r2 -check_r3 0x80000000 - -test_name SL_4 -mvi r1, 16 -mvi r2, 31 -sl r3, r1, r2 -check_r3 0 - -test_name SL_5 -mvi r1, 1 -mvi r2, 34 -sl r3, r1, r2 -check_r3 4 - -test_name SL_6 -mvi r1, 2 -sl r3, r1, r1 -check_r3 8 - -test_name SL_7 -mvi r3, 2 -sl r3, r3, r3 -check_r3 8 - -end diff --git a/tests/tcg/lm32/test_sli.S b/tests/tcg/lm32/test_sli.S deleted file mode 100644 index a421de9014..0000000000 --- a/tests/tcg/lm32/test_sli.S +++ /dev/null @@ -1,30 +0,0 @@ -.include "macros.inc" - -start - -test_name SLI_1 -mvi r1, 1 -sli r3, r1, 0 -check_r3 1 - -test_name SLI_2 -mvi r1, 0 -sli r3, r1, 1 -check_r3 0 - -test_name SLI_3 -mvi r1, 1 -sli r3, r1, 31 -check_r3 0x80000000 - -test_name SLI_4 -mvi r1, 16 -sli r3, r1, 31 -check_r3 0 - -test_name SLI_7 -mvi r3, 2 -sli r3, r3, 2 -check_r3 8 - -end diff --git a/tests/tcg/lm32/test_sr.S b/tests/tcg/lm32/test_sr.S deleted file mode 100644 index 62431a9864..0000000000 --- a/tests/tcg/lm32/test_sr.S +++ /dev/null @@ -1,57 +0,0 @@ -.include "macros.inc" - -start - -test_name SR_1 -mvi r1, 1 -mvi r2, 0 -sr r3, r1, r2 -check_r3 1 - -test_name SR_2 -mvi r1, 0 -mvi r2, 1 -sr r3, r1, r2 -check_r3 0 - -test_name SR_3 -load r1 0x40000000 -mvi r2, 30 -sr r3, r1, r2 -check_r3 1 - -test_name SR_4 -load r1 0x40000000 -mvi r2, 31 -sr r3, r1, r2 -check_r3 0 - -test_name SR_5 -mvi r1, 16 -mvi r2, 34 -sr r3, r1, r2 -check_r3 4 - -test_name SR_6 -mvi r1, 2 -sr r3, r1, r1 -check_r3 0 - -test_name SR_7 -mvi r3, 2 -sr r3, r3, r3 -check_r3 0 - -test_name SR_8 -mvi r1, 0xfffffff0 -mvi r2, 2 -sr r3, r1, r2 -check_r3 0xfffffffc - -test_name SR_9 -mvi r1, 0xfffffff0 -mvi r2, 4 -sr r3, r1, r2 -check_r3 0xffffffff - -end diff --git a/tests/tcg/lm32/test_sri.S b/tests/tcg/lm32/test_sri.S deleted file mode 100644 index c1be907b5b..0000000000 --- a/tests/tcg/lm32/test_sri.S +++ /dev/null @@ -1,40 +0,0 @@ -.include "macros.inc" - -start - -test_name SRI_1 -mvi r1, 1 -sri r3, r1, 0 -check_r3 1 - -test_name SRI_2 -mvi r1, 0 -sri r3, r1, 1 -check_r3 0 - -test_name SRI_3 -load r1 0x40000000 -sri r3, r1, 30 -check_r3 1 - -test_name SRI_4 -load r1 0x40000000 -sri r3, r1, 31 -check_r3 0 - -test_name SRI_5 -mvi r3, 2 -sri r3, r3, 2 -check_r3 0 - -test_name SRI_6 -mvi r1, 0xfffffff0 -sri r3, r1, 2 -check_r3 0xfffffffc - -test_name SRI_7 -mvi r1, 0xfffffff0 -sri r3, r1, 4 -check_r3 0xffffffff - -end diff --git a/tests/tcg/lm32/test_sru.S b/tests/tcg/lm32/test_sru.S deleted file mode 100644 index 2ab0b54c77..0000000000 --- a/tests/tcg/lm32/test_sru.S +++ /dev/null @@ -1,57 +0,0 @@ -.include "macros.inc" - -start - -test_name SRU_1 -mvi r1, 1 -mvi r2, 0 -sru r3, r1, r2 -check_r3 1 - -test_name SRU_2 -mvi r1, 0 -mvi r2, 1 -sru r3, r1, r2 -check_r3 0 - -test_name SRU_3 -load r1 0x40000000 -mvi r2, 30 -sru r3, r1, r2 -check_r3 1 - -test_name SRU_4 -load r1 0x40000000 -mvi r2, 31 -sru r3, r1, r2 -check_r3 0 - -test_name SRU_5 -mvi r1, 16 -mvi r2, 34 -sru r3, r1, r2 -check_r3 4 - -test_name SRU_6 -mvi r1, 2 -sru r3, r1, r1 -check_r3 0 - -test_name SRU_7 -mvi r3, 2 -sru r3, r3, r3 -check_r3 0 - -test_name SRU_8 -mvi r1, 0xfffffff0 -mvi r2, 2 -sru r3, r1, r2 -check_r3 0x3ffffffc - -test_name SRU_9 -mvi r1, 0xfffffff0 -mvi r2, 4 -sru r3, r1, r2 -check_r3 0x0fffffff - -end diff --git a/tests/tcg/lm32/test_srui.S b/tests/tcg/lm32/test_srui.S deleted file mode 100644 index 872c374121..0000000000 --- a/tests/tcg/lm32/test_srui.S +++ /dev/null @@ -1,40 +0,0 @@ -.include "macros.inc" - -start - -test_name SRUI_1 -mvi r1, 1 -srui r3, r1, 0 -check_r3 1 - -test_name SRUI_2 -mvi r1, 0 -srui r3, r1, 1 -check_r3 0 - -test_name SRUI_3 -load r1 0x40000000 -srui r3, r1, 30 -check_r3 1 - -test_name SRUI_4 -load r1 0x40000000 -srui r3, r1, 31 -check_r3 0 - -test_name SRUI_5 -mvi r3, 2 -srui r3, r3, 2 -check_r3 0 - -test_name SRUI_6 -mvi r1, 0xfffffff0 -srui r3, r1, 2 -check_r3 0x3ffffffc - -test_name SRUI_7 -mvi r1, 0xfffffff0 -srui r3, r1, 4 -check_r3 0x0fffffff - -end diff --git a/tests/tcg/lm32/test_sub.S b/tests/tcg/lm32/test_sub.S deleted file mode 100644 index 44b74a9e10..0000000000 --- a/tests/tcg/lm32/test_sub.S +++ /dev/null @@ -1,75 +0,0 @@ -.include "macros.inc" - -start - -test_name SUB_1 -mvi r1, 0 -mvi r2, 0 -sub r3, r1, r2 -check_r3 0 - -test_name SUB_2 -mvi r1, 0 -mvi r2, 1 -sub r3, r1, r2 -check_r3 -1 - -test_name SUB_3 -mvi r1, 1 -mvi r2, 0 -sub r3, r1, r2 -check_r3 1 - -test_name SUB_4 -mvi r1, 1 -mvi r2, -1 -sub r3, r1, r2 -check_r3 2 - -test_name SUB_5 -mvi r1, -1 -mvi r2, 1 -sub r3, r1, r2 -check_r3 -2 - -test_name SUB_6 -mvi r1, -1 -mvi r2, 0 -sub r3, r1, r2 -check_r3 -1 - -test_name SUB_7 -mvi r1, 0 -mvi r2, -1 -sub r3, r1, r2 -check_r3 1 - -test_name SUB_8 -mvi r3, 2 -sub r3, r3, r3 -check_r3 0 - -test_name SUB_9 -mvi r1, 4 -mvi r3, 2 -sub r3, r1, r3 -check_r3 2 - -test_name SUB_10 -mvi r1, 4 -mvi r3, 2 -sub r3, r3, r1 -check_r3 -2 - -test_name SUB_11 -mvi r1, 4 -sub r3, r1, r1 -check_r3 0 - -test_name SUB_12 -load r1 0x12345678 -load r2 0xabcdef97 -sub r3, r1, r2 -check_r3 0x666666e1 - -end diff --git a/tests/tcg/lm32/test_sw.S b/tests/tcg/lm32/test_sw.S deleted file mode 100644 index 2b1c017e7b..0000000000 --- a/tests/tcg/lm32/test_sw.S +++ /dev/null @@ -1,38 +0,0 @@ -.include "macros.inc" - -start - -test_name SW_1 -load r1 data -load r2 0xaabbccdd -sw (r1+0), r2 -check_mem data 0xaabbccdd - -test_name SW_2 -load r1 data -load r2 0x00112233 -sw (r1+4), r2 -check_mem data1 0x00112233 - -test_name SW_3 -load r1 data -load r2 0x44556677 -sw (r1+-4), r2 -check_mem data0 0x44556677 - -test_name SW_4 -load r1 data -sw (r1+0), r1 -lw r3, (r1+0) -check_r3 data - -end - -.data - .align 4 -data0: - .byte 0, 0, 0, 0 -data: - .byte 0, 0, 0, 0 -data1: - .byte 0, 0, 0, 0 diff --git a/tests/tcg/lm32/test_xnor.S b/tests/tcg/lm32/test_xnor.S deleted file mode 100644 index 14a62075f6..0000000000 --- a/tests/tcg/lm32/test_xnor.S +++ /dev/null @@ -1,51 +0,0 @@ -.include "macros.inc" - -start - -test_name XNOR_1 -mvi r1, 0 -mvi r2, 0 -xnor r3, r1, r2 -check_r3 0xffffffff - -test_name XNOR_2 -mvi r1, 0 -mvi r2, 1 -xnor r3, r1, r2 -check_r3 0xfffffffe - -test_name XNOR_3 -mvi r1, 1 -mvi r2, 1 -xnor r3, r1, r2 -check_r3 0xffffffff - -test_name XNOR_4 -mvi r1, 1 -mvi r2, 0 -xnor r3, r1, r2 -check_r3 0xfffffffe - -test_name XNOR_5 -load r1 0xaa55aa55 -load r2 0x55aa55aa -xnor r3, r1, r2 -check_r3 0 - -test_name XNOR_6 -load r1 0xaa550000 -load r2 0x0000aa55 -xnor r3, r1, r2 -check_r3 0x55aa55aa - -test_name XNOR_7 -load r1 0xaa55aa55 -xnor r3, r1, r1 -check_r3 0xffffffff - -test_name XNOR_8 -load r3 0xaa55aa55 -xnor r3, r3, r3 -check_r3 0xffffffff - -end diff --git a/tests/tcg/lm32/test_xnori.S b/tests/tcg/lm32/test_xnori.S deleted file mode 100644 index 9d9c3c6780..0000000000 --- a/tests/tcg/lm32/test_xnori.S +++ /dev/null @@ -1,35 +0,0 @@ -.include "macros.inc" - -start - -test_name XNORI_1 -mvi r1, 0 -xnori r3, r1, 0 -check_r3 0xffffffff - -test_name XNORI_2 -mvi r1, 0 -xnori r3, r1, 1 -check_r3 0xfffffffe - -test_name XNORI_3 -mvi r1, 1 -xnori r3, r1, 1 -check_r3 0xffffffff - -test_name XNORI_4 -mvi r1, 1 -xnori r3, r1, 0 -check_r3 0xfffffffe - -test_name XNORI_5 -load r1 0xaa55aa55 -xnori r3, r1, 0x5555 -check_r3 0x55aa00ff - -test_name XNORI_6 -load r3 0xaa55aa55 -xnori r3, r3, 0x5555 -check_r3 0x55aa00ff - -end diff --git a/tests/tcg/lm32/test_xor.S b/tests/tcg/lm32/test_xor.S deleted file mode 100644 index 6c6e712bae..0000000000 --- a/tests/tcg/lm32/test_xor.S +++ /dev/null @@ -1,51 +0,0 @@ -.include "macros.inc" - -start - -test_name XOR_1 -mvi r1, 0 -mvi r2, 0 -xor r3, r1, r2 -check_r3 0 - -test_name XOR_2 -mvi r1, 0 -mvi r2, 1 -xor r3, r1, r2 -check_r3 1 - -test_name XOR_3 -mvi r1, 1 -mvi r2, 1 -xor r3, r1, r2 -check_r3 0 - -test_name XOR_4 -mvi r1, 1 -mvi r2, 0 -xor r3, r1, r2 -check_r3 1 - -test_name XOR_5 -load r1 0xaa55aa55 -load r2 0x55aa55aa -xor r3, r1, r2 -check_r3 0xffffffff - -test_name XOR_6 -load r1 0xaa550000 -load r2 0x0000aa55 -xor r3, r1, r2 -check_r3 0xaa55aa55 - -test_name XOR_7 -load r1 0xaa55aa55 -xor r3, r1, r1 -check_r3 0 - -test_name XOR_8 -load r3 0xaa55aa55 -xor r3, r3, r3 -check_r3 0 - -end diff --git a/tests/tcg/lm32/test_xori.S b/tests/tcg/lm32/test_xori.S deleted file mode 100644 index 2051699f12..0000000000 --- a/tests/tcg/lm32/test_xori.S +++ /dev/null @@ -1,35 +0,0 @@ -.include "macros.inc" - -start - -test_name XORI_1 -mvi r1, 0 -xori r3, r1, 0 -check_r3 0 - -test_name XORI_2 -mvi r1, 0 -xori r3, r1, 1 -check_r3 1 - -test_name XORI_3 -mvi r1, 1 -xori r3, r1, 1 -check_r3 0 - -test_name XORI_4 -mvi r1, 1 -xori r3, r1, 0 -check_r3 1 - -test_name XORI_5 -load r1 0xaa55aa55 -xori r3, r1, 0x5555 -check_r3 0xaa55ff00 - -test_name XORI_6 -load r3 0xaa55aa55 -xori r3, r3, 0x5555 -check_r3 0xaa55ff00 - -end diff --git a/tests/tcg/multiarch/system/memory.c b/tests/tcg/multiarch/system/memory.c index eb0ec6f8eb..41c7f66e2e 100644 --- a/tests/tcg/multiarch/system/memory.c +++ b/tests/tcg/multiarch/system/memory.c @@ -326,6 +326,7 @@ static bool do_unsigned_test(init_ufn fn) fn(i); ok = do_unsigned_reads(i); } + return ok; #else fn(0); return do_unsigned_reads(0); diff --git a/tests/tcg/ppc64/Makefile.target b/tests/tcg/ppc64/Makefile.target index 0c6a4585fc..a6a4ddaeca 100644 --- a/tests/tcg/ppc64/Makefile.target +++ b/tests/tcg/ppc64/Makefile.target @@ -10,4 +10,17 @@ PPC64_TESTS=bcdsub endif bcdsub: CFLAGS += -mpower8-vector +PPC64_TESTS += byte_reverse +ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_POWER10),) +run-byte_reverse: QEMU_OPTS+=-cpu POWER10 +run-plugin-byte_reverse-with-%: QEMU_OPTS+=-cpu POWER10 +else +byte_reverse: + $(call skip-test, "BUILD of $@", "missing compiler support") +run-byte_reverse: + $(call skip-test, "RUN of byte_reverse", "not built") +run-plugin-byte_reverse-with-%: + $(call skip-test, "RUN of byte_reverse ($*)", "not built") +endif + TESTS += $(PPC64_TESTS) diff --git a/tests/tcg/ppc64le/Makefile.target b/tests/tcg/ppc64le/Makefile.target index 1acfcff94a..c0c14ffbad 100644 --- a/tests/tcg/ppc64le/Makefile.target +++ b/tests/tcg/ppc64le/Makefile.target @@ -9,4 +9,17 @@ PPC64LE_TESTS=bcdsub endif bcdsub: CFLAGS += -mpower8-vector +PPC64LE_TESTS += byte_reverse +ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_POWER10),) +run-byte_reverse: QEMU_OPTS+=-cpu POWER10 +run-plugin-byte_reverse-with-%: QEMU_OPTS+=-cpu POWER10 +else +byte_reverse: + $(call skip-test, "BUILD of $@", "missing compiler support") +run-byte_reverse: + $(call skip-test, "RUN of byte_reverse", "not built") +run-plugin-byte_reverse-with-%: + $(call skip-test, "RUN of byte_reverse ($*)", "not built") +endif + TESTS += $(PPC64LE_TESTS) diff --git a/tests/tcg/ppc64le/byte_reverse.c b/tests/tcg/ppc64le/byte_reverse.c new file mode 100644 index 0000000000..53b76fc2e2 --- /dev/null +++ b/tests/tcg/ppc64le/byte_reverse.c @@ -0,0 +1,21 @@ +#include <assert.h> + +int main(void) +{ + unsigned long var; + + var = 0xFEDCBA9876543210; + asm("brh %0, %0" : "+r"(var)); + assert(var == 0xDCFE98BA54761032); + + var = 0xFEDCBA9876543210; + asm("brw %0, %0" : "+r"(var)); + assert(var == 0x98BADCFE10325476); + + var = 0xFEDCBA9876543210; + asm("brd %0, %0" : "+r"(var)); + assert(var == 0x1032547698BADCFE); + + return 0; +} + diff --git a/tests/tcg/sparc64/Makefile.target b/tests/tcg/sparc64/Makefile.target index 5bd7f90583..408dace783 100644 --- a/tests/tcg/sparc64/Makefile.target +++ b/tests/tcg/sparc64/Makefile.target @@ -1,11 +1,6 @@ # -*- Mode: makefile -*- # -# sparc specific tweaks and masking out broken tests - -# different from the other hangs: -# tests/tcg/multiarch/linux-test.c:264: Value too large for defined data type (ret=-1, errno=92/Value too large for defined data type) -run-linux-test: linux-test - $(call skip-test, $<, "BROKEN") +# sparc specific tweaks # On Sparc64 Linux support 8k pages EXTRA_RUNS+=run-test-mmap-8192 diff --git a/tests/tcg/tricore/Makefile.softmmu-target b/tests/tcg/tricore/Makefile.softmmu-target new file mode 100644 index 0000000000..5007c60ce8 --- /dev/null +++ b/tests/tcg/tricore/Makefile.softmmu-target @@ -0,0 +1,26 @@ +TESTS_PATH = $(SRC_PATH)/tests/tcg/tricore + +LDFLAGS = -T$(TESTS_PATH)/link.ld +ASFLAGS = + +TESTS += test_abs.tst +TESTS += test_bmerge.tst +TESTS += test_clz.tst +TESTS += test_dvstep.tst +TESTS += test_fadd.tst +TESTS += test_fmul.tst +TESTS += test_ftoi.tst +TESTS += test_madd.tst +TESTS += test_msub.tst +TESTS += test_muls.tst + +QEMU_OPTS += -M tricore_testboard -nographic -kernel + +%.pS: $(TESTS_PATH)/%.S + $(HOST_CC) -E -o $@ $< + +%.o: %.pS + $(AS) $(ASFLAGS) -o $@ $< + +%.tst: %.o + $(LD) $(LDFLAGS) $< -o $@ diff --git a/tests/tcg/tricore/link.ld b/tests/tcg/tricore/link.ld new file mode 100644 index 0000000000..364bcdc00a --- /dev/null +++ b/tests/tcg/tricore/link.ld @@ -0,0 +1,60 @@ +/* Default linker script, for normal executables */ +OUTPUT_FORMAT("elf32-tricore") +OUTPUT_ARCH(tricore) +ENTRY(_start) + +/* the internal ram description */ +MEMORY +{ + text_ram (rx!p): org = 0x80000000, len = 15K + data_ram (w!xp): org = 0xd0000000, len = 130K +} +/* + * Define the sizes of the user and system stacks. + */ +__USTACK_SIZE = DEFINED (__USTACK_SIZE) ? __USTACK_SIZE : 1K ; +/* + * Define the start address and the size of the context save area. + */ +__CSA_BEGIN = 0xd0000000 ; +__CSA_SIZE = 8k ; +__CSA_END = __CSA_BEGIN + __CSA_SIZE ; + +SECTIONS +{ + .text : + { + *(.text) + . = ALIGN(8); + } > text_ram + + .rodata : + { + *(.rodata) + *(.rodata1) + } > data_ram + + .data : + { + . = ALIGN(8) ; + *(.data) + *(.data.*) + . = ALIGN(8) ; + __USTACK = . + __USTACK_SIZE -768; + + } > data_ram + /* + * Allocate space for BSS sections. + */ + .bss : + { + BSS_BASE = . ; + *(.bss) + *(COMMON) + . = ALIGN(8) ; + } > data_ram + /* Make sure CSA, stack and heap addresses are properly aligned. */ + _. = ASSERT ((__CSA_BEGIN & 0x3f) == 0 , "illegal CSA start address") ; + _. = ASSERT ((__CSA_SIZE & 0x3f) == 0 , "illegal CSA size") ; + +} diff --git a/tests/tcg/tricore/macros.h b/tests/tcg/tricore/macros.h new file mode 100644 index 0000000000..0d76fc403a --- /dev/null +++ b/tests/tcg/tricore/macros.h @@ -0,0 +1,129 @@ +/* Helpers */ +#define LI(reg, val) \ + mov.u reg, lo:val; \ + movh DREG_TEMP_LI, up:val; \ + or reg, reg, DREG_TEMP_LI; \ + +/* Address definitions */ +#define TESTDEV_ADDR 0xf0000000 +/* Register definitions */ +#define DREG_RS1 %d0 +#define DREG_RS2 %d1 +#define DREG_RS3 %d4 +#define DREG_CALC_RESULT %d1 +#define DREG_CALC_PSW %d2 +#define DREG_CORRECT_PSW %d3 +#define DREG_TEMP_LI %d10 +#define DREG_TEMP %d11 +#define DREG_TEST_NUM %d14 +#define DREG_CORRECT_RESULT %d15 + +#define DREG_DEV_ADDR %a15 + +#define EREG_RS1 %e6 +#define EREG_RS1_LO %d6 +#define EREG_RS1_HI %d7 +#define EREG_RS2 %e8 +#define EREG_RS2_LO %d8 +#define EREG_RS2_HI %d9 +#define EREG_CALC_RESULT %e8 +#define EREG_CALC_RESULT_HI %d9 +#define EREG_CALC_RESULT_LO %d8 +#define EREG_CORRECT_RESULT_LO %d0 +#define EREG_CORRECT_RESULT_HI %d1 + +/* Test case wrappers */ +#define TEST_CASE(num, testreg, correct, code...) \ +test_ ## num: \ + code; \ + LI(DREG_CORRECT_RESULT, correct) \ + mov DREG_TEST_NUM, num; \ + jne testreg, DREG_CORRECT_RESULT, fail \ + +#define TEST_CASE_E(num, correct_lo, correct_hi, code...) \ +test_ ## num: \ + code; \ + mov DREG_TEST_NUM, num; \ + LI(EREG_CORRECT_RESULT_LO, correct_lo) \ + jne EREG_CALC_RESULT_LO, EREG_CORRECT_RESULT_LO, fail; \ + LI(EREG_CORRECT_RESULT_HI, correct_hi) \ + jne EREG_CALC_RESULT_HI, EREG_CORRECT_RESULT_HI, fail; + +#define TEST_CASE_PSW(num, testreg, correct, correct_psw, code...) \ +test_ ## num: \ + code; \ + LI(DREG_CORRECT_RESULT, correct) \ + mov DREG_TEST_NUM, num; \ + jne testreg, DREG_CORRECT_RESULT, fail; \ + mfcr DREG_CALC_PSW, $psw; \ + LI(DREG_CORRECT_PSW, correct_psw) \ + mov DREG_TEST_NUM, num; \ + jne DREG_CALC_PSW, DREG_CORRECT_PSW, fail; + +/* Actual test case type + * e.g inst %dX, %dY -> TEST_D_D + * inst %dX, %dY, %dZ -> TEST_D_DD + * inst %eX, %dY, %dZ -> TEST_E_DD + */ +#define TEST_D_D(insn, num, result, rs1) \ + TEST_CASE(num, DREG_CALC_RESULT, result, \ + LI(DREG_RS1, rs1); \ + insn DREG_CALC_RESULT, DREG_RS1; \ + ) + +#define TEST_D_D_PSW(insn, num, result, psw, rs1) \ + TEST_CASE_PSW(num, DREG_CALC_RESULT, result, psw, \ + LI(DREG_RS1, rs1); \ + rstv; \ + insn DREG_CORRECT_RESULT, DREG_RS1; \ + ) + +#define TEST_D_DD_PSW(insn, num, result, psw, rs1, rs2) \ + TEST_CASE_PSW(num, DREG_CALC_RESULT, result, psw, \ + LI(DREG_RS1, rs1); \ + LI(DREG_RS2, rs2); \ + rstv; \ + insn DREG_CALC_RESULT, DREG_RS1, DREG_RS2; \ + ) + +#define TEST_D_DDD_PSW(insn, num, result, psw, rs1, rs2, rs3) \ + TEST_CASE_PSW(num, DREG_CALC_RESULT, result, psw, \ + LI(DREG_RS1, rs1); \ + LI(DREG_RS2, rs2); \ + LI(DREG_RS3, rs3); \ + rstv; \ + insn DREG_CALC_RESULT, DREG_RS1, DREG_RS2, DREG_RS3; \ + ) + +#define TEST_D_DDI_PSW(insn, num, result, psw, rs1, rs2, imm) \ + TEST_CASE_PSW(num, DREG_CALC_RESULT, result, psw, \ + LI(DREG_RS1, rs1); \ + LI(DREG_RS2, rs2); \ + rstv; \ + insn DREG_CALC_RESULT, DREG_RS1, DREG_RS2, imm; \ + ) + +#define TEST_E_ED(insn, num, res_hi, res_lo, rs1_hi, rs1_lo, rs2) \ + TEST_CASE_E(num, res_lo, res_hi, \ + LI(EREG_RS1_LO, rs1_lo); \ + LI(EREG_RS1_HI, rs1_hi); \ + LI(DREG_RS2, rs2); \ + insn EREG_CALC_RESULT, EREG_RS1, DREG_RS2; \ + ) + +/* Pass/Fail handling part */ +#define TEST_PASSFAIL \ + j pass; \ +fail: \ + LI(DREG_TEMP, TESTDEV_ADDR) \ + mov.a DREG_DEV_ADDR, DREG_TEMP; \ + st.w [DREG_DEV_ADDR], DREG_TEST_NUM;\ + debug; \ + j fail; \ +pass: \ + LI(DREG_TEMP, TESTDEV_ADDR) \ + mov.a DREG_DEV_ADDR, DREG_TEMP; \ + mov DREG_TEST_NUM, 0; \ + st.w [DREG_DEV_ADDR], DREG_TEST_NUM;\ + debug; \ + j pass; diff --git a/tests/tcg/tricore/test_abs.S b/tests/tcg/tricore/test_abs.S new file mode 100644 index 0000000000..e42240159a --- /dev/null +++ b/tests/tcg/tricore/test_abs.S @@ -0,0 +1,7 @@ +#include "macros.h" +.text +.global _start +_start: + TEST_D_D(abs, 1, 0, 0) + + TEST_PASSFAIL diff --git a/tests/tcg/tricore/test_bmerge.S b/tests/tcg/tricore/test_bmerge.S new file mode 100644 index 0000000000..8a0fa6d3f6 --- /dev/null +++ b/tests/tcg/tricore/test_bmerge.S @@ -0,0 +1,8 @@ +#include "macros.h" +.text +.global _start +_start: + TEST_D_DD_PSW(bmerge, 1, 0x555557f7, 0x00000b80, 0x0000001d, 0x0000ffff) + + TEST_PASSFAIL + diff --git a/tests/tcg/tricore/test_clz.S b/tests/tcg/tricore/test_clz.S new file mode 100644 index 0000000000..e03835f123 --- /dev/null +++ b/tests/tcg/tricore/test_clz.S @@ -0,0 +1,9 @@ +#include "macros.h" +.text +.global _start +_start: + TEST_D_D(cls.h, 1, 0x0, 0x6db17976) + TEST_D_D(cls.h, 2, 0x000f000f, 0x0) + + TEST_PASSFAIL + diff --git a/tests/tcg/tricore/test_dvstep.S b/tests/tcg/tricore/test_dvstep.S new file mode 100644 index 0000000000..858dbc62dd --- /dev/null +++ b/tests/tcg/tricore/test_dvstep.S @@ -0,0 +1,15 @@ +#include "macros.h" +.text +.global _start +_start: + # Result RS1 RS2 + TEST_E_ED(dvstep, 1, 0x000001ff, 0xfffe5cff, 0x00000001, 0xfffffe5c, 0x0) + TEST_E_ED(dvstep, 2, 0x00000000, 0x000000ff, 0x00000000, 0x00000000, 0x0) + TEST_E_ED(dvstep, 3, 0x0000f000, 0x000000fd, 0x010000f0, 0x00000000, 0x0) + TEST_E_ED(dvstep, 4, 0xfffff000, 0x00000000, 0x7ffffff0, 0x00000000, 0x0) + TEST_E_ED(dvstep.u, 5, 0xffffff00, 0x100008ff, 0xffffffff, 0x00100008, 0x0) + TEST_E_ED(dvstep.u, 6, 0x00000100, 0x00000000, 0x08000001, 0x00000000, \ + 0xffffff2d) + + TEST_PASSFAIL + diff --git a/tests/tcg/tricore/test_fadd.S b/tests/tcg/tricore/test_fadd.S new file mode 100644 index 0000000000..1a65054803 --- /dev/null +++ b/tests/tcg/tricore/test_fadd.S @@ -0,0 +1,16 @@ +#include "macros.h" +.text +.global _start +_start: + TEST_D_DD_PSW(add.f, 1, 0x7fc00000, 0x00000b80, 0xffffff85, 0x00001234) + TEST_D_DD_PSW(add.f, 2, 0xf9c00000, 0x00000b80, 0xf9400000, 0xf9400000) + TEST_D_DD_PSW(add.f, 3, 0x8bb858ca, 0x00000b80, 0x8b3858ca, 0x8b3858ca) + TEST_D_DD_PSW(add.f, 4, 0x00000000, 0x00000b80, 0x000000ff, 0x00000000) + TEST_D_DD_PSW(add.f, 5, 0x7fc00000, 0x00000b80, 0xfffffe52, 0x0a4cf70c) + TEST_D_DD_PSW(add.f, 6, 0x9e6d5076, 0x84000b80, 0x9ded50ec, 0x9ded4fff) + TEST_D_DD_PSW(add.f, 7, 0x00000000, 0x04000b80, 0x0000e8bd, 0x00000000) + TEST_D_DD_PSW(add.f, 8, 0x7fc00000, 0xc4000b80, 0xffad546e, 0xffad546e) + TEST_D_DD_PSW(add.f, 9, 0x7fc00000, 0x04000b80, 0xfffe0000, 0x08130000) + + TEST_PASSFAIL + diff --git a/tests/tcg/tricore/test_fmul.S b/tests/tcg/tricore/test_fmul.S new file mode 100644 index 0000000000..fb1f634b2d --- /dev/null +++ b/tests/tcg/tricore/test_fmul.S @@ -0,0 +1,8 @@ +#include "macros.h" +.text +.global _start +_start: + TEST_D_DD_PSW(mul.f, 1, 0x974f4f0a, 0x84000b80, 0x1a0b1980, 0xbcbec42d) + + TEST_PASSFAIL + diff --git a/tests/tcg/tricore/test_ftoi.S b/tests/tcg/tricore/test_ftoi.S new file mode 100644 index 0000000000..fb4af6b5aa --- /dev/null +++ b/tests/tcg/tricore/test_ftoi.S @@ -0,0 +1,10 @@ +#include "macros.h" +.text +.global _start +_start: + TEST_D_D_PSW(ftoi, 1, 0x0, 0x84000b80, 0x05f6e605) + TEST_D_D_PSW(ftoi, 2, 0x0, 0x04000b80, 0x00012200) + TEST_D_D_PSW(ftoi, 3, 0x0, 0xc4000b80, 0xffffffff) + + TEST_PASSFAIL + diff --git a/tests/tcg/tricore/test_madd.S b/tests/tcg/tricore/test_madd.S new file mode 100644 index 0000000000..5d839772bb --- /dev/null +++ b/tests/tcg/tricore/test_madd.S @@ -0,0 +1,11 @@ +#include "macros.h" +.text +.global _start +_start: + TEST_D_DDI_PSW(madd, 1, 0x0000fffd, 0x60000b80, 0x0000ffff, 0x7fffffff,2) + TEST_D_DDI_PSW(madd, 2, 0xffff7fff, 0x60000b80, 0xffff8001, 0x7fffffff,2) + TEST_D_DDD_PSW(madds.u, 3, 0xffffffff, 0x60000b80, 0x00000000, 0x80000000, \ + 0x80000000) + + TEST_PASSFAIL + diff --git a/tests/tcg/tricore/test_msub.S b/tests/tcg/tricore/test_msub.S new file mode 100644 index 0000000000..6dee87d99c --- /dev/null +++ b/tests/tcg/tricore/test_msub.S @@ -0,0 +1,9 @@ +#include "macros.h" +.text +.global _start +_start: + TEST_D_DDI_PSW(msub, 1, 0xd2fbe5e0, 0x00000b80,0x64003300, 0xff5420d4, -216) + TEST_D_DDI_PSW(msub, 2, 0xfffffc10, 0x00000b80,0xfffffe68, 0xfffffffd, -200) + TEST_D_DDD_PSW(msubs.u, 3, 0x0, 0x60000b80, 0x1, 0xffffffff, 0xffffffdb) + TEST_PASSFAIL + diff --git a/tests/tcg/tricore/test_muls.S b/tests/tcg/tricore/test_muls.S new file mode 100644 index 0000000000..ca517556bc --- /dev/null +++ b/tests/tcg/tricore/test_muls.S @@ -0,0 +1,9 @@ +#include "macros.h" +.text +.global _start +_start: + TEST_D_DD_PSW(muls.u, 1, 0xffffffff, 0x78000b80, 0x80000001, 0xffffffff) + TEST_D_DD_PSW(muls.u, 2, 0xffffffff, 0x60000b80, 0xfffffffe, 0xffffffff) + + TEST_PASSFAIL + diff --git a/tests/unit/test-write-threshold.c b/tests/unit/test-write-threshold.c index fc1c45a2eb..0158e4637a 100644 --- a/tests/unit/test-write-threshold.c +++ b/tests/unit/test-write-threshold.c @@ -7,117 +7,41 @@ */ #include "qemu/osdep.h" -#include "qapi/error.h" #include "block/block_int.h" #include "block/write-threshold.h" -static void test_threshold_not_set_on_init(void) -{ - uint64_t res; - BlockDriverState bs; - memset(&bs, 0, sizeof(bs)); - - g_assert(!bdrv_write_threshold_is_set(&bs)); - - res = bdrv_write_threshold_get(&bs); - g_assert_cmpint(res, ==, 0); -} - -static void test_threshold_set_get(void) -{ - uint64_t threshold = 4 * 1024 * 1024; - uint64_t res; - BlockDriverState bs; - memset(&bs, 0, sizeof(bs)); - - bdrv_write_threshold_set(&bs, threshold); - - g_assert(bdrv_write_threshold_is_set(&bs)); - - res = bdrv_write_threshold_get(&bs); - g_assert_cmpint(res, ==, threshold); -} - -static void test_threshold_multi_set_get(void) -{ - uint64_t threshold1 = 4 * 1024 * 1024; - uint64_t threshold2 = 15 * 1024 * 1024; - uint64_t res; - BlockDriverState bs; - memset(&bs, 0, sizeof(bs)); - - bdrv_write_threshold_set(&bs, threshold1); - bdrv_write_threshold_set(&bs, threshold2); - res = bdrv_write_threshold_get(&bs); - g_assert_cmpint(res, ==, threshold2); -} - static void test_threshold_not_trigger(void) { - uint64_t amount = 0; uint64_t threshold = 4 * 1024 * 1024; BlockDriverState bs; - BdrvTrackedRequest req; memset(&bs, 0, sizeof(bs)); - memset(&req, 0, sizeof(req)); - req.offset = 1024; - req.bytes = 1024; - - bdrv_check_request(req.offset, req.bytes, &error_abort); bdrv_write_threshold_set(&bs, threshold); - amount = bdrv_write_threshold_exceeded(&bs, &req); - g_assert_cmpuint(amount, ==, 0); + bdrv_write_threshold_check_write(&bs, 1024, 1024); + g_assert_cmpuint(bdrv_write_threshold_get(&bs), ==, threshold); } static void test_threshold_trigger(void) { - uint64_t amount = 0; uint64_t threshold = 4 * 1024 * 1024; BlockDriverState bs; - BdrvTrackedRequest req; memset(&bs, 0, sizeof(bs)); - memset(&req, 0, sizeof(req)); - req.offset = (4 * 1024 * 1024) - 1024; - req.bytes = 2 * 1024; - - bdrv_check_request(req.offset, req.bytes, &error_abort); bdrv_write_threshold_set(&bs, threshold); - amount = bdrv_write_threshold_exceeded(&bs, &req); - g_assert_cmpuint(amount, >=, 1024); + bdrv_write_threshold_check_write(&bs, threshold - 1024, 2 * 1024); + g_assert_cmpuint(bdrv_write_threshold_get(&bs), ==, 0); } -typedef struct TestStruct { - const char *name; - void (*func)(void); -} TestStruct; - int main(int argc, char **argv) { - size_t i; - TestStruct tests[] = { - { "/write-threshold/not-set-on-init", - test_threshold_not_set_on_init }, - { "/write-threshold/set-get", - test_threshold_set_get }, - { "/write-threshold/multi-set-get", - test_threshold_multi_set_get }, - { "/write-threshold/not-trigger", - test_threshold_not_trigger }, - { "/write-threshold/trigger", - test_threshold_trigger }, - { NULL, NULL } - }; - g_test_init(&argc, &argv, NULL); - for (i = 0; tests[i].name != NULL; i++) { - g_test_add_func(tests[i].name, tests[i].func); - } + g_test_add_func("/write-threshold/not-trigger", test_threshold_not_trigger); + g_test_add_func("/write-threshold/trigger", test_threshold_trigger); + return g_test_run(); } |