Add the boot code and semihosting helpers needed to run the multiarch system tests on riscv64, and add riscv64 to MULTIARCH_SOFTMMU_TARGETS. The aarch64 makefile was used as a guide for the make rules.
boot.S does not clear bss as the libmem plugin test would count the stores and fail with a mismatch. Instead the BSS is described as PT_LOAD, so the QEMU ELF loader fills the region with zero, the same as aarch64 and loongarch64. Signed-off-by: Joel Stanley <[email protected]> --- tests/tcg/riscv64/system.c | 30 +++++++++++++++++ tests/tcg/Makefile.target | 2 +- tests/tcg/riscv64/Makefile.softmmu-target | 40 ++++++++++++----------- tests/tcg/riscv64/boot.S | 23 +++++++++++++ 4 files changed, 75 insertions(+), 20 deletions(-) create mode 100644 tests/tcg/riscv64/system.c create mode 100644 tests/tcg/riscv64/boot.S diff --git a/tests/tcg/riscv64/system.c b/tests/tcg/riscv64/system.c new file mode 100644 index 000000000000..08196a540f96 --- /dev/null +++ b/tests/tcg/riscv64/system.c @@ -0,0 +1,30 @@ +/* + * RISC-V semihosting support for multiarch test suite + * + * Copyright 2026 Tenstorrent USA Inc + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "semicall.h" + +#define SYS_WRITEC 0x3 +#define SYS_EXIT 0x18 + +#define ADP_Stopped_ApplicationExit 0x20026 + +void __sys_outc(char c) +{ + __semi_call(SYS_WRITEC, (uintptr_t)&c); +} + +void _exit(int code) +{ + const uintptr_t args[2] = { ADP_Stopped_ApplicationExit, (uintptr_t)code }; + + __semi_call(SYS_EXIT, (uintptr_t)args); + + /* Hang if QEMU fails to exit */ + while (1) { + asm volatile("wfi"); + } +} diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target index 1b83824ff4e7..d4dd0fec650d 100644 --- a/tests/tcg/Makefile.target +++ b/tests/tcg/Makefile.target @@ -129,7 +129,7 @@ else EXTRA_CFLAGS += -ffreestanding -fno-stack-protector # We skip the multiarch tests if the target hasn't provided a boot.S -MULTIARCH_SOFTMMU_TARGETS = i386 alpha aarch64 arm loongarch64 s390x x86_64 +MULTIARCH_SOFTMMU_TARGETS = i386 alpha aarch64 arm loongarch64 s390x x86_64 riscv64 ifneq ($(filter $(TARGET_NAME),$(MULTIARCH_SOFTMMU_TARGETS)),) -include $(SRC_PATH)/tests/tcg/minilib/Makefile.target diff --git a/tests/tcg/riscv64/Makefile.softmmu-target b/tests/tcg/riscv64/Makefile.softmmu-target index f2850a194084..82e8fe2664b0 100644 --- a/tests/tcg/riscv64/Makefile.softmmu-target +++ b/tests/tcg/riscv64/Makefile.softmmu-target @@ -5,9 +5,11 @@ TEST_SRC = $(SRC_PATH)/tests/tcg/riscv64 VPATH += $(TEST_SRC) +CRT_OBJS = boot.o system.o + LINK_SCRIPT = $(TEST_SRC)/semihost.ld -LDFLAGS = -T $(LINK_SCRIPT) -CFLAGS += -g -Og +LDFLAGS = -Wl,-T$(LINK_SCRIPT) -static -nostdlib $(MINILIB_OBJS) -lgcc +CFLAGS += -g -Og $(MINILIB_INC) # Used by riscv64 tcg tests and shared 'multiarch' tests QEMU_CPU = rv64 @@ -53,23 +55,23 @@ test-zicclsm-off.o: test-zicclsm.S $(call quiet-command, \ $(CC) $(CFLAGS) $< -Wa$(COMMA)--noexecstack -c -o $@, CC, $@) -EXTRA_RUNS += run-plugin-doubletrap -run-plugin-doubletrap: doubletrap - $(call run-test, $<, \ - $(QEMU) -monitor none -display none \ - -chardev file$(COMMA)path=$<.out$(COMMA)id=output \ - -plugin ../plugins/libdiscons.so -d plugin -D $<.pout \ - $(QEMU_OPTS) $<) - -EXTRA_RUNS += run-plugin-interruptedmemory -run-plugin-interruptedmemory: interruptedmemory - $(call run-test, $<, \ - $(QEMU) -monitor none -display none \ - -chardev file$(COMMA)path=$<.out$(COMMA)id=output \ - -plugin ../plugins/libdiscons.so -d plugin -D $<.pout \ - $(QEMU_OPTS) $<) +ifeq ($(CONFIG_PLUGIN),y) +EXTRA_RUNS_WITH_PLUGIN += run-plugin-doubletrap-with-libdiscons.so \ + run-plugin-interruptedmemory-with-libdiscons.so +endif CLEANFILES += interruptedmemory doubletrap -# We don't currently support the multiarch system tests -undefine MULTIARCH_TESTS +# Multiarch tests +TESTS += $(MULTIARCH_TESTS) +EXTRA_RUNS += $(MULTIARCH_RUNS) + +.PRECIOUS: $(CRT_OBJS) + +# Build and link the multiarch tests +%: %.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS) + $(call quiet-command, \ + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) $(CRT_OBJS), CC, $@) + +# Default is zicclsm=true, so misaligned accesses must work +memory: private CFLAGS += -DCHECK_UNALIGNED=1 diff --git a/tests/tcg/riscv64/boot.S b/tests/tcg/riscv64/boot.S new file mode 100644 index 000000000000..b403549345a1 --- /dev/null +++ b/tests/tcg/riscv64/boot.S @@ -0,0 +1,23 @@ +/* + * RISC-V boot code for multiarch test suite + * + * Copyright 2026 Tenstorrent USA Inc + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#define MSTATUS_VS 0x00000600 +#define MSTATUS_FS 0x00006000 + +.section .text._start + .global _start + .type _start, @function +_start: + /* Enable FPU and vector unit */ + li t0, (MSTATUS_FS | MSTATUS_VS) + csrs mstatus, t0 + la sp, __stack_top + call main + +exit: + /* exit with main()'s return code */ + call _exit -- 2.47.3
