irqasm.S 2.1 KB

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