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