mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00

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>
73 lines
1.5 KiB
ArmAsm
73 lines
1.5 KiB
ArmAsm
/*
|
|
* 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
|