Skip to content

Commit 9d7f96d

Browse files
committed
Add misalignment test suite
Force a variable and a function placed at a misaligned address to trigger the all three misaligned traps. The test suite only tested the misalignment of instruction fetch and lw/sw instruction. The corresponding trap handler is called successfully to handle the trap.
1 parent e8c8ee9 commit 9d7f96d

File tree

5 files changed

+176
-0
lines changed

5 files changed

+176
-0
lines changed

src/emulate.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ static uint32_t *csr_get_ptr(riscv_t *rv, uint32_t csr)
218218
return (uint32_t *) (&rv->csr_misa);
219219

220220
/* Machine Trap Handling */
221+
case CSR_MEDELEG: /* Machine Exception Delegation Register */
222+
return (uint32_t *) (&rv->csr_medeleg);
223+
case CSR_MIDELEG: /* Machine Interrupt Delegation Register */
224+
return (uint32_t *) (&rv->csr_mideleg);
221225
case CSR_MSCRATCH: /* Machine Scratch Register */
222226
return (uint32_t *) (&rv->csr_mscratch);
223227
case CSR_MEPC: /* Machine Exception Program Counter */

tests/system/alignment/Makefile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
PREFIX ?= riscv32-unknown-elf-
2+
ARCH = -march=rv32izicsr
3+
LINKER_SCRIPT = linker.ld
4+
5+
DEBUG_CFLAGS = -g
6+
CFLAGS = -c
7+
LDFLAGS = -T
8+
EXEC = misalign.elf
9+
10+
CC = $(PREFIX)gcc
11+
AS = $(PREFIX)as
12+
LD = $(PREFIX)ld
13+
OBJDUMP = $(PREFIX)objdump
14+
15+
deps = main.o misalign.o
16+
17+
all:
18+
$(CC) $(DEBUG_CLAGS) $(CFLAGS) main.c
19+
$(AS) $(DEBUG_CLAGS) $(ARCH) misalign.S -o misalign.o
20+
$(LD) $(LDFLAGS) $(LINKER_SCRIPT) -o $(EXEC) $(deps)
21+
22+
dump:
23+
$(OBJDUMP) -Ds $(EXEC) | less
24+
25+
clean:
26+
rm $(EXEC) $(deps)

tests/system/alignment/linker.ld

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
OUTPUT_ARCH( "riscv" )
2+
3+
ENTRY(_start)
4+
5+
SECTIONS
6+
{
7+
. = 0x10000;
8+
.text : { *(.text) }
9+
. = 0x8000003;
10+
.misdata : { *(.misdata) }
11+
. = 0x10000007;
12+
.mistext : { *(.mistext) }
13+
.data : { *(.data) }
14+
.bss : { *(.bss) }
15+
}

tests/system/alignment/main.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#define write_csr(reg, val) ({ asm volatile("csrw " #reg ", %0" ::"rK"(val)); })
2+
3+
#define CAUSE_MISALIGNED_INSN_FETCH (1U << 0x0)
4+
#define CAUSE_MISALIGNED_LOAD (1U << 0x4)
5+
#define CAUSE_MISALIGNED_STORE (1U << 0x6)
6+
7+
#define printstr(ptr, length) \
8+
do { \
9+
asm volatile( \
10+
"add a7, x0, 0x40;" \
11+
"add a0, x0, 0x1;" /* stdout */ \
12+
"add a1, x0, %0;" \
13+
"mv a2, %1;" /* length character */ \
14+
"ecall;" \
15+
: \
16+
: "r"(ptr), "r"(length) \
17+
: "a0", "a1", "a2", "a7"); \
18+
} while (0)
19+
20+
#define TEST_OUTPUT(msg, length) printstr(msg, length)
21+
22+
#define TEST_LOGGER(msg) \
23+
{ \
24+
char _msg[] = msg; \
25+
TEST_OUTPUT(_msg, sizeof(_msg)); \
26+
}
27+
28+
extern int *misalign_data;
29+
30+
extern void misalign_func();
31+
32+
extern void misalign_trap_handler();
33+
34+
int main()
35+
{
36+
/* init s-mode trap handler */
37+
write_csr(stvec, misalign_trap_handler);
38+
write_csr(medeleg, CAUSE_MISALIGNED_INSN_FETCH | CAUSE_MISALIGNED_LOAD |
39+
CAUSE_MISALIGNED_STORE);
40+
41+
/* misalign load */
42+
const int x = *misalign_data;
43+
/* execute the registered trap handler is considered a pass (use gdb to
44+
* track) */
45+
TEST_LOGGER("MISALIGNED LOAD TEST PASSED!\n");
46+
47+
/* misalign store */
48+
char *ptr = (char *) misalign_data;
49+
*(int *) (ptr + 3) = x + 3;
50+
/* execute the registered trap handler is considered a pass (use gdb to
51+
* track) */
52+
TEST_LOGGER("MISALIGNED STORE TEST PASSED!\n");
53+
54+
/* misalign instuction fetch */
55+
misalign_func();
56+
/* execute the registered trap handler is considered a pass (use gdb to
57+
* track) */
58+
TEST_LOGGER("MISALIGNED INSTRUCTION FETCH TEST PASSED!\n");
59+
60+
return 0;
61+
}

tests/system/alignment/misalign.S

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
CAUSE_MISALIGNED_INSN_FETCH = 0x0
2+
CAUSE_MISALIGNED_LOAD = 0x4
3+
CAUSE_MISALIGNED_STORE = 0x6
4+
5+
.section .misdata, "aw", @progbits
6+
.global misalign_data
7+
.type misalign_data, @object
8+
misalign_data:
9+
.word = 0xBAAAAAAD
10+
. = 0x8000003 # force misaligned address
11+
12+
.section .mistext, "ax", @progbits
13+
.global misalign_func
14+
.type misalign_func, @function
15+
misalign_func:
16+
. = 0x10000007 # force misaligned address
17+
addi t0, t0, 1
18+
19+
.section .text
20+
.global _start
21+
_start:
22+
call main
23+
j exit
24+
25+
# Assume three traps are delegated to supervisor,
26+
# so handle them using supervisor CSR
27+
.global misalign_trap_handler
28+
misalign_trap_handler:
29+
csrr t0, scause
30+
31+
# Check for misaligned instruction fetch
32+
li t1, CAUSE_MISALIGNED_INSN_FETCH
33+
beq t0, t1, misaligned_insn_fetch_handler
34+
35+
# Check for misaligned load
36+
li t1, CAUSE_MISALIGNED_LOAD
37+
beq t0, t1, misaligned_load_handler
38+
39+
# Check for misaligned store
40+
li t1, CAUSE_MISALIGNED_STORE
41+
beq t0, t1, misaligned_store_handler
42+
43+
# If none of the above, exit failed
44+
fail:
45+
li a0, 1
46+
j exit
47+
48+
exit:
49+
li a7, 93
50+
ecall
51+
52+
misaligned_insn_fetch_handler:
53+
# simply jump back to caller since no really handling it
54+
# since the rest of instruction are also misaligned
55+
jalr zero, ra, 0
56+
57+
misaligned_load_handler:
58+
# Handle load misalignment: skip load
59+
csrr t0, sepc
60+
addi t0, t0, 4
61+
csrw sepc, t0
62+
sret
63+
64+
misaligned_store_handler:
65+
# Handle store misalignment: skip store
66+
csrr t0, sepc
67+
addi t0, t0, 4
68+
csrw sepc, t0
69+
sret
70+

0 commit comments

Comments
 (0)