|
@@ -0,0 +1,53 @@
|
|
|
+#include "picorv32.h"
|
|
|
+
|
|
|
+ // The IRQ dispatch code is written in assembly to make
|
|
|
+ // better use of the register bank switching: can simply
|
|
|
+ // use the saved registers here, no saving needed.
|
|
|
+ // registers need to be
|
|
|
+ .pushsection ".init.irq","ax"
|
|
|
+ .globl _irq
|
|
|
+_irq:
|
|
|
+ addqxi sp,sp,0
|
|
|
+
|
|
|
+ // s10 contains the IRQ return address, s11 the mask of
|
|
|
+ // IRQs to be handled.
|
|
|
+ lui s0, %hi(__irq_handler_table)
|
|
|
+ li s1, 0
|
|
|
+.Lirq_loop:
|
|
|
+ // ctz would make this more efficient...
|
|
|
+ slli t0,s11,16
|
|
|
+ bnez t0,1f
|
|
|
+ srli s11,s11,16
|
|
|
+ addi s1,s1,16*4
|
|
|
+1:
|
|
|
+ zext.b t0,s11
|
|
|
+ bnez t0,2f
|
|
|
+ srli s11,s11,8
|
|
|
+ addi s1,s1,8*4
|
|
|
+2:
|
|
|
+ andi t0,s11,15
|
|
|
+ bnez t0,3f
|
|
|
+ srli s11,s11,4
|
|
|
+ addi s1,s1,4*4
|
|
|
+3:
|
|
|
+ andi t0,s11,3
|
|
|
+ bnez t0,4f
|
|
|
+ srli s11,s11,2
|
|
|
+ addi s1,s1,2*4
|
|
|
+4:
|
|
|
+ andi t0,s11,1
|
|
|
+ bnez t0,5f
|
|
|
+ srli s11,s11,1
|
|
|
+ addi s1,s1,1*4
|
|
|
+5:
|
|
|
+ add t0,s0,s1
|
|
|
+ lw t0,%lo(__irq_handler_table)(t0)
|
|
|
+ srli a0,s1,2
|
|
|
+ jalr t0
|
|
|
+ srli s11,s11,1
|
|
|
+ addi s1,s1,4*1
|
|
|
+ bnez s11,.Lirq_loop
|
|
|
+
|
|
|
+ mret
|
|
|
+ .type _irq, @function
|
|
|
+ .size _irq, . - _irq
|