irqasm.S 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. // registers need to be
  9. .pushsection ".init.irq","ax"
  10. .balign 4
  11. .globl _irq
  12. .option push
  13. .option norvc // Alignment matters more here
  14. _irq:
  15. addqxi sp,sp,0
  16. // s10 contains the IRQ return address, s11 the mask of
  17. // IRQs to be handled.
  18. // Send EOI for all interrupts (previously done in hardware)
  19. sw s11,SYS_EOI(zero)
  20. // Fast dispatch for the ABC-bus interrupt handler
  21. andi s0,s11,1 << ABC_IRQ
  22. beqz s0,1f
  23. jal irqhandler_abc_0
  24. sub s11,s11,s0
  25. beqz s11,.L_done
  26. 1:
  27. li s1, 0
  28. .Lirq_loop:
  29. // ctz would make this more efficient...
  30. #if IRQ_VECTORS > 16
  31. slli t0,s11,16
  32. bnez t0,1f
  33. srli s11,s11,16
  34. addi s1,s1,16*4
  35. 1:
  36. #endif
  37. #if IRQ_VECTORS > 8
  38. zext.b t0,s11
  39. bnez t0,2f
  40. srli s11,s11,8
  41. addi s1,s1,8*4
  42. 2:
  43. #endif
  44. #if IRQ_VECTORS > 4
  45. andi t0,s11,15
  46. bnez t0,3f
  47. srli s11,s11,4
  48. addi s1,s1,4*4
  49. 3:
  50. #endif
  51. #if IRQ_VECTORS > 2
  52. andi t0,s11,3
  53. bnez t0,4f
  54. srli s11,s11,2
  55. addi s1,s1,2*4
  56. 4:
  57. #endif
  58. #if IRQ_VECTORS > 1
  59. andi t0,s11,1
  60. bnez t0,5f
  61. srli s11,s11,1
  62. addi s1,s1,1*4
  63. 5:
  64. #endif
  65. srli a0,s1,2 // Vector number
  66. mv a1,s10 // PC (including the rvc flag)
  67. .option norelax // ld will mess up trying to relax this instruction
  68. jalr s1,%lo(__irq_handler_table) // Must be in zero page
  69. .option relax
  70. srli s11,s11,1
  71. addi s1,s1,4*1
  72. bnez s11,.Lirq_loop
  73. .L_done:
  74. mret
  75. .type _irq, @function
  76. .size _irq, . - _irq
  77. .option pop
  78. // Debug functions to read and write x-registers from interrupt
  79. // mode by register number
  80. .pushsection ".text.hot.rdxreg","ax"
  81. .globl rdxreg
  82. .balign 4
  83. rdxreg:
  84. la a3,_xreg_smc
  85. lw a2,8(a3) // addqxi a0,zero,0
  86. andi a0,a0,31
  87. slli a0,a0,15 // rs1
  88. or a2,a2,a0
  89. sw a2,(a3)
  90. jr a3
  91. .type rdxreg, @function
  92. .size rdxreg, . - rdxreg
  93. .popsection
  94. .pushsection ".text.hot.wrxreg","ax"
  95. .globl wrxreg
  96. .balign 4
  97. wrxreg:
  98. la a3,_xreg_smc
  99. lw a2,12(a3) // addxqi zero,a1,0
  100. andi a0,a0,31
  101. slli a0,a0,7 // rd
  102. or a2,a2,a0
  103. sw a2,(a3)
  104. jr a3
  105. .type wrxreg, @function
  106. .size wrxreg, . - wrxreg
  107. .popsection
  108. __rwtext
  109. .balign 4
  110. .option norvc
  111. _xreg_smc:
  112. nop
  113. ret
  114. addqxi a0,zero,0
  115. addxqi zero,a1,0
  116. .type _xreg_smc, @function
  117. .size _xreg_smc, . - _xreg_smc