context_gcc.S 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Copyright (c) 2019-Present Nuclei Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020/03/26 Huaqi First Nuclei RISC-V porting implementation
  9. */
  10. #include "riscv_encoding.h"
  11. #ifndef __riscv_32e
  12. #define portRegNum 32
  13. #else
  14. #define portRegNum 14
  15. #endif
  16. #define portCONTEXT_SIZE ( portRegNum * REGBYTES )
  17. .extern rt_interrupt_from_thread
  18. .extern rt_interrupt_to_thread
  19. .section .text
  20. /*
  21. * void rt_hw_context_switch_to(rt_ubase_t to);
  22. * a0 --> to_thread
  23. */
  24. .globl rt_hw_context_switch_to
  25. /* Start the first task. This also clears the bit that indicates the FPU is
  26. in use in case the FPU was used before the scheduler was started - which
  27. would otherwise result in the unnecessary leaving of space in the stack
  28. for lazy saving of FPU registers. */
  29. .align 3
  30. rt_hw_context_switch_to:
  31. LOAD sp, 0x0(a0) /* Read sp from first TCB member(a0) */
  32. /* Pop PC from stack and set MEPC */
  33. LOAD t0, 0 * REGBYTES(sp)
  34. csrw CSR_MEPC, t0
  35. /* Pop mstatus from stack and set it */
  36. LOAD t0, (portRegNum - 1) * REGBYTES(sp)
  37. csrw CSR_MSTATUS, t0
  38. /* Interrupt still disable here */
  39. /* Restore Registers from Stack */
  40. LOAD x1, 1 * REGBYTES(sp) /* RA */
  41. LOAD x5, 2 * REGBYTES(sp)
  42. LOAD x6, 3 * REGBYTES(sp)
  43. LOAD x7, 4 * REGBYTES(sp)
  44. LOAD x8, 5 * REGBYTES(sp)
  45. LOAD x9, 6 * REGBYTES(sp)
  46. LOAD x10, 7 * REGBYTES(sp)
  47. LOAD x11, 8 * REGBYTES(sp)
  48. LOAD x12, 9 * REGBYTES(sp)
  49. LOAD x13, 10 * REGBYTES(sp)
  50. LOAD x14, 11 * REGBYTES(sp)
  51. LOAD x15, 12 * REGBYTES(sp)
  52. #ifndef __riscv_32e
  53. LOAD x16, 13 * REGBYTES(sp)
  54. LOAD x17, 14 * REGBYTES(sp)
  55. LOAD x18, 15 * REGBYTES(sp)
  56. LOAD x19, 16 * REGBYTES(sp)
  57. LOAD x20, 17 * REGBYTES(sp)
  58. LOAD x21, 18 * REGBYTES(sp)
  59. LOAD x22, 19 * REGBYTES(sp)
  60. LOAD x23, 20 * REGBYTES(sp)
  61. LOAD x24, 21 * REGBYTES(sp)
  62. LOAD x25, 22 * REGBYTES(sp)
  63. LOAD x26, 23 * REGBYTES(sp)
  64. LOAD x27, 24 * REGBYTES(sp)
  65. LOAD x28, 25 * REGBYTES(sp)
  66. LOAD x29, 26 * REGBYTES(sp)
  67. LOAD x30, 27 * REGBYTES(sp)
  68. LOAD x31, 28 * REGBYTES(sp)
  69. #endif
  70. addi sp, sp, portCONTEXT_SIZE
  71. mret
  72. .align 2
  73. .global irqc_msip_handler
  74. irqc_msip_handler:
  75. addi sp, sp, -portCONTEXT_SIZE
  76. STORE x1, 1 * REGBYTES(sp) /* RA */
  77. STORE x5, 2 * REGBYTES(sp)
  78. STORE x6, 3 * REGBYTES(sp)
  79. STORE x7, 4 * REGBYTES(sp)
  80. STORE x8, 5 * REGBYTES(sp)
  81. STORE x9, 6 * REGBYTES(sp)
  82. STORE x10, 7 * REGBYTES(sp)
  83. STORE x11, 8 * REGBYTES(sp)
  84. STORE x12, 9 * REGBYTES(sp)
  85. STORE x13, 10 * REGBYTES(sp)
  86. STORE x14, 11 * REGBYTES(sp)
  87. STORE x15, 12 * REGBYTES(sp)
  88. #ifndef __riscv_32e
  89. STORE x16, 13 * REGBYTES(sp)
  90. STORE x17, 14 * REGBYTES(sp)
  91. STORE x18, 15 * REGBYTES(sp)
  92. STORE x19, 16 * REGBYTES(sp)
  93. STORE x20, 17 * REGBYTES(sp)
  94. STORE x21, 18 * REGBYTES(sp)
  95. STORE x22, 19 * REGBYTES(sp)
  96. STORE x23, 20 * REGBYTES(sp)
  97. STORE x24, 21 * REGBYTES(sp)
  98. STORE x25, 22 * REGBYTES(sp)
  99. STORE x26, 23 * REGBYTES(sp)
  100. STORE x27, 24 * REGBYTES(sp)
  101. STORE x28, 25 * REGBYTES(sp)
  102. STORE x29, 26 * REGBYTES(sp)
  103. STORE x30, 27 * REGBYTES(sp)
  104. STORE x31, 28 * REGBYTES(sp)
  105. #endif
  106. /* Push mstatus to stack */
  107. csrr t0, CSR_MSTATUS
  108. STORE t0, (portRegNum - 1) * REGBYTES(sp)
  109. /* Push additional registers */
  110. /* Store sp to task stack */
  111. LOAD t0, rt_interrupt_from_thread
  112. STORE sp, 0(t0)
  113. csrr t0, CSR_MEPC
  114. STORE t0, 0(sp)
  115. jal xPortTaskSwitch
  116. /* Switch task context */
  117. LOAD t0, rt_interrupt_to_thread
  118. LOAD sp, 0x0(t0)
  119. /* Pop PC from stack and set MEPC */
  120. LOAD t0, 0 * REGBYTES(sp)
  121. csrw CSR_MEPC, t0
  122. /* Pop additional registers */
  123. /* Pop mstatus from stack and set it */
  124. LOAD t0, (portRegNum - 1) * REGBYTES(sp)
  125. csrw CSR_MSTATUS, t0
  126. /* Interrupt still disable here */
  127. /* Restore Registers from Stack */
  128. LOAD x1, 1 * REGBYTES(sp) /* RA */
  129. LOAD x5, 2 * REGBYTES(sp)
  130. LOAD x6, 3 * REGBYTES(sp)
  131. LOAD x7, 4 * REGBYTES(sp)
  132. LOAD x8, 5 * REGBYTES(sp)
  133. LOAD x9, 6 * REGBYTES(sp)
  134. LOAD x10, 7 * REGBYTES(sp)
  135. LOAD x11, 8 * REGBYTES(sp)
  136. LOAD x12, 9 * REGBYTES(sp)
  137. LOAD x13, 10 * REGBYTES(sp)
  138. LOAD x14, 11 * REGBYTES(sp)
  139. LOAD x15, 12 * REGBYTES(sp)
  140. #ifndef __riscv_32e
  141. LOAD x16, 13 * REGBYTES(sp)
  142. LOAD x17, 14 * REGBYTES(sp)
  143. LOAD x18, 15 * REGBYTES(sp)
  144. LOAD x19, 16 * REGBYTES(sp)
  145. LOAD x20, 17 * REGBYTES(sp)
  146. LOAD x21, 18 * REGBYTES(sp)
  147. LOAD x22, 19 * REGBYTES(sp)
  148. LOAD x23, 20 * REGBYTES(sp)
  149. LOAD x24, 21 * REGBYTES(sp)
  150. LOAD x25, 22 * REGBYTES(sp)
  151. LOAD x26, 23 * REGBYTES(sp)
  152. LOAD x27, 24 * REGBYTES(sp)
  153. LOAD x28, 25 * REGBYTES(sp)
  154. LOAD x29, 26 * REGBYTES(sp)
  155. LOAD x30, 27 * REGBYTES(sp)
  156. LOAD x31, 28 * REGBYTES(sp)
  157. #endif
  158. addi sp, sp, portCONTEXT_SIZE
  159. mret