.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