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
|
.section .text
.align 2
.global setup_timer_irq
.include "memory_map.inc"
setup_timer_irq:
addi sp, sp, -16 # Allocate stack frame
sw ra, 12(sp) # save return address to the stack
lw t0, irq_handler # load address of irq_handler
slli t0, t0, 1 # shift address left by one; LSB will be 0 which is direct mode (what we want)
csrw mtvec, t0 # write handler address and mode
# Here we cannot use csrsi because it can only set up to 5 bits
li t0, 0x80 # set 7th bit (indexed from 0)
csrw mie, t0 # activate machine timer interrupt
# write high value to the timercmp just to be sure we don't
# trigger an interrupt by mistake
li t0, 0x7FFFFFFF # high number
li t1, 0xFFFFFFFF # high number
li t2, MTIMECMP # load address of timecmp register
sw t0, 4(t2) # store the first number to the upper part first
sw t1, 0(t2) # then the second to the lower part
csrsi mstatus, 0x4 # set 3rd bit to activate machine interrupts.
lw ra, 12(sp) # load return address
addi sp, sp, 16 # deallocate stack frame
ret
irq_handler:
mret
|