mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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>
This commit is contained in:
committed by
Alistair Francis
parent
b3452452e6
commit
a1f44e0c59
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user