context_iar.S 5.0 KB

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