Browse Source
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
committed by
Alistair Francis
2 changed files with 77 additions and 0 deletions
@ -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…
Reference in new issue