context.s 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. ;
  2. ; Copyright (c) 2006-2022, RT-Thread Development Team
  3. ;
  4. ; SPDX-License-Identifier: Apache-2.0
  5. ;
  6. ; Change Logs:
  7. ; Date Author Notes
  8. ; 2018-09-01 xuzhuoyi the first version.
  9. ; 2019-06-17 zhaoxiaowei fix bugs of old c28x interrupt api.
  10. ; 2019-07-03 zhaoxiaowei add _rt_hw_calc_csb function to support __rt_ffs.
  11. ; 2019-12-05 xiaolifan add support for hardware fpu32
  12. ; 2022-06-21 guyunjie trim pendsv (RTOSINT_Handler)
  13. ; 2022-08-24 guyunjie fix bugs in context switching
  14. .ref _rt_interrupt_to_thread
  15. .ref _rt_interrupt_from_thread
  16. .ref _rt_thread_switch_interrupt_flag
  17. .def _RTOSINT_Handler
  18. .def _rt_hw_get_st0
  19. .def _rt_hw_get_st1
  20. .def _rt_hw_calc_csb
  21. .def _rt_hw_context_switch_interrupt
  22. .def _rt_hw_context_switch
  23. .def _rt_hw_context_switch_to
  24. .def _rt_hw_interrupt_thread_switch
  25. .def _rt_hw_interrupt_disable
  26. .def _rt_hw_interrupt_enable
  27. ;workaround for importing fpu settings from the compiler
  28. .cdecls C,NOLIST
  29. %{
  30. #ifdef __TMS320C28XX_FPU32__
  31. #define __FPU32__ 1
  32. #else
  33. #define __FPU32__ 0
  34. #endif
  35. %}
  36. RT_CTX_SAVE .macro
  37. PUSH AR1H:AR0H
  38. PUSH XAR2
  39. PUSH XAR3
  40. PUSH XAR4
  41. PUSH XAR5
  42. PUSH XAR6
  43. PUSH XAR7
  44. PUSH XT
  45. PUSH RPC
  46. .if __FPU32__
  47. PUSH RB
  48. MOV32 *SP++, STF
  49. MOV32 *SP++, R0H
  50. MOV32 *SP++, R1H
  51. MOV32 *SP++, R2H
  52. MOV32 *SP++, R3H
  53. MOV32 *SP++, R4H
  54. MOV32 *SP++, R5H
  55. MOV32 *SP++, R6H
  56. MOV32 *SP++, R7H
  57. .endif
  58. .endm
  59. RT_CTX_RESTORE .macro
  60. .if __FPU32__
  61. MOV32 R7H, *--SP, UNCF
  62. MOV32 R6H, *--SP, UNCF
  63. MOV32 R5H, *--SP, UNCF
  64. MOV32 R4H, *--SP, UNCF
  65. MOV32 R3H, *--SP, UNCF
  66. MOV32 R2H, *--SP, UNCF
  67. MOV32 R1H, *--SP, UNCF
  68. MOV32 R0H, *--SP, UNCF
  69. MOV32 STF, *--SP
  70. POP RB
  71. .endif
  72. POP RPC
  73. POP XT
  74. POP XAR7
  75. POP XAR6
  76. POP XAR5
  77. POP XAR4
  78. POP XAR3
  79. POP XAR2
  80. MOVZ AR0 , @SP
  81. SUBB XAR0, #6
  82. MOVL ACC , *XAR0
  83. AND ACC, #0xFFFF << 16
  84. MOV AL, IER
  85. MOVL *XAR0, ACC
  86. POP AR1H:AR0H
  87. .endm
  88. .text
  89. .newblock
  90. ;
  91. ; rt_base_t rt_hw_interrupt_disable();
  92. ;
  93. .asmfunc
  94. _rt_hw_interrupt_disable:
  95. PUSH ST1
  96. SETC INTM,DBGM
  97. MOV AL, *--SP
  98. LRETR
  99. .endasmfunc
  100. ;
  101. ; void rt_hw_interrupt_enable(rt_base_t level);
  102. ;
  103. .asmfunc
  104. _rt_hw_interrupt_enable:
  105. MOV *SP++, AL
  106. POP ST1
  107. LRETR
  108. .endasmfunc
  109. ;
  110. ; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  111. ; ACC --> from
  112. ; SP[4] --> to
  113. ;
  114. .asmfunc
  115. _rt_hw_context_switch_interrupt:
  116. MOVL XAR0, ACC
  117. MOVL XAR4, *-SP[4]
  118. ; set rt_thread_switch_interrupt_flag to 1
  119. MOVL XAR5, #_rt_thread_switch_interrupt_flag
  120. MOVL ACC, *XAR5
  121. BF _reswitch, NEQ ; ACC!=0
  122. MOVB ACC, #1
  123. MOVL *XAR5, ACC
  124. MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread
  125. MOVL *XAR5, XAR0
  126. _reswitch:
  127. MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread
  128. MOVL *XAR5, XAR4
  129. LRETR
  130. .endasmfunc
  131. ;
  132. ; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  133. ; ACC --> from
  134. ; SP[4] --> to
  135. ;
  136. .asmfunc
  137. _rt_hw_context_switch:
  138. MOVL XAR0, ACC
  139. MOVL XAR4, *-SP[4]
  140. ; set rt_thread_switch_interrupt_flag to 1
  141. MOVL XAR5, #_rt_thread_switch_interrupt_flag
  142. MOVL ACC, *XAR5
  143. BF _reswitch2, NEQ ; ACC!=0
  144. MOVB ACC, #1
  145. MOVL *XAR5, ACC
  146. MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread
  147. MOVL *XAR5, XAR0
  148. _reswitch2:
  149. MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread
  150. MOVL *XAR5, XAR4
  151. TRAP #16
  152. LRETR
  153. .endasmfunc
  154. ;
  155. ; * void rt_hw_context_switch_to(rt_uint32 to);
  156. ; * ACC --> to
  157. ;
  158. .asmfunc
  159. _rt_hw_context_switch_to:
  160. ; get to thread
  161. MOVL XAR1, #_rt_interrupt_to_thread
  162. MOVL *XAR1, ACC
  163. ; set from thread to 0
  164. MOVL XAR1, #_rt_interrupt_from_thread
  165. MOVL XAR0, #0
  166. MOVL *XAR1, XAR0
  167. ; set interrupt flag to 1
  168. MOVL XAR1, #_rt_thread_switch_interrupt_flag
  169. MOVL XAR0, #1
  170. MOVL *XAR1, XAR0
  171. TRAP #16
  172. ; never reach here!
  173. .endasmfunc
  174. .asmfunc
  175. _RTOSINT_Handler:
  176. ; disable interrupt to protect context switch
  177. ; DINT ;this is done by hardware so not needed
  178. ; get rt_thread_switch_interrupt_flag
  179. MOVL XAR0, #_rt_thread_switch_interrupt_flag
  180. MOVL ACC, *XAR0
  181. BF rtosint_exit, EQ ; pendsv already handled
  182. ; clear rt_thread_switch_interrupt_flag to 0
  183. MOVL XAR1, #0
  184. MOVL *XAR0, XAR1
  185. MOVL XAR0, #_rt_interrupt_from_thread
  186. MOVL ACC, *XAR0
  187. BF switch_to_thread, EQ ; skip register save at the first time
  188. RT_CTX_SAVE ; push cpu registers
  189. MOVL ACC, *XAR0
  190. MOVL XAR0, ACC
  191. MOVZ AR1, @SP ; get from thread stack pointer
  192. MOVL *XAR0, XAR1 ; update from thread stack pointer
  193. switch_to_thread:
  194. MOVL XAR1, #_rt_interrupt_to_thread
  195. MOVL ACC, *XAR1
  196. MOVL XAR1, ACC
  197. MOVL ACC, *XAR1
  198. MOV @SP, AL ; load thread stack pointer
  199. RT_CTX_RESTORE ; pop cpu registers
  200. rtosint_exit:
  201. ; do not restore interrupt here: to be restored according to the
  202. ; switched-to context during IRET (automaticlly by hardware)
  203. IRET
  204. .endasmfunc
  205. .asmfunc
  206. _rt_hw_get_st0:
  207. PUSH ST0
  208. POP AL
  209. LRETR
  210. .endasmfunc
  211. .asmfunc
  212. _rt_hw_get_st1:
  213. PUSH ST1
  214. POP AL
  215. LRETR
  216. .endasmfunc
  217. ; C28x do not have a build-in "__ffs" func in its C compiler.
  218. ; We can use the "Count Sign Bits" (CSB) instruction to make one.
  219. ; CSB will return the number of 0's minus 1 above the highest set bit.
  220. ; The count is placed in T. For example:
  221. ; ACC T maxbit
  222. ; 0x00000001 30 0
  223. ; 0x00000010 26 4
  224. ; 0x000001FF 22 8
  225. ; 0x000001F0 22 8
  226. .asmfunc
  227. _rt_hw_calc_csb:
  228. MOV AH, #0
  229. CSB ACC ; T = no. of sign bits - 1
  230. MOVU ACC, T ; ACC = no. of sign bits - 1
  231. SUBB ACC, #30 ; ACC = ACC - 30
  232. ABS ACC ; ACC = |ACC|
  233. lretr
  234. .endasmfunc
  235. ; compatible with old version
  236. .asmfunc
  237. _rt_hw_interrupt_thread_switch:
  238. LRETR
  239. NOP
  240. .endasmfunc
  241. .end