/ test / asm / interrupt.asm
interrupt.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, 0x200
  8      csrw mtvec, x1
  9      li x27, 0     # handler count
 10      li x30, 0     # interrupt count
 11      li x31, 0xde  # branch guard
 12      csrsi mstatus, 0x8 # machine interrupt enable
 13      csrr x29, mstatus
 14      li x1, 0x30000
 15      csrw mie, x1 # enable custom interrupt 0 and 1
 16      li x1, 0
 17      li x2, 1
 18      li x5, 4
 19      li x6, 7
 20      li x7, 0
 21  loop:
 22      add x3, x2, x1
 23      mv x1, x2
 24      mv x2, x3
 25      bne x2, x4, loop
 26  infloop:
 27      j infloop
 28  
 29  int_handler:
 30      # save main loop register state
 31      mv x9, x1
 32      mv x10, x2
 33      mv x11, x3
 34  
 35      csrr x28, mstatus
 36  
 37      # check cause
 38      csrr x1, mip
 39      csrr x2, mie
 40      and x1, x1, x2
 41      srli x1, x1, 16
 42      li x2, 0x80000010 # cause for 01,11
 43      xori x1, x1, 0b10
 44      bnez x1, not_0b10
 45      addi x2, x2, 1 # cause for 10
 46      not_0b10:
 47      csrr x3, mcause
 48      bne x2, x3, fail
 49  
 50      # generate new mie mask
 51      andi x2, x30, 0x3
 52      bnez x2, fill_skip
 53      li x2, 0x3
 54      fill_skip:
 55      slli x2, x2, 16
 56      csrw mie, x2
 57  
 58      # clear interrupts
 59      csrr x1, mip
 60      srli x1, x1, 16
 61      andi x2, x1, 0x1
 62      beqz x2, skip_clear_edge
 63          addi x30, x30, 1
 64          li x2, 0x10000
 65          csrc mip, x2 # clear edge reported interrupt
 66      skip_clear_edge:
 67      andi x2, x1, 0x2
 68      beqz x2, skip_clear_level
 69          addi x30, x30, 1
 70          csrwi 0x7ff, 1 # clear level reported interrupt via custom csr
 71      skip_clear_level:
 72      addi x27, x27, 1
 73  
 74  
 75      # load state
 76      mv x1, x5
 77      mv x2, x6
 78      mv x3, x7
 79      # fibonacci step
 80      beq x3, x8, skip
 81      add x3, x2, x1
 82      mv x1, x2
 83      mv x2, x3
 84      # store state
 85      mv x5, x1
 86      mv x6, x2
 87      mv x7, x3
 88  skip:
 89      # restore main loop register state
 90      mv x1, x9
 91      mv x2, x10
 92      mv x3, x11
 93      mret
 94  
 95  fail:
 96      csrwi 0x7ff, 2
 97      j fail
 98  
 99  
100  .org 0x200
101      j int_handler
102      li x31, 0xae  # should never happen
103  
104  INIT_REGS_ALLOCATION