1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
la t0,handler
csrw mtvec,t0 # Set trap handler address and mode (0/direct)
li t0,0x400
csrc mstatush,t0 # Enable trap handler
li t0,0x80
csrw mie,t0 # Enable machine timer interrupt and disable others
la t1,mmio
csrw 0x801,t1 # Set MMIO base address
lw t0,2(t1) # Load current mtime
addi t0,t0,1
sw t0,10(t1) # Set mtimecmp for 1 second in the future
csrsi mstatus,8 # Enable interrupts globally
task1:
li a0,1
li a7,1
ecall
j task1
task2:
li a0,2
li a7,1
ecall
j task2
.balign 4
handler:
lw t0,2(t1) # Load current mtime
addi t0,t0,1
sw t0,10(t1) # Set mtimecmp for 1 second in the future
la t0,currenttask
lw t2,0(t0) # Get current task number
addi t2,t2,1 # Flip to the other task
andi t2,t2,1
sw t2,0(t0) # Write the number back
beqz t2,handler_return1
j handler_return2
handler_return1:
la a0,task1
csrw mepc,a0 # Set return address to start of task 1
mret
handler_return2:
la a0,task2
csrw mepc,a0 # Set return address to start of task 2
mret
currenttask: .word 1
mmio:
|