2
0

irqasm.S 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. #include "compiler.h"
  2. #include "sections.h"
  3. #include "picorv32.h"
  4. #include "ioregs.h"
  5. // The IRQ dispatch code is written in assembly to make
  6. // better use of the register bank switching: can simply
  7. // use the saved registers here, no saving needed.
  8. .pushsection ".init.irq","ax"
  9. .balign 4
  10. .globl _irq
  11. .option push
  12. .option norvc // Just messes up alignment
  13. .option arch, +zbb // Enable the ctz instruction
  14. _irq:
  15. // s11 contains the mask of IRQs to be handled.
  16. .Lirq_loop:
  17. ctz a0,s11 // Vector number
  18. slli t1,a0,2 // Table index
  19. .option norelax // Relaxing this instruction will do bad things
  20. lw ra,%lo(__irq_handler_table)(t1)
  21. .option relax
  22. jalr ra
  23. // Strip the lowest set bit of s11 - the interrupt just handled
  24. addi t1,s11,-1
  25. and s11,s11,t1
  26. // Check for newly arrived higher priority interrupts; this
  27. // avoids priority inversion. This will also send EOI (really
  28. // INTACK) for those interrupts.
  29. pollirq s11,zero,s11
  30. bnez s11,.Lirq_loop
  31. mret
  32. .type _irq, @function
  33. .size _irq, . - _irq
  34. .option pop