On Fri, Jun 19, 2026 at 7:53 PM Nikita Shubin <[email protected]> wrote: > > Extend the TCG test infrastructure to support 32-bit RISC-V (riscv32) > system tests. > > - configure: Add riscv32 to probe_target_compiler() using the same > container (debian-all-test-cross) as riscv64, with cross prefix > riscv64-linux-gnu- (the compiler can generate 32-bit code with > -march=rv32imafdch -mabi=ilp32d). > > - tests/tcg/riscv32/: New directory with: > * Makefile.softmmu-target – build rules for 32-bit softmmu tests > * semihost.ld – linker script (same as riscv64, RAM at 0x80000000) > * test-semihosting-open.S – test for SYS_OPEN with auto length (-1) > > The semihosting test validates the fix for sign-extended 32-bit > pointers when running riscv32 guests on qemu-system-riscv32. > > CFLAGS and LDFLAGS are explicitly set for rv32imafdch/ilp32d ABI, > and LDFLAGS includes -melf32lriscv to produce 32-bit ELF. > > Signed-off-by: Nikita Shubin <[email protected]>
Reviewed-by: Alistair Francis <[email protected]> Alistair > --- > configure | 6 +++- > tests/tcg/riscv32/Makefile.softmmu-target | 30 +++++++++++++++++ > tests/tcg/riscv32/semihost.ld | 24 +++++++++++++ > tests/tcg/riscv32/test-semihosting-open.S | 56 > +++++++++++++++++++++++++++++++ > 4 files changed, 115 insertions(+), 1 deletion(-) > > diff --git a/configure b/configure > index d8bc10060e..2df0811b5d 100755 > --- a/configure > +++ b/configure > @@ -1405,7 +1405,7 @@ probe_target_compiler() { > mips) container_hosts=x86_64 ;; > ppc) container_hosts=x86_64 ;; > ppc64|ppc64le) container_hosts=x86_64 ;; > - riscv64) container_hosts=x86_64 ;; > + riscv32|riscv64) container_hosts=x86_64 ;; > s390x) container_hosts=x86_64 ;; > sh4) container_hosts=x86_64 ;; > sparc64) container_hosts=x86_64 ;; > @@ -1424,6 +1424,10 @@ probe_target_compiler() { > container_image=debian-all-test-cross > container_cross_prefix=aarch64-linux-gnu- > ;; > + riscv32) > + container_image=debian-all-test-cross > + container_cross_prefix=riscv64-linux-gnu- > + ;; > alpha|hppa|m68k|mips|mipsel|riscv64|sh4|sparc64) > container_image=debian-all-test-cross > ;; > diff --git a/tests/tcg/riscv32/Makefile.softmmu-target > b/tests/tcg/riscv32/Makefile.softmmu-target > new file mode 100644 > index 0000000000..eff5b000f0 > --- /dev/null > +++ b/tests/tcg/riscv32/Makefile.softmmu-target > @@ -0,0 +1,30 @@ > +# > +# SPDX-License-Identifier: GPL-2.0-or-later > +# > +# RISC-V 32-bit system tests > +# > + > +TEST_SRC = $(SRC_PATH)/tests/tcg/riscv32 > +VPATH += $(TEST_SRC) > + > +LINK_SCRIPT = $(TEST_SRC)/semihost.ld > +LDFLAGS = -T $(LINK_SCRIPT) > +CFLAGS += -g -Og > + > +%.o: %.S > + $(CC) $(CFLAGS) $< -Wa,--noexecstack -c -o $@ > +%: %.o $(LINK_SCRIPT) > + $(LD) $(LDFLAGS) $< -o $@ > + > +QEMU_OPTS += -M virt -display none -semihosting -device loader,file= > +# provide flags for riscv32 as we are using riscv64-linux-gnu- > +CFLAGS += -march=rv32imafdch -mabi=ilp32d > +LDFLAGS += -melf32lriscv > + > +EXTRA_RUNS += run-semihosting-open > +run-semihosting-open: test-semihosting-open > + $(call run-test, $<, \ > + $(QEMU) $(QEMU_OPTS)$<) > + > +# We don't currently support the multiarch system tests > +undefine MULTIARCH_TESTS > \ No newline at end of file > diff --git a/tests/tcg/riscv32/semihost.ld b/tests/tcg/riscv32/semihost.ld > new file mode 100644 > index 0000000000..ff3b786481 > --- /dev/null > +++ b/tests/tcg/riscv32/semihost.ld > @@ -0,0 +1,24 @@ > +/* > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > +ENTRY(_start) > + > +SECTIONS > +{ > + /* virt machine, RAM starts at 2gb */ > + . = 0x80000000; > + .text : { > + *(.text) > + } > + .rodata : { > + *(.rodata) > + } > + /* align r/w section to next 2mb */ > + . = ALIGN(1 << 21); > + .data : { > + *(.data) > + } > + .bss : { > + *(.bss) > + } > +} > diff --git a/tests/tcg/riscv32/test-semihosting-open.S > b/tests/tcg/riscv32/test-semihosting-open.S > new file mode 100644 > index 0000000000..acbb31c558 > --- /dev/null > +++ b/tests/tcg/riscv32/test-semihosting-open.S > @@ -0,0 +1,56 @@ > +/* > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > +.option norvc > +.text > +.global _start > +_start: > + # Argument block for SYS_OPEN (each arg is 4 bytes in RV32) > + la a1, open_args > + la t0, test_filename > + sw t0, 0(a1) # arg0: pointer to filename > + li t0, 4 # arg1: "w" (write, create, truncate) > + sw t0, 4(a1) > + li t0, -1 # arg2: auto length (-1 = 0xffffffff) > + sw t0, 8(a1) > + > + # SYS_OPEN semihosting call > + li a0, 0x01 > + .balign 16 > + slli zero, zero, 0x1f > + ebreak > + srai zero, zero, 0x7 > + > + # Check result: a0 should be a valid file descriptor (not -1) > + li t0, -1 > + beq a0, t0, fail > + > + # Success > + li a0, 0 > + j exit > + > +fail: > + li a0, 1 > + > +exit: > + # Extended semihosting exit > + la a1, semiargs > + li t0, 0x20026 # ADP_Stopped_ApplicationExit > + sw t0, 0(a1) > + sw a0, 4(a1) > + li a0, 0x20 # TARGET_SYS_EXIT_EXTENDED > + .balign 16 > + slli zero, zero, 0x1f > + ebreak > + srai zero, zero, 0x7 > + > + j . > + > +.data > +.balign 16 > +test_filename: > + .string "testfile.txt" > +open_args: > + .space 12 # 3 * 4 bytes > +semiargs: > + .space 8 # 2 * 4 bytes > > -- > 2.52.0 > >
