Skip to content

Commit 7886682

Browse files
committed
Fix incorrect U-mode timer behaviour
1 parent ead1d87 commit 7886682

File tree

3 files changed

+76
-13
lines changed

3 files changed

+76
-13
lines changed

asm/timer.s

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# https://danielmangum.com/posts/risc-v-bytes-timer-interrupts/
2+
3+
.option norvc
4+
.section .data
5+
.section .text.init
6+
.global _start
7+
8+
_start:
9+
li a0, 0
10+
11+
# set timer for 1 second in the future
12+
li t0, 0xf0000008
13+
li t1, 1000
14+
sw t1, 0(t0)
15+
sw zero, 4(t0)
16+
17+
# set up trap vector
18+
la t0, mtrap
19+
csrw mtvec, t0
20+
21+
# set mstatus.MPP to U
22+
li t0, 0x1800
23+
csrc mstatus, t0
24+
25+
# enable mie.MTIE
26+
li t0, 0x80
27+
csrs mie, t0
28+
29+
# jump to user mode
30+
la t1, user
31+
csrw mepc, t1
32+
mret
33+
34+
mtrap:
35+
# increment counter
36+
addi a0, a0, 1
37+
38+
# reset time to 0
39+
li t0, 0xf0000000
40+
sw zero, 0(t0)
41+
sw zero, 4(t0)
42+
43+
mret
44+
45+
user:
46+
j user

src/debugger.mlog.jinja

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ loop:
148148
op shl timeh timeh 32
149149
op add time time timeh
150150

151+
read mtimecmp CPU "mtimecmp"
152+
read mtimecmph CPU "mtimecmph"
153+
op shl mtimecmph mtimecmph 32
154+
op add mtimecmp mtimecmp mtimecmph
155+
151156
read instret CSRS "{{ 'instret'|csr }}"
152157
read instreth CSRS "{{ 'instreth'|csr }}"
153158
op shl instreth instreth 32
@@ -375,13 +380,16 @@ loop__no_mark_icache:
375380

376381
#{{'\n'}} {{ print(0, 17) }}
377382

378-
print "cycle = {0}\n"
379-
format cycle
383+
print "mtimecmp = {0}\n"
384+
format mtimecmp
380385

381-
print "time = {0}\n"
386+
print "time = {0}\n"
382387
format time
383388

384-
print "instret = {0}\n\n"
389+
print "cycle = {0}\n"
390+
format cycle
391+
392+
print "instret = {0}\n\n"
385393
format instret
386394

387395
#{{'\n'}} {{ print(0, 34) }}

src/main.mlog.jinja

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,24 +128,30 @@ main:
128128
op equal mtimeh_eq_mtimecmph mtimeh mtimecmph
129129
op greaterThanEq mtime_ge_mtimecmp mtime mtimecmp
130130

131-
op and mtip mtimeh_eq_mtimecmph mtime_ge_mtimecmp
132-
op or mtip mtip mtimeh_gt_mtimecmph
133-
op shl mtip mtip 7
131+
op and mip.mtip mtimeh_eq_mtimecmph mtime_ge_mtimecmp
132+
op or mip.mtip mip.mtip mtimeh_gt_mtimecmph
133+
op shl mip.mtip mip.mtip 7
134134

135135
read mip {{CSRS}} "{{ 'mip'|csr }}"
136136
op and mip mip 0b11111111111111111111111101111111
137-
op or mip mip mtip
137+
op or mip mip mip.mtip
138138
write mip {{CSRS}} "{{ 'mip'|csr }}"
139139

140140
# check if interrupts should fire
141141

142+
jump main__interrupts_user_mode lessThan privilege_mode 0b11
143+
op and mstatus.mie mstatus 0b1000
144+
jump main__skip_interrupts equal mstatus.mie 0
145+
main__interrupts_user_mode:
146+
142147
# timer interrupt
143148
read mie {{CSRS}} "{{ 'mie'|csr }}"
144-
op and mtie mie mtip
149+
op and mie.mtie mie mip.mtip
145150
set mcause 0x80000007 # machine timer interrupt
146151
set mtval 0
147-
jump trap notEqual mtie 0
152+
jump trap notEqual mie.mtie 0
148153

154+
main__skip_interrupts:
149155
main__skip_time_update:
150156

151157
set mtval pc
@@ -334,7 +340,11 @@ default_mtvec_handler:
334340

335341
illegal_instruction:
336342
set mcause 2
337-
set mtval 0 # TODO: return faulting instruction bits?
343+
# TODO: return faulting instruction bits?
344+
# continue into trap_without_mtval
345+
346+
trap_without_mtval:
347+
set mtval 0
338348
# continue into trap
339349

340350
trap:
@@ -1598,8 +1608,7 @@ ECALL:
15981608
# 0b1000 (8) = ecall from U-mode
15991609
# 0b1011 (11) = ecall from S-mode
16001610
op or mcause 0b1000 privilege_mode
1601-
set mtval 0
1602-
jump trap always
1611+
jump trap_without_mtval always
16031612

16041613
EBREAK:
16051614
set mcause 3 # breakpoint

0 commit comments

Comments
 (0)