/*
  RISC-V / RV32 interrupt support code
  Based on the RISC-V proxy kernel
*/

.section .text

.global trap_entry
trap_entry:
    csrrw  sp,mscratch,sp
    addi   sp,sp,-320
    sw     ra,4(sp)
    sw     gp,12(sp)
    sw     tp,16(sp)
    sw     t0,20(sp)
    sw     t1,24(sp)
    sw     t2,28(sp)
    sw     s0,32(sp)
    sw     s1,36(sp)
    sw     a0,40(sp)
    sw     a1,44(sp)
    sw     a2,48(sp)
    sw     a3,52(sp)
    sw     a4,56(sp)
    sw     a5,60(sp)
    sw     a6,64(sp)
    sw     a7,68(sp)
    sw     s2,72(sp)
    sw     s3,76(sp)
    sw     s4,80(sp)
    sw     s5,84(sp)
    sw     s6,88(sp)
    sw     s7,92(sp)
    sw     s8,96(sp)
    sw     s9,100(sp)
    sw     s10,104(sp)
    sw     s11,108(sp)
    sw     t3,112(sp)
    sw     t4,116(sp)
    sw     t5,120(sp)
    sw     t6,124(sp)
    csrr   t0,mscratch
    csrr   s0,mstatus
    csrr   t1,mepc
    csrr   t2,mbadaddr
    csrr   t3,mcause
    sw     t0,8(sp)
    sw     s0,128(sp)
    sw     t1,132(sp)
    sw     t2,136(sp)
    sw     t3,140(sp)
    li     t0,-1
    sw     t0,144(sp)
    mv     a0,sp

    la     t0, jump_table
    sll    t3, t3, 2
    add    t0, t0, t3
    lw     t0, 0(t0)
    la     ra, jump_table_return
    jr     t0

jump_table:
    .word undefined_handler
    .word undefined_handler
    .word undefined_handler
    .word undefined_handler
    .word undefined_handler
    .word undefined_handler
    .word undefined_handler
    .word undefined_handler
    .word undefined_handler
    .word undefined_handler
    .word undefined_handler
    .word spll_irq_entry
    .word undefined_handler
    .word undefined_handler
    .word undefined_handler
    .word undefined_handler

jump_table_return:

    mv     a0,sp

    lw     t1,128(a0)
    lw     t2,132(a0)
    addi   sp,sp,320
    csrw   mscratch,sp
    csrw   mepc,t2
    lw     ra,4(a0)
    lw     sp,8(a0)
    lw     gp,12(a0)
    lw     tp,16(a0)
    lw     t0,20(a0)
    lw     t1,24(a0)
    lw     t2,28(a0)
    lw     s0,32(a0)
    lw     s1,36(a0)
    lw     a1,44(a0)
    lw     a2,48(a0)
    lw     a3,52(a0)
    lw     a4,56(a0)
    lw     a5,60(a0)
    lw     a6,64(a0)
    lw     a7,68(a0)
    lw     s2,72(a0)
    lw     s3,76(a0)
    lw     s4,80(a0)
    lw     s5,84(a0)
    lw     s6,88(a0)
    lw     s7,92(a0)
    lw     s8,96(a0)
    lw     s9,100(a0)
    lw     s10,104(a0)
    lw     s11,108(a0)
    lw     t3,112(a0)
    lw     t4,116(a0)
    lw     t5,120(a0)
    lw     t6,124(a0)
    lw     a0,40(a0)
    mret

.weak undefined_handler
undefined_handler:
    j      undefined_handler

