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