context.s 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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. ;
  13. .ref _rt_interrupt_to_thread
  14. .ref _rt_interrupt_from_thread
  15. .ref _rt_thread_switch_interrupt_flag
  16. .def _RTOSINT_Handler
  17. .def _rt_hw_get_st0
  18. .def _rt_hw_get_st1
  19. .def _rt_hw_calc_csb
  20. .def _rt_hw_context_switch_interrupt
  21. .def _rt_hw_context_switch
  22. .def _rt_hw_context_switch_to
  23. .def _rt_hw_interrupt_thread_switch
  24. .def _rt_hw_interrupt_disable
  25. .def _rt_hw_interrupt_enable
  26. ;workaround for importing fpu settings from the compiler
  27. .cdecls C,NOLIST
  28. %{
  29. #ifdef __TMS320C28XX_FPU32__
  30. #define __FPU32__ 1
  31. #else
  32. #define __FPU32__ 0
  33. #endif
  34. %}
  35. RT_CTX_SAVE .macro
  36. PUSH AR1H:AR0H
  37. PUSH XAR2
  38. PUSH XAR3
  39. PUSH XAR4
  40. PUSH XAR5
  41. PUSH XAR6
  42. PUSH XAR7
  43. PUSH XT
  44. PUSH RPC
  45. .if __FPU32__
  46. PUSH RB
  47. MOV32 *SP++, STF
  48. MOV32 *SP++, R0H
  49. MOV32 *SP++, R1H
  50. MOV32 *SP++, R2H
  51. MOV32 *SP++, R3H
  52. MOV32 *SP++, R4H
  53. MOV32 *SP++, R5H
  54. MOV32 *SP++, R6H
  55. MOV32 *SP++, R7H
  56. .endif
  57. .endm
  58. RT_CTX_RESTORE .macro
  59. .if __FPU32__
  60. MOV32 R7H, *--SP, UNCF
  61. MOV32 R6H, *--SP, UNCF
  62. MOV32 R5H, *--SP, UNCF
  63. MOV32 R4H, *--SP, UNCF
  64. MOV32 R3H, *--SP, UNCF
  65. MOV32 R2H, *--SP, UNCF
  66. MOV32 R1H, *--SP, UNCF
  67. MOV32 R0H, *--SP, UNCF
  68. MOV32 STF, *--SP
  69. POP RB
  70. .endif
  71. POP RPC
  72. POP XT
  73. POP XAR7
  74. POP XAR6
  75. POP XAR5
  76. POP XAR4
  77. POP XAR3
  78. POP XAR2
  79. MOVZ AR0 , @SP
  80. SUBB XAR0, #6
  81. MOVL ACC , *XAR0
  82. AND ACC, #0xFFFF << 16
  83. MOV AL, IER
  84. MOVL *XAR0, ACC
  85. POP AR1H:AR0H
  86. .endm
  87. .text
  88. .newblock
  89. ;
  90. ; rt_base_t rt_hw_interrupt_disable();
  91. ;
  92. .asmfunc
  93. _rt_hw_interrupt_disable:
  94. PUSH ST1
  95. SETC INTM,DBGM
  96. MOV AL, *--SP
  97. LRETR
  98. .endasmfunc
  99. ;
  100. ; void rt_hw_interrupt_enable(rt_base_t level);
  101. ;
  102. .asmfunc
  103. _rt_hw_interrupt_enable:
  104. MOV *SP++, AL
  105. POP ST1
  106. LRETR
  107. .endasmfunc
  108. ;
  109. ; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  110. ; r0 --> from
  111. ; r4 --> to
  112. .asmfunc
  113. _rt_hw_context_switch_interrupt:
  114. MOVL XAR0, #0
  115. MOV AR0, AL
  116. MOVL XAR4, *-SP[4]
  117. ; set rt_thread_switch_interrupt_flag to 1
  118. MOVL XAR5, #_rt_thread_switch_interrupt_flag
  119. MOVL XAR6, *XAR5
  120. MOVL ACC, XAR6
  121. CMPB AL, #1
  122. B _reswitch, EQ
  123. MOVL XAR6, #1
  124. MOVL *XAR5, XAR6
  125. MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread
  126. MOVL *XAR5, XAR0
  127. _reswitch:
  128. MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread
  129. MOVL *XAR5, XAR4
  130. LRETR
  131. .endasmfunc
  132. ;
  133. ; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  134. ; r0 --> from
  135. ; r4 --> to
  136. .asmfunc
  137. _rt_hw_context_switch:
  138. MOVL XAR0, #0
  139. MOV AR0, AL
  140. MOVL XAR4, *-SP[4]
  141. ; set rt_thread_switch_interrupt_flag to 1
  142. MOVL XAR5, #_rt_thread_switch_interrupt_flag
  143. MOVL XAR6, *XAR5
  144. MOVL ACC, XAR6
  145. CMPB AL, #1
  146. B _reswitch2, EQ
  147. MOVL XAR6, #1
  148. MOVL *XAR5, XAR6
  149. MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread
  150. MOVL *XAR5, XAR0
  151. _reswitch2:
  152. MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread
  153. MOVL *XAR5, XAR4
  154. TRAP #16
  155. LRETR
  156. .endasmfunc
  157. .asmfunc
  158. _RTOSINT_Handler:
  159. ; disable interrupt to protect context switch
  160. DINT
  161. ; get rt_thread_switch_interrupt_flag
  162. MOV AR0, #_rt_thread_switch_interrupt_flag
  163. MOV AL, *AR0
  164. MOV AR1, AL
  165. CMP AR1, #0
  166. B rtosint_exit, EQ ; pendsv already handled
  167. ; clear rt_thread_switch_interrupt_flag to 0
  168. MOV AR1, #0x00
  169. MOV *AR0, AR1
  170. MOV AR0, #_rt_interrupt_from_thread
  171. MOV AL, *AR0
  172. MOV AR1, AL
  173. CMP AR1, #0
  174. B switch_to_thread, EQ ; skip register save at the first time
  175. ;#if defined (__VFP_FP__) && !defined(__SOFTFP__)
  176. ; TST lr, #0x10 ; if(!EXC_RETURN[4])
  177. ; VSTMDBEQ r1!, {d8 - d15} ; push FPU register s16~s31
  178. ;#endif
  179. RT_CTX_SAVE ; push r4 - r11 register
  180. ;#if defined (__VFP_FP__) && !defined(__SOFTFP__)
  181. ; MOV r4, #0x00 ; flag = 0
  182. ; TST lr, #0x10 ; if(!EXC_RETURN[4])
  183. ; MOVEQ r4, #0x01 ; flag = 1
  184. ; STMFD r1!, {r4} ; push flag
  185. ;#endif
  186. MOV AL, *AR0
  187. MOV AR0, AL
  188. MOVZ AR1, @SP ; get from thread stack pointer
  189. MOV *AR0, AR1 ; update from thread stack pointer
  190. switch_to_thread:
  191. MOV AR1, #_rt_interrupt_to_thread
  192. MOV AL, *AR1
  193. MOV AR1, AL
  194. MOV AL, *AR1
  195. MOV AR1, AL ; load thread stack pointer
  196. ;#if defined (__VFP_FP__) && !defined(__SOFTFP__)
  197. ; LDMFD r1!, {r3} ; pop flag
  198. ;#endif
  199. MOV @SP, AR1
  200. RT_CTX_RESTORE ; pop r4 - r11 register
  201. rtosint_exit:
  202. ; restore interrupt
  203. EINT
  204. IRET
  205. .endasmfunc
  206. .asmfunc
  207. _rt_hw_get_st0:
  208. PUSH ST0
  209. POP AL
  210. LRETR
  211. .endasmfunc
  212. .asmfunc
  213. _rt_hw_get_st1:
  214. PUSH ST1
  215. POP AL
  216. LRETR
  217. .endasmfunc
  218. ; C28x do not have a build-in "__ffs" func in its C compiler.
  219. ; We can use the "Count Sign Bits" (CSB) instruction to make one.
  220. ; CSB will return the number of 0's minus 1 above the highest set bit.
  221. ; The count is placed in T. For example:
  222. ; ACC T maxbit
  223. ; 0x00000001 30 0
  224. ; 0x00000010 26 4
  225. ; 0x000001FF 22 8
  226. ; 0x000001F0 22 8
  227. .asmfunc
  228. _rt_hw_calc_csb:
  229. MOV AH, #0
  230. CSB ACC ; T = no. of sign bits - 1
  231. MOVU ACC, T ; ACC = no. of sign bits - 1
  232. SUBB ACC, #30 ; ACC = ACC - 30
  233. ABS ACC ; ACC = |ACC|
  234. lretr
  235. .endasmfunc
  236. ;
  237. ; * void rt_hw_context_switch_to(rt_uint32 to);
  238. ; * r0 --> to
  239. .asmfunc
  240. _rt_hw_context_switch_to:
  241. MOV AR1, #_rt_interrupt_to_thread
  242. MOV *AR1, AL
  243. ;#if defined (__VFP_FP__) && !defined(__SOFTFP__)
  244. ; CLEAR CONTROL.FPCA
  245. ; MRS r2, CONTROL ; read
  246. ; BIC r2, #0x04 ; modify
  247. ; MSR CONTROL, r2 ; write-back
  248. ;#endif
  249. ; set from thread to 0
  250. MOV AR1, #_rt_interrupt_from_thread
  251. MOV AR0, #0x0
  252. MOV *AR1, AR0
  253. ; set interrupt flag to 1
  254. MOV AR1, #_rt_thread_switch_interrupt_flag
  255. MOV AR0, #1
  256. MOV *AR1, AR0
  257. TRAP #16
  258. ; never reach here!
  259. .endasmfunc
  260. ; compatible with old version
  261. .asmfunc
  262. _rt_hw_interrupt_thread_switch:
  263. LRETR
  264. NOP
  265. .endasmfunc
  266. .end