Skip to main content

28 Control and Status Registers

The following code sample shows how to enable timer interrupts, set and wait for a timer interrupt to occur:

.equ RTC_BASE, 0x40000000
.equ TIMER_BASE, 0x40004000

# setup machine trap vector
1: auipc t0, %pcrel_hi(mtvec) # load mtvec(hi)
addi t0, t0, %pcrel_lo(1b) # load mtvec(lo)
csrrw zero, mtvec, t0

# set mstatus.MIE=1 (enable M mode interrupt)
li t0, 8
csrrs zero, mstatus, t0

# set mie.MTIE=1 (enable M mode timer interrupts)
li t0, 128
csrrs zero, mie, t0

# read from mtime
li a0, RTC_BASE
ld a1, 0(a0)

# write to mtimecmp
li a0, TIMER_BASE
li t0, 1000000000
add a1, a1, t0
sd a1, 0(a0)

# loop
loop:
wfi
j loop

# break on interrupt
mtvec:
csrrc t0, mcause, zero
bgez t0, fail # interrupt causes are less than zero
slli t0, t0, 1 # shift off high bit
srli t0, t0, 1
li t1, 7 # check this is an m_timer interrupt
bne t0, t1, fail
j pass

pass:
la a0, pass_msg
jal puts
j shutdown

fail:
la a0, fail_msg
jal puts
j shutdown

.section .rodata

pass_msg:
.string "PASS\n"

fail_msg:
.string "FAIL\n"