Browse Source

tests/tcg/riscv64: Add test for MEPC bit masking

Add a regression test to verify that MEPC properly masks the lower
bits when an address with mode bits is written to it, as required by
the RISC-V Privileged Architecture specification.

The test sets STVEC to an address with bit 0 set (vectored mode),
triggers an illegal instruction exception, copies STVEC to MEPC in the
trap handler, and verifies that MEPC masks bits [1:0] correctly for
IALIGN=32.

Without the fix, MEPC retains the mode bits (returns non-zero/FAIL).
With the fix, MEPC clears bits [1:0] (returns 0/PASS).

Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20250703182157.281320-3-charmitro@posteo.net>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
pull/292/head
Charalampos Mitrodimas 9 months ago
committed by Alistair Francis
parent
commit
a1f44e0c59
  1. 4
      tests/tcg/riscv64/Makefile.softmmu-target
  2. 73
      tests/tcg/riscv64/test-mepc-masking.S

4
tests/tcg/riscv64/Makefile.softmmu-target

@ -20,5 +20,9 @@ EXTRA_RUNS += run-issue1060
run-issue1060: issue1060
$(call run-test, $<, $(QEMU) $(QEMU_OPTS)$<)
EXTRA_RUNS += run-test-mepc-masking
run-test-mepc-masking: test-mepc-masking
$(call run-test, $<, $(QEMU) $(QEMU_OPTS)$<)
# We don't currently support the multiarch system tests
undefine MULTIARCH_TESTS

73
tests/tcg/riscv64/test-mepc-masking.S

@ -0,0 +1,73 @@
/*
* Test for MEPC masking bug fix
*
* This test verifies that MEPC properly masks the lower bits according
* to the RISC-V specification when vectored mode bits from STVEC are
* written to MEPC.
*/
.option norvc
.text
.global _start
_start:
/* Set up machine trap vector */
lla t0, machine_trap_handler
csrw mtvec, t0
/* Set STVEC with vectored mode (mode bits = 01) */
li t0, 0x80004001
csrw stvec, t0
/* Clear medeleg to handle exceptions in M-mode */
csrw medeleg, zero
/* Trigger illegal instruction exception */
.word 0xffffffff
test_completed:
/* Exit with result in a0 */
/* a0 = 0: success (bits [1:0] were masked) */
/* a0 != 0: failure (some bits were not masked) */
j _exit
machine_trap_handler:
/* Check if illegal instruction (mcause = 2) */
csrr t0, mcause
li t1, 2
bne t0, t1, skip_test
/* Test: Copy STVEC (with mode bits) to MEPC */
csrr t0, stvec /* t0 = 0x80004001 */
csrw mepc, t0 /* Write to MEPC */
csrr t1, mepc /* Read back MEPC */
/* Check if bits [1:0] are masked (IALIGN=32 without RVC) */
andi a0, t1, 3 /* a0 = 0 if both bits masked correctly */
/* Set correct return address */
lla t0, test_completed
csrw mepc, t0
skip_test:
mret
/* Exit with semihosting */
_exit:
lla a1, semiargs
li t0, 0x20026 /* ADP_Stopped_ApplicationExit */
sd t0, 0(a1)
sd a0, 8(a1)
li a0, 0x20 /* TARGET_SYS_EXIT_EXTENDED */
/* Semihosting call sequence */
.balign 16
slli zero, zero, 0x1f
ebreak
srai zero, zero, 0x7
j .
.data
.balign 8
semiargs:
.space 16
Loading…
Cancel
Save