/ test / asm / interrupt_vectored.asm
interrupt_vectored.asm
  1  .include "init_regs.s"
  2  
  3  _start:
  4      INIT_REGS_LOAD
  5  
  6      # fibonacci spiced with interrupt handler (also with fibonacci)
  7      li x1, 0x201
  8      csrw mtvec, x1
  9      li x1, 0x203
 10      csrw mtvec, x1
 11      csrr x16, mtvec     # since mtvec is WARL, should stay 0x201
 12      ecall               # synchronous exception jumps to 0x200 + 0x0
 13  
 14  interrupts:
 15      li x27, 0       # handler count
 16      li x30, 0       # interrupt count
 17      li x31, 0xde    # branch guard
 18  
 19      csrsi mstatus, 0x8  # machine interrupt enable
 20      csrr x29, mstatus
 21      li x1, 0x30000
 22      csrw mie, x1        # enable custom interrupt 0 and 1
 23      li x1, 0
 24      li x2, 1
 25      li x5, 4
 26      li x6, 7
 27      li x7, 0
 28      li x12, 4
 29      li x13, 7
 30      li x14, 0
 31  loop:
 32      add x3, x2, x1
 33      mv x1, x2
 34      mv x2, x3
 35      bne x2, x4, loop
 36  infloop:
 37      j infloop
 38  
 39  int0_handler:
 40      # save main loop register state
 41      mv x9, x1
 42      mv x10, x2
 43      mv x11, x3
 44  
 45      # check cause
 46      li x2, 0x80000010 # cause for 01,11
 47      csrr x3, mcause
 48      bne x2, x3, fail
 49  
 50      # fibonacci step
 51      beq x7, x8, skip
 52      add x7, x6, x5
 53      mv x5, x6
 54      mv x6, x7
 55  
 56  skip:
 57      # generate new mie mask
 58      andi x2, x30, 0x3
 59      bnez x2, fill_skip
 60      li x2, 0x3
 61      fill_skip:
 62      slli x2, x2, 16
 63      csrw mie, x2
 64  
 65      # clear interrupts
 66      csrr x1, mip
 67      srli x1, x1, 16
 68      andi x2, x1, 0x1
 69      beqz x2, skip_clear_edge
 70          addi x30, x30, 1
 71          li x2, 0x10000
 72          csrc mip, x2 # clear edge reported interrupt
 73      skip_clear_edge:
 74      andi x2, x1, 0x2
 75      beqz x2, skip_clear_level
 76          addi x30, x30, 1
 77          csrwi 0x7ff, 1 # clear level reported interrupt via custom csr
 78      skip_clear_level:
 79      addi x27, x27, 1
 80  
 81      # restore main loop register state
 82      mv x1, x9
 83      mv x2, x10
 84      mv x3, x11
 85      mret
 86  
 87  int1_handler:
 88      # save main loop register state
 89      mv x9, x1
 90      mv x10, x2
 91      mv x11, x3
 92  
 93      # check cause
 94      li x2, 0x80000011 # cause for 10
 95      csrr x3, mcause
 96      bne x2, x3, fail
 97  
 98      # fibonacci step
 99      beq x14, x15, skip
100      add x14, x13, x12
101      mv x12, x13
102      mv x13, x14
103      j skip
104  
105  ecall_handler:
106      li x17, 0x111
107      la x1, interrupts
108      csrw mepc, x1
109      mret
110  
111  fail:
112      csrwi 0x7ff, 2
113      j fail
114  
115  .org 0x200
116      j ecall_handler
117      nop
118      nop
119      nop
120      nop
121      nop
122      nop
123      nop
124      nop
125      nop
126      nop
127      nop
128      nop
129      nop
130      nop
131      j fail
132      j int0_handler
133      j int1_handler
134      li x31, 0xae  # should never happen
135  
136  INIT_REGS_ALLOCATION