summaryrefslogtreecommitdiff
path: root/software/first/setup_timer_irq.S
blob: 4ae714f60624bbce4a8cb3cd7b31a572683b2507 (plain)
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