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
>
>

Reply via email to