1# SPDX-License-Identifier: GPL-2.0 2# Makefile for nolibc tests 3# we're in ".../tools/testing/selftests/nolibc" 4ifeq ($(srctree),) 5srctree := $(patsubst %/tools/testing/selftests/,%,$(dir $(CURDIR))) 6endif 7 8include $(srctree)/tools/scripts/utilities.mak 9# We need this for the "__cc-option" macro. 10include $(srctree)/scripts/Makefile.compiler 11 12ifneq ($(O),) 13ifneq ($(call is-absolute,$(O)),y) 14$(error Only absolute O= parameters are supported) 15endif 16objtree := $(O) 17else 18objtree ?= $(srctree) 19endif 20 21ifeq ($(ARCH),) 22include $(srctree)/scripts/subarch.include 23ARCH = $(SUBARCH) 24endif 25 26cc-option = $(call __cc-option, $(CC),$(CLANG_CROSS_FLAGS),$(1),$(2)) 27 28# XARCH extends the kernel's ARCH with a few variants of the same 29# architecture that only differ by the configuration, the toolchain 30# and the Qemu program used. It is copied as-is into ARCH except for 31# a few specific values which are mapped like this: 32# 33# XARCH | ARCH | config 34# -------------|-----------|------------------------- 35# ppc | powerpc | 32 bits 36# ppc64 | powerpc | 64 bits big endian 37# ppc64le | powerpc | 64 bits little endian 38# 39# It is recommended to only use XARCH, though it does not harm if 40# ARCH is already set. For simplicity, ARCH is sufficient for all 41# architectures where both are equal. 42 43# configure default variants for target kernel supported architectures 44XARCH_powerpc = ppc 45XARCH_mips = mips32le 46XARCH_riscv = riscv64 47XARCH = $(or $(XARCH_$(ARCH)),$(ARCH)) 48 49# map from user input variants to their kernel supported architectures 50ARCH_armthumb = arm 51ARCH_ppc = powerpc 52ARCH_ppc64 = powerpc 53ARCH_ppc64le = powerpc 54ARCH_mips32le = mips 55ARCH_mips32be = mips 56ARCH_mipsn32le = mips 57ARCH_mipsn32be = mips 58ARCH_mips64le = mips 59ARCH_mips64be = mips 60ARCH_riscv32 = riscv 61ARCH_riscv64 = riscv 62ARCH_s390x = s390 63ARCH_sparc32 = sparc 64ARCH_sparc64 = sparc 65ARCH_sh4 = sh 66ARCH := $(or $(ARCH_$(XARCH)),$(XARCH)) 67 68# kernel image names by architecture 69IMAGE_i386 = arch/x86/boot/bzImage 70IMAGE_x86_64 = arch/x86/boot/bzImage 71IMAGE_x86 = arch/x86/boot/bzImage 72IMAGE_arm64 = arch/arm64/boot/Image 73IMAGE_arm = arch/arm/boot/zImage 74IMAGE_armthumb = arch/arm/boot/zImage 75IMAGE_mips32le = vmlinuz 76IMAGE_mips32be = vmlinuz 77IMAGE_mipsn32le = vmlinuz 78IMAGE_mipsn32be = vmlinuz 79IMAGE_mips64le = vmlinuz 80IMAGE_mips64be = vmlinuz 81IMAGE_ppc = vmlinux 82IMAGE_ppc64 = vmlinux 83IMAGE_ppc64le = arch/powerpc/boot/zImage 84IMAGE_riscv = arch/riscv/boot/Image 85IMAGE_riscv32 = arch/riscv/boot/Image 86IMAGE_riscv64 = arch/riscv/boot/Image 87IMAGE_s390x = arch/s390/boot/bzImage 88IMAGE_s390 = arch/s390/boot/bzImage 89IMAGE_loongarch = arch/loongarch/boot/vmlinuz.efi 90IMAGE_sparc32 = arch/sparc/boot/image 91IMAGE_sparc64 = arch/sparc/boot/image 92IMAGE_m68k = vmlinux 93IMAGE_sh4 = arch/sh/boot/zImage 94IMAGE = $(objtree)/$(IMAGE_$(XARCH)) 95IMAGE_NAME = $(notdir $(IMAGE)) 96 97# default kernel configurations that appear to be usable 98DEFCONFIG_i386 = defconfig 99DEFCONFIG_x86_64 = defconfig 100DEFCONFIG_x86 = defconfig 101DEFCONFIG_arm64 = defconfig 102DEFCONFIG_arm = multi_v7_defconfig 103DEFCONFIG_armthumb = multi_v7_defconfig 104DEFCONFIG_mips32le = malta_defconfig 105DEFCONFIG_mips32be = malta_defconfig generic/eb.config 106DEFCONFIG_mipsn32le = malta_defconfig generic/64r2.config 107DEFCONFIG_mipsn32be = malta_defconfig generic/64r6.config generic/eb.config 108DEFCONFIG_mips64le = malta_defconfig generic/64r6.config 109DEFCONFIG_mips64be = malta_defconfig generic/64r2.config generic/eb.config 110DEFCONFIG_ppc = pmac32_defconfig 111DEFCONFIG_ppc64 = powernv_be_defconfig 112DEFCONFIG_ppc64le = powernv_defconfig 113DEFCONFIG_riscv = defconfig 114DEFCONFIG_riscv32 = rv32_defconfig 115DEFCONFIG_riscv64 = defconfig 116DEFCONFIG_s390x = defconfig 117DEFCONFIG_s390 = defconfig compat.config 118DEFCONFIG_loongarch = defconfig 119DEFCONFIG_sparc32 = sparc32_defconfig 120DEFCONFIG_sparc64 = sparc64_defconfig 121DEFCONFIG_m68k = virt_defconfig 122DEFCONFIG_sh4 = rts7751r2dplus_defconfig 123DEFCONFIG = $(DEFCONFIG_$(XARCH)) 124 125EXTRACONFIG_arm = -e CONFIG_NAMESPACES 126EXTRACONFIG_armthumb = -e CONFIG_NAMESPACES 127EXTRACONFIG_m68k = -e CONFIG_BLK_DEV_INITRD 128EXTRACONFIG_sh4 = -e CONFIG_BLK_DEV_INITRD -e CONFIG_CMDLINE_FROM_BOOTLOADER 129EXTRACONFIG = $(EXTRACONFIG_$(XARCH)) 130 131# optional tests to run (default = all) 132TEST = 133 134# QEMU_ARCH: arch names used by qemu 135QEMU_ARCH_i386 = i386 136QEMU_ARCH_x86_64 = x86_64 137QEMU_ARCH_x86 = x86_64 138QEMU_ARCH_arm64 = aarch64 139QEMU_ARCH_arm = arm 140QEMU_ARCH_armthumb = arm 141QEMU_ARCH_mips32le = mipsel # works with malta_defconfig 142QEMU_ARCH_mips32be = mips 143QEMU_ARCH_mipsn32le = mips64el 144QEMU_ARCH_mipsn32be = mips64 145QEMU_ARCH_mips64le = mips64el 146QEMU_ARCH_mips64be = mips64 147QEMU_ARCH_ppc = ppc 148QEMU_ARCH_ppc64 = ppc64 149QEMU_ARCH_ppc64le = ppc64 150QEMU_ARCH_riscv = riscv64 151QEMU_ARCH_riscv32 = riscv32 152QEMU_ARCH_riscv64 = riscv64 153QEMU_ARCH_s390x = s390x 154QEMU_ARCH_s390 = s390x 155QEMU_ARCH_loongarch = loongarch64 156QEMU_ARCH_sparc32 = sparc 157QEMU_ARCH_sparc64 = sparc64 158QEMU_ARCH_m68k = m68k 159QEMU_ARCH_sh4 = sh4 160QEMU_ARCH = $(QEMU_ARCH_$(XARCH)) 161 162QEMU_ARCH_USER_ppc64le = ppc64le 163QEMU_ARCH_USER_mipsn32le = mipsn32el 164QEMU_ARCH_USER_mipsn32be = mipsn32 165QEMU_ARCH_USER = $(or $(QEMU_ARCH_USER_$(XARCH)),$(QEMU_ARCH_$(XARCH))) 166 167QEMU_BIOS_DIR = /usr/share/edk2/ 168QEMU_BIOS_loongarch = $(QEMU_BIOS_DIR)/loongarch64/OVMF_CODE.fd 169 170ifneq ($(QEMU_BIOS_$(XARCH)),) 171QEMU_ARGS_BIOS = -bios $(QEMU_BIOS_$(XARCH)) 172endif 173 174# QEMU_ARGS : some arch-specific args to pass to qemu 175QEMU_ARGS_i386 = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)" 176QEMU_ARGS_x86_64 = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)" 177QEMU_ARGS_x86 = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)" 178QEMU_ARGS_arm64 = -M virt -cpu cortex-a53 -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)" 179QEMU_ARGS_arm = -M virt -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)" 180QEMU_ARGS_armthumb = -M virt -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)" 181QEMU_ARGS_mips32le = -M malta -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)" 182QEMU_ARGS_mips32be = -M malta -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)" 183QEMU_ARGS_mipsn32le = -M malta -cpu 5KEc -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)" 184QEMU_ARGS_mipsn32be = -M malta -cpu I6400 -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)" 185QEMU_ARGS_mips64le = -M malta -cpu I6400 -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)" 186QEMU_ARGS_mips64be = -M malta -cpu 5KEc -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)" 187QEMU_ARGS_ppc = -M g3beige -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 188QEMU_ARGS_ppc64 = -M powernv -append "console=hvc0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 189QEMU_ARGS_ppc64le = -M powernv -append "console=hvc0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 190QEMU_ARGS_riscv = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 191QEMU_ARGS_riscv32 = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 192QEMU_ARGS_riscv64 = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 193QEMU_ARGS_s390x = -M s390-ccw-virtio -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 194QEMU_ARGS_s390 = -M s390-ccw-virtio -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 195QEMU_ARGS_loongarch = -M virt -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 196QEMU_ARGS_sparc32 = -M SS-5 -m 256M -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 197QEMU_ARGS_sparc64 = -M sun4u -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 198QEMU_ARGS_m68k = -M virt -append "console=ttyGF0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 199QEMU_ARGS_sh4 = -M r2d -serial file:/dev/stdout -append "console=ttySC1,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" 200QEMU_ARGS = -m 1G $(QEMU_ARGS_$(XARCH)) $(QEMU_ARGS_BIOS) $(QEMU_ARGS_EXTRA) 201 202# OUTPUT is only set when run from the main makefile, otherwise 203# it defaults to this nolibc directory. 204OUTPUT ?= $(CURDIR)/ 205 206ifeq ($(V),1) 207Q= 208else 209Q=@ 210endif 211 212CFLAGS_i386 = $(call cc-option,-m32) 213CFLAGS_arm = -marm 214CFLAGS_armthumb = -mthumb -march=armv6t2 215CFLAGS_ppc = -m32 -mbig-endian -mno-vsx $(call cc-option,-mmultiple) 216CFLAGS_ppc64 = -m64 -mbig-endian -mno-vsx $(call cc-option,-mmultiple) 217CFLAGS_ppc64le = -m64 -mlittle-endian -mno-vsx $(call cc-option,-mabi=elfv2) 218CFLAGS_s390x = -m64 219CFLAGS_s390 = -m31 220CFLAGS_mips32le = -EL -mabi=32 -fPIC 221CFLAGS_mips32be = -EB -mabi=32 222CFLAGS_mipsn32le = -EL -mabi=n32 -fPIC -march=mips64r2 223CFLAGS_mipsn32be = -EB -mabi=n32 -march=mips64r6 224CFLAGS_mips64le = -EL -mabi=64 -march=mips64r6 225CFLAGS_mips64be = -EB -mabi=64 -march=mips64r2 226CFLAGS_sparc32 = $(call cc-option,-m32) 227CFLAGS_sh4 = -ml -m4 228ifeq ($(origin XARCH),command line) 229CFLAGS_XARCH = $(CFLAGS_$(XARCH)) 230endif 231 232include Makefile.include 233 234CFLAGS ?= $(CFLAGS_NOLIBC_TEST) $(CFLAGS_XARCH) $(CFLAGS_EXTRA) 235LDFLAGS := 236 237LIBGCC := -lgcc 238 239ifneq ($(LLVM),) 240# Not needed for clang 241LIBGCC := 242endif 243 244# Modify CFLAGS based on LLVM= 245include $(srctree)/tools/scripts/Makefile.include 246 247# GCC uses "s390", clang "systemz" 248CLANG_CROSS_FLAGS := $(subst --target=s390-linux,--target=systemz-linux,$(CLANG_CROSS_FLAGS)) 249 250REPORT ?= awk '/\[OK\][\r]*$$/{p++} /\[FAIL\][\r]*$$/{if (!f) printf("\n"); f++; print;} /\[SKIPPED\][\r]*$$/{s++} \ 251 END{ printf("\n%3d test(s): %3d passed, %3d skipped, %3d failed => status: ", p+s+f, p, s, f); \ 252 if (f || !p) printf("failure\n"); else if (s) printf("warning\n"); else printf("success\n");; \ 253 printf("\nSee all results in %s\n", ARGV[1]); }' 254 255help: 256 @echo "Supported targets under selftests/nolibc:" 257 @echo " all call the \"run\" target below" 258 @echo " help this help" 259 @echo " sysroot create the nolibc sysroot here (uses \$$ARCH)" 260 @echo " nolibc-test build the executable (uses \$$CC and \$$CROSS_COMPILE)" 261 @echo " libc-test build an executable using the compiler's default libc instead" 262 @echo " run-user runs the executable under QEMU (uses \$$XARCH, \$$TEST)" 263 @echo " initramfs.cpio prepare the initramfs archive with nolibc-test" 264 @echo " initramfs prepare the initramfs tree with nolibc-test" 265 @echo " defconfig create a fresh new default config (uses \$$XARCH)" 266 @echo " kernel (re)build the kernel (uses \$$XARCH)" 267 @echo " kernel-standalone (re)build the kernel with the initramfs (uses \$$XARCH)" 268 @echo " run runs the kernel in QEMU after building it (uses \$$XARCH, \$$TEST)" 269 @echo " rerun runs a previously prebuilt kernel in QEMU (uses \$$XARCH, \$$TEST)" 270 @echo " clean clean the sysroot, initramfs, build and output files" 271 @echo "" 272 @echo "The output file is \"run.out\". Test ranges may be passed using \$$TEST." 273 @echo "" 274 @echo "Currently using the following variables:" 275 @echo " ARCH = $(ARCH)" 276 @echo " XARCH = $(XARCH)" 277 @echo " CROSS_COMPILE = $(CROSS_COMPILE)" 278 @echo " CC = $(CC)" 279 @echo " OUTPUT = $(OUTPUT)" 280 @echo " TEST = $(TEST)" 281 @echo " QEMU_ARCH = $(if $(QEMU_ARCH),$(QEMU_ARCH),UNKNOWN_ARCH) [determined from \$$XARCH]" 282 @echo " IMAGE_NAME = $(if $(IMAGE_NAME),$(IMAGE_NAME),UNKNOWN_ARCH) [determined from \$$XARCH]" 283 @echo "" 284 285all: run 286 287sysroot: sysroot/$(ARCH)/include 288 289sysroot/$(ARCH)/include: 290 $(Q)rm -rf sysroot/$(ARCH) sysroot/sysroot 291 $(QUIET_MKDIR)mkdir -p sysroot 292 $(Q)$(MAKE) -C $(srctree) outputmakefile 293 $(Q)$(MAKE) -C $(srctree)/tools/include/nolibc ARCH=$(ARCH) OUTPUT=$(CURDIR)/sysroot/ headers_standalone headers_check 294 $(Q)mv sysroot/sysroot sysroot/$(ARCH) 295 296ifneq ($(NOLIBC_SYSROOT),0) 297nolibc-test: nolibc-test.c nolibc-test-linkage.c sysroot/$(ARCH)/include 298 $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \ 299 -nostdlib -nostdinc -static -Isysroot/$(ARCH)/include nolibc-test.c nolibc-test-linkage.c $(LIBGCC) 300else 301nolibc-test: nolibc-test.c nolibc-test-linkage.c 302 $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \ 303 -nostdlib -static -include $(srctree)/tools/include/nolibc/nolibc.h nolibc-test.c nolibc-test-linkage.c $(LIBGCC) 304endif 305 306libc-test: nolibc-test.c nolibc-test-linkage.c 307 $(QUIET_CC)$(HOSTCC) -o $@ nolibc-test.c nolibc-test-linkage.c 308 309# local libc-test 310run-libc-test: libc-test 311 $(Q)./libc-test > "$(CURDIR)/run.out" || : 312 $(Q)$(REPORT) $(CURDIR)/run.out 313 314# local nolibc-test 315run-nolibc-test: nolibc-test 316 $(Q)./nolibc-test > "$(CURDIR)/run.out" || : 317 $(Q)$(REPORT) $(CURDIR)/run.out 318 319# qemu user-land test 320run-user: nolibc-test 321 $(Q)qemu-$(QEMU_ARCH_USER) ./nolibc-test > "$(CURDIR)/run.out" || : 322 $(Q)$(REPORT) $(CURDIR)/run.out 323 324initramfs.cpio: kernel nolibc-test 325 $(QUIET_GEN)echo 'file /init nolibc-test 755 0 0' | $(objtree)/usr/gen_init_cpio - > initramfs.cpio 326 327initramfs: nolibc-test 328 $(QUIET_MKDIR)mkdir -p initramfs 329 $(call QUIET_INSTALL, initramfs/init) 330 $(Q)cp nolibc-test initramfs/init 331 332defconfig: 333 $(Q)$(MAKE) -C $(srctree) ARCH=$(ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE) $(DEFCONFIG) 334 $(Q)if [ -n "$(EXTRACONFIG)" ]; then \ 335 $(srctree)/scripts/config --file $(objtree)/.config $(EXTRACONFIG); \ 336 $(MAKE) -C $(srctree) ARCH=$(ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE) olddefconfig < /dev/null; \ 337 fi 338 339kernel: 340 $(Q)$(MAKE) -C $(srctree) ARCH=$(ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE) $(IMAGE_NAME) < /dev/null 341 342kernel-standalone: initramfs 343 $(Q)$(MAKE) -C $(srctree) ARCH=$(ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE) $(IMAGE_NAME) CONFIG_INITRAMFS_SOURCE=$(CURDIR)/initramfs < /dev/null 344 345# run the tests after building the kernel 346run: kernel initramfs.cpio 347 $(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(IMAGE)" -initrd initramfs.cpio -serial file:/dev/stdout $(QEMU_ARGS) > "$(CURDIR)/run.out" 348 $(Q)$(REPORT) $(CURDIR)/run.out 349 350# re-run the tests from an existing kernel 351rerun: 352 $(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(IMAGE)" -initrd initramfs.cpio -serial file:/dev/stdout $(QEMU_ARGS) > "$(CURDIR)/run.out" 353 $(Q)$(REPORT) $(CURDIR)/run.out 354 355# report with existing test log 356report: 357 $(Q)$(REPORT) $(CURDIR)/run.out 358 359clean: 360 $(call QUIET_CLEAN, sysroot) 361 $(Q)rm -rf sysroot 362 $(call QUIET_CLEAN, nolibc-test) 363 $(Q)rm -f nolibc-test 364 $(call QUIET_CLEAN, libc-test) 365 $(Q)rm -f libc-test 366 $(call QUIET_CLEAN, initramfs.cpio) 367 $(Q)rm -rf initramfs.cpio 368 $(call QUIET_CLEAN, initramfs) 369 $(Q)rm -rf initramfs 370 $(call QUIET_CLEAN, run.out) 371 $(Q)rm -rf run.out 372 373.PHONY: sysroot/$(ARCH)/include 374