1234567891011121314151617181920212223242526272829303132333435363738394041 |
- #include "compiler.h"
- #include "sections.h"
- #include "picorv32.h"
- #include "ioregs.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.
- .pushsection ".init.irq","ax"
- .balign 4
- .globl _irq
- .option push
- .option norvc // Just messes up alignment
- .option arch, +zbb // Enable the ctz instruction
- _irq:
- // s11 contains the mask of IRQs to be handled.
- .Lirq_loop:
- ctz a0,s11 // Vector number
- slli t1,a0,2 // Table index
- .option norelax // Relaxing this instruction will do bad things
- lw ra,%lo(__irq_handler_table)(t1)
- .option relax
- jalr ra
- // Strip the lowest set bit of s11 - the interrupt just handled
- addi t1,s11,-1
- and s11,s11,t1
- // Check for newly arrived higher priority interrupts; this
- // avoids priority inversion. This will also send EOI (really
- // INTACK) for those interrupts.
- pollirq s11,zero,s11
- bnez s11,.Lirq_loop
- mret
- .type _irq, @function
- .size _irq, . - _irq
- .option pop
|