Currently the boot.S code assumes everything starts at EL1. This will break things like the memory test which will barf on unaligned memory access when run at a higher level. Adapt the boot code to do some basic verification of the starting mode and the minimal configuration to move to the lower exception levels. With this we can run the memory test with: -M virt,secure=on -M virt,secure=on,virtualization=on -M virt,virtualisation=on If a test needs to be at a particular EL it can use the semihosting command line to indicate the level we should execute in. Cc: Julian Armistead <julian.armistead@linaro.org> Cc: Jim MacArthur <jim.macarthur@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-ID: <20250603110204.838117-4-alex.bennee@linaro.org>
135 lines
4.6 KiB
Text
135 lines
4.6 KiB
Text
#
|
|
# Aarch64 system tests
|
|
#
|
|
|
|
AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
|
|
AARCH64_SYSTEM_SRC=$(AARCH64_SRC)/system
|
|
|
|
VPATH+=$(AARCH64_SYSTEM_SRC)
|
|
|
|
# These objects provide the basic boot code and helper functions for all tests
|
|
CRT_OBJS=boot.o
|
|
|
|
AARCH64_TEST_C_SRCS=$(wildcard $(AARCH64_SYSTEM_SRC)/*.c)
|
|
AARCH64_TEST_S_SRCS=$(AARCH64_SYSTEM_SRC)/mte.S
|
|
|
|
AARCH64_C_TESTS = $(patsubst $(AARCH64_SYSTEM_SRC)/%.c, %, $(AARCH64_TEST_C_SRCS))
|
|
AARCH64_S_TESTS = $(patsubst $(AARCH64_SYSTEM_SRC)/%.S, %, $(AARCH64_TEST_S_SRCS))
|
|
|
|
AARCH64_TESTS = $(AARCH64_C_TESTS)
|
|
AARCH64_TESTS += $(AARCH64_S_TESTS)
|
|
|
|
CRT_PATH=$(AARCH64_SYSTEM_SRC)
|
|
LINK_SCRIPT=$(AARCH64_SYSTEM_SRC)/kernel.ld
|
|
LDFLAGS=-Wl,-T$(LINK_SCRIPT)
|
|
TESTS+=$(AARCH64_TESTS) $(MULTIARCH_TESTS)
|
|
EXTRA_RUNS+=$(MULTIARCH_RUNS)
|
|
CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
|
|
LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
|
|
|
|
config-cc.mak: Makefile
|
|
$(quiet-@)( \
|
|
$(call cc-option,-march=armv8.3-a, CROSS_CC_HAS_ARMV8_3); \
|
|
$(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE)) 3> config-cc.mak
|
|
-include config-cc.mak
|
|
|
|
# building head blobs
|
|
.PRECIOUS: $(CRT_OBJS)
|
|
|
|
%.o: $(CRT_PATH)/%.S
|
|
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -x assembler-with-cpp -Wa,--noexecstack -c $< -o $@
|
|
|
|
# Build and link the tests
|
|
%: %.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS)
|
|
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
|
|
|
|
memory: CFLAGS+=-DCHECK_UNALIGNED=1
|
|
|
|
memory-sve: memory.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS)
|
|
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
|
|
|
|
memory-sve: CFLAGS+=-DCHECK_UNALIGNED=1 -march=armv8.1-a+sve -O3
|
|
|
|
TESTS+=memory-sve
|
|
|
|
# Running
|
|
QEMU_BASE_MACHINE=-M virt -cpu max -display none
|
|
QEMU_BASE_ARGS=-semihosting-config enable=on,target=native,chardev=output
|
|
QEMU_OPTS+=$(QEMU_BASE_MACHINE) $(QEMU_BASE_ARGS) -kernel
|
|
|
|
# console test is manual only
|
|
QEMU_SEMIHOST=-serial none -chardev stdio,mux=on,id=stdio0 -semihosting-config enable=on,chardev=stdio0 -mon chardev=stdio0,mode=readline
|
|
run-semiconsole: QEMU_OPTS=$(QEMU_BASE_MACHINE) $(QEMU_SEMIHOST) -kernel
|
|
run-semiconsole: semiconsole
|
|
$(call skip-test, $<, "MANUAL ONLY")
|
|
$(if $(V),@printf " %-7s %s %s\n" "TO RUN" $(notdir $(QEMU)) "$(QEMU_OPTS) $<")
|
|
run-plugin-semiconsole-with-%: semiconsole
|
|
$(call skip-test, $<, "MANUAL ONLY")
|
|
|
|
# vtimer test needs EL2
|
|
QEMU_EL2_MACHINE=-machine virt,virtualization=on,gic-version=2 -cpu cortex-a57 -smp 4
|
|
QEMU_EL2_BASE_ARGS=-semihosting-config enable=on,target=native,chardev=output,arg="2"
|
|
run-vtimer: QEMU_OPTS=$(QEMU_EL2_MACHINE) $(QEMU_EL2_BASE_ARGS) -kernel
|
|
|
|
# Simple Record/Replay Test
|
|
.PHONY: memory-record
|
|
run-memory-record: memory-record memory
|
|
$(call run-test, $<, \
|
|
$(QEMU) -monitor none -display none \
|
|
-chardev file$(COMMA)path=$<.out$(COMMA)id=output \
|
|
-icount shift=5$(COMMA)rr=record$(COMMA)rrfile=record.bin \
|
|
$(QEMU_OPTS) memory)
|
|
|
|
.PHONY: memory-replay
|
|
run-memory-replay: memory-replay run-memory-record
|
|
$(call run-test, $<, \
|
|
$(QEMU) -monitor none -display none \
|
|
-chardev file$(COMMA)path=$<.out$(COMMA)id=output \
|
|
-icount shift=5$(COMMA)rr=replay$(COMMA)rrfile=record.bin \
|
|
$(QEMU_OPTS) memory)
|
|
|
|
EXTRA_RUNS+=run-memory-replay
|
|
|
|
ifneq ($(CROSS_CC_HAS_ARMV8_3),)
|
|
pauth-3: CFLAGS += $(CROSS_CC_HAS_ARMV8_3)
|
|
# This test explicitly checks the output of the pauth operation so we
|
|
# must force the use of the QARMA5 algorithm for it.
|
|
run-pauth-3: QEMU_BASE_MACHINE=-M virt -cpu max,pauth-qarma5=on -display none
|
|
else
|
|
pauth-3:
|
|
$(call skip-test, "BUILD of $@", "missing compiler support")
|
|
run-pauth-3:
|
|
$(call skip-test, "RUN of pauth-3", "not built")
|
|
endif
|
|
|
|
ifneq ($(CROSS_CC_HAS_ARMV8_MTE),)
|
|
QEMU_MTE_ENABLED_MACHINE=-M virt,mte=on -cpu max -display none
|
|
QEMU_OPTS_WITH_MTE_ON = $(QEMU_MTE_ENABLED_MACHINE) $(QEMU_BASE_ARGS) -kernel
|
|
mte: CFLAGS+=-march=armv8.5-a+memtag
|
|
mte: mte.S $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS)
|
|
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
|
|
|
|
run-mte: QEMU_OPTS=$(QEMU_OPTS_WITH_MTE_ON)
|
|
run-mte: mte
|
|
|
|
ifeq ($(GDB_SUPPORTS_MTE_IN_BAREMETAL),y)
|
|
run-gdbstub-mte: QEMU_OPTS=$(QEMU_OPTS_WITH_MTE_ON)
|
|
run-gdbstub-mte: mte
|
|
$(call run-test, $@, $(GDB_SCRIPT) \
|
|
--output run-gdbstub-mte.out \
|
|
--gdb $(GDB) \
|
|
--qemu $(QEMU) --qargs "-chardev null$(COMMA)id=output $(QEMU_OPTS)" \
|
|
--bin $< --test $(AARCH64_SRC)/gdbstub/test-mte.py -- --mode=system, \
|
|
gdbstub MTE support)
|
|
|
|
EXTRA_RUNS += run-gdbstub-mte
|
|
else # !GDB_SUPPORTS_MTE_IN_BAREMETAL
|
|
run-gdbstub-mte:
|
|
$(call skip-test "RUN of gdbstub-mte", "GDB does not support MTE in baremetal!")
|
|
endif
|
|
else # !CROSS_CC_HAS_ARMV8_MTE
|
|
mte:
|
|
$(call skip-test, "BUILD of $@", "missing compiler support")
|
|
run-mte:
|
|
$(call skip-test, "RUN of mte", "not build")
|
|
endif
|