summaryrefslogtreecommitdiff
path: root/software/first/setup_timer_irq.S
diff options
context:
space:
mode:
authorSilvan Jegen <s.jegen@gmail.com>2019-08-01 18:41:21 +0200
committerSilvan Jegen <s.jegen@gmail.com>2019-08-01 19:11:27 +0200
commitaa72093ffe1abafd605b5ec3b2d50c20b11c14a9 (patch)
tree39eb51dc8ec29d5f75c9c86fb7e171ad24504675 /software/first/setup_timer_irq.S
parent3f8b15773b76750d0e877fac502277e2d5dcf791 (diff)
Start implementing irq setup and handling
Diffstat (limited to 'software/first/setup_timer_irq.S')
-rw-r--r--software/first/setup_timer_irq.S34
1 files changed, 34 insertions, 0 deletions
diff --git a/software/first/setup_timer_irq.S b/software/first/setup_timer_irq.S
new file mode 100644
index 0000000..4ae714f
--- /dev/null
+++ b/software/first/setup_timer_irq.S
@@ -0,0 +1,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