context_gcc.S 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018/10/28 Bernard The unify RISC-V porting implementation
  9. * 2018/12/27 Jesven Add SMP support
  10. */
  11. #include "cpuport.h"
  12. #ifdef RT_USING_SMP
  13. #define rt_hw_interrupt_disable rt_hw_local_irq_disable
  14. #define rt_hw_interrupt_enable rt_hw_local_irq_enable
  15. #endif
  16. /*
  17. * rt_base_t rt_hw_interrupt_disable(void);
  18. */
  19. .globl rt_hw_interrupt_disable
  20. rt_hw_interrupt_disable:
  21. csrrci a0, mstatus, 8
  22. ret
  23. /*
  24. * void rt_hw_interrupt_enable(rt_base_t level);
  25. */
  26. .globl rt_hw_interrupt_enable
  27. rt_hw_interrupt_enable:
  28. csrw mstatus, a0
  29. ret
  30. /*
  31. * #ifdef RT_USING_SMP
  32. * void rt_hw_context_switch_to(rt_ubase_t to, stuct rt_thread *to_thread);
  33. * #else
  34. * void rt_hw_context_switch_to(rt_ubase_t to);
  35. * #endif
  36. * a0 --> to
  37. * a1 --> to_thread
  38. */
  39. .globl rt_hw_context_switch_to
  40. rt_hw_context_switch_to:
  41. LOAD sp, (a0)
  42. LOAD a0, 2 * REGBYTES(sp)
  43. csrw mstatus, a0
  44. j rt_hw_context_switch_exit
  45. /*
  46. * #ifdef RT_USING_SMP
  47. * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
  48. * #else
  49. * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
  50. * #endif
  51. *
  52. * a0 --> from
  53. * a1 --> to
  54. * a2 --> to_thread
  55. */
  56. .globl rt_hw_context_switch
  57. rt_hw_context_switch:
  58. /* saved from thread context
  59. * x1/ra -> sp(0)
  60. * x1/ra -> sp(1)
  61. * mstatus.mie -> sp(2)
  62. * x(i) -> sp(i-4)
  63. */
  64. addi sp, sp, -32 * REGBYTES
  65. STORE sp, (a0)
  66. STORE x1, 0 * REGBYTES(sp)
  67. STORE x1, 1 * REGBYTES(sp)
  68. csrr a0, mstatus
  69. andi a0, a0, 8
  70. beqz a0, save_mpie
  71. li a0, 0x80
  72. save_mpie:
  73. STORE a0, 2 * REGBYTES(sp)
  74. STORE x4, 4 * REGBYTES(sp)
  75. STORE x5, 5 * REGBYTES(sp)
  76. STORE x6, 6 * REGBYTES(sp)
  77. STORE x7, 7 * REGBYTES(sp)
  78. STORE x8, 8 * REGBYTES(sp)
  79. STORE x9, 9 * REGBYTES(sp)
  80. STORE x10, 10 * REGBYTES(sp)
  81. STORE x11, 11 * REGBYTES(sp)
  82. STORE x12, 12 * REGBYTES(sp)
  83. STORE x13, 13 * REGBYTES(sp)
  84. STORE x14, 14 * REGBYTES(sp)
  85. STORE x15, 15 * REGBYTES(sp)
  86. STORE x16, 16 * REGBYTES(sp)
  87. STORE x17, 17 * REGBYTES(sp)
  88. STORE x18, 18 * REGBYTES(sp)
  89. STORE x19, 19 * REGBYTES(sp)
  90. STORE x20, 20 * REGBYTES(sp)
  91. STORE x21, 21 * REGBYTES(sp)
  92. STORE x22, 22 * REGBYTES(sp)
  93. STORE x23, 23 * REGBYTES(sp)
  94. STORE x24, 24 * REGBYTES(sp)
  95. STORE x25, 25 * REGBYTES(sp)
  96. STORE x26, 26 * REGBYTES(sp)
  97. STORE x27, 27 * REGBYTES(sp)
  98. STORE x28, 28 * REGBYTES(sp)
  99. STORE x29, 29 * REGBYTES(sp)
  100. STORE x30, 30 * REGBYTES(sp)
  101. STORE x31, 31 * REGBYTES(sp)
  102. /* restore to thread context
  103. * sp(0) -> epc;
  104. * sp(1) -> ra;
  105. * sp(i) -> x(i+2)
  106. */
  107. LOAD sp, (a1)
  108. j rt_hw_context_switch_exit
  109. .global rt_hw_context_switch_exit
  110. rt_hw_context_switch_exit:
  111. #ifdef RT_USING_SMP
  112. #ifdef RT_USING_SIGNALS
  113. mv a0, sp
  114. csrr t0, mhartid
  115. /* switch interrupt stack of current cpu */
  116. la sp, __stack_start__
  117. addi t1, t0, 1
  118. li t2, __STACKSIZE__
  119. mul t1, t1, t2
  120. add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */
  121. call rt_signal_check
  122. mv sp, a0
  123. #endif
  124. #endif
  125. /* resw ra to mepc */
  126. LOAD a0, 0 * REGBYTES(sp)
  127. csrw mepc, a0
  128. LOAD x1, 1 * REGBYTES(sp)
  129. li t0, 0x00001800
  130. csrs mstatus, t0
  131. LOAD a0, 2 * REGBYTES(sp)
  132. csrs mstatus, a0
  133. LOAD x4, 4 * REGBYTES(sp)
  134. LOAD x5, 5 * REGBYTES(sp)
  135. LOAD x6, 6 * REGBYTES(sp)
  136. LOAD x7, 7 * REGBYTES(sp)
  137. LOAD x8, 8 * REGBYTES(sp)
  138. LOAD x9, 9 * REGBYTES(sp)
  139. LOAD x10, 10 * REGBYTES(sp)
  140. LOAD x11, 11 * REGBYTES(sp)
  141. LOAD x12, 12 * REGBYTES(sp)
  142. LOAD x13, 13 * REGBYTES(sp)
  143. LOAD x14, 14 * REGBYTES(sp)
  144. LOAD x15, 15 * REGBYTES(sp)
  145. LOAD x16, 16 * REGBYTES(sp)
  146. LOAD x17, 17 * REGBYTES(sp)
  147. LOAD x18, 18 * REGBYTES(sp)
  148. LOAD x19, 19 * REGBYTES(sp)
  149. LOAD x20, 20 * REGBYTES(sp)
  150. LOAD x21, 21 * REGBYTES(sp)
  151. LOAD x22, 22 * REGBYTES(sp)
  152. LOAD x23, 23 * REGBYTES(sp)
  153. LOAD x24, 24 * REGBYTES(sp)
  154. LOAD x25, 25 * REGBYTES(sp)
  155. LOAD x26, 26 * REGBYTES(sp)
  156. LOAD x27, 27 * REGBYTES(sp)
  157. LOAD x28, 28 * REGBYTES(sp)
  158. LOAD x29, 29 * REGBYTES(sp)
  159. LOAD x30, 30 * REGBYTES(sp)
  160. LOAD x31, 31 * REGBYTES(sp)
  161. addi sp, sp, 32 * REGBYTES
  162. mret