context.s 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  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. ; 2022-10-15 guyunjie add zero-latency interrupt
  15. .ref rt_interrupt_to_thread
  16. .ref rt_interrupt_from_thread
  17. .ref rt_thread_switch_interrupt_flag
  18. .def rtosint_handler
  19. .def rt_hw_get_st0
  20. .def rt_hw_get_st1
  21. .def rt_hw_calc_csb
  22. .def rt_hw_context_switch_interrupt
  23. .def rt_hw_context_switch
  24. .def rt_hw_context_switch_to
  25. .def rt_hw_interrupt_thread_switch
  26. .def rt_hw_interrupt_disable
  27. .def rt_hw_interrupt_enable
  28. ;importing settings from compiler and config
  29. .cdecls C,NOLIST
  30. %{
  31. #include <rtconfig.h>
  32. #ifdef __TMS320C28XX_FPU32__
  33. #define __FPU32__ 1
  34. #else
  35. #define __FPU32__ 0
  36. #endif
  37. #ifdef __TMS320C28XX_FPU64__
  38. #define __FPU64__ 1
  39. #else
  40. #define __FPU64__ 0
  41. #endif
  42. #ifdef __TMS320C28XX_VCRC__
  43. #define __VCRC__ 1
  44. #else
  45. #define __VCRC__ 0
  46. #endif
  47. #ifdef RT_USING_ZERO_LATENCY
  48. #define ZERO_LATENCY 1
  49. #ifndef ZERO_LATENCY_INT_MASK
  50. #error ZERO_LATENCY_INT_MASK must be defined for zero latency interrupt
  51. #elif ZERO_LATENCY_INT_MASK & 0x8000
  52. #error RTOS bit (0x8000) must not be set in ZERO_LATENCY_INT_MASK
  53. #endif
  54. #else
  55. #define ZERO_LATENCY 0
  56. #endif
  57. %}
  58. .text
  59. .newblock
  60. ;
  61. ; rt_base_t rt_hw_interrupt_disable();
  62. ;
  63. .asmfunc
  64. rt_hw_interrupt_disable:
  65. .if ZERO_LATENCY
  66. MOV AL, IER
  67. AND IER, #ZERO_LATENCY_INT_MASK
  68. .else
  69. PUSH ST1
  70. SETC INTM
  71. POP AL
  72. .endif
  73. MOV AH, #0
  74. LRETR
  75. .endasmfunc
  76. ;
  77. ; void rt_hw_interrupt_enable(rt_base_t level);
  78. ;
  79. .asmfunc
  80. rt_hw_interrupt_enable:
  81. .if ZERO_LATENCY
  82. MOV IER, AL
  83. .else
  84. PUSH AL
  85. POP ST1
  86. .endif
  87. LRETR
  88. .endasmfunc
  89. ;
  90. ; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  91. ; ACC --> from
  92. ; SP[4] --> to
  93. ;
  94. .asmfunc
  95. rt_hw_context_switch_interrupt:
  96. ; ACC, XAR4-7 are "save on call" following TI C28x C/C++ compiler convention
  97. ; and therefore can be used in a function without being saved on stack first
  98. ; (the compiler has already saved it before the call).
  99. ; Reference: TMS320C28x Optimizing CC++ Compiler
  100. ; note this convention is only applicable to normal functions not to isrs
  101. MOVL XAR6, ACC
  102. MOVL XAR4, *-SP[4]
  103. ; set rt_thread_switch_interrupt_flag to 1
  104. MOVL XAR5, #rt_thread_switch_interrupt_flag
  105. MOVL ACC, *XAR5
  106. BF reswitch2, NEQ ; ACC!=0
  107. MOVB ACC, #1
  108. MOVL *XAR5, ACC
  109. MOVL XAR5, #rt_interrupt_from_thread ; set rt_interrupt_from_thread
  110. MOVL *XAR5, XAR6
  111. reswitch2:
  112. MOVL XAR5, #rt_interrupt_to_thread ; set rt_interrupt_to_thread
  113. MOVL *XAR5, XAR4
  114. LRETR
  115. .endasmfunc
  116. ;
  117. ; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  118. ; ACC --> from
  119. ; SP[4] --> to
  120. ;
  121. .asmfunc
  122. rt_hw_context_switch:
  123. MOVL XAR6, ACC
  124. MOVL XAR4, *-SP[4]
  125. ; set rt_thread_switch_interrupt_flag to 1
  126. MOVL XAR5, #rt_thread_switch_interrupt_flag
  127. MOVL ACC, *XAR5
  128. BF reswitch1, NEQ ; ACC!=0
  129. MOVB ACC, #1
  130. MOVL *XAR5, ACC
  131. MOVL XAR5, #rt_interrupt_from_thread ; set rt_interrupt_from_thread
  132. MOVL *XAR5, XAR6
  133. reswitch1:
  134. MOVL XAR5, #rt_interrupt_to_thread ; set rt_interrupt_to_thread
  135. MOVL *XAR5, XAR4
  136. OR IFR, #0x8000
  137. LRETR
  138. .endasmfunc
  139. ;
  140. ; * void rt_hw_context_switch_to(rt_uint32 to);
  141. ; * ACC --> to
  142. ;
  143. .asmfunc
  144. rt_hw_context_switch_to:
  145. ; get to thread
  146. MOVL XAR5, #rt_interrupt_to_thread
  147. MOVL *XAR5, ACC
  148. ; set from thread to 0
  149. MOVL XAR5, #rt_interrupt_from_thread
  150. MOVL XAR4, #0
  151. MOVL *XAR5, XAR4
  152. ; set interrupt flag to 1
  153. MOVL XAR5, #rt_thread_switch_interrupt_flag
  154. MOVL XAR4, #1
  155. MOVL *XAR5, XAR4
  156. ; trigger rtos interrupt
  157. OR IFR, #0x8000
  158. OR IER, #0x8000
  159. CLRC INTM
  160. ; never reach here!
  161. .endasmfunc
  162. .asmfunc
  163. rtosint_handler:
  164. .if ZERO_LATENCY
  165. ; mask out non-critical interrupts and enable global interrupt
  166. ; so rtosint_handler won't block critical interrupts
  167. AND IER, #ZERO_LATENCY_INT_MASK
  168. CLRC INTM
  169. .endif
  170. MOVL ACC, *-SP[4]
  171. MOV AR0, AL ; save original IER
  172. PUSH AR1H:AR0H
  173. PUSH XAR2
  174. ; get rt_thread_switch_interrupt_flag
  175. MOVL XAR1, #rt_thread_switch_interrupt_flag
  176. MOVL ACC, *XAR1
  177. BF rtosint_exit, EQ ; rtos_int already handled
  178. ; clear rt_thread_switch_interrupt_flag to 0
  179. MOVL XAR2, #0
  180. MOVL *XAR1, XAR2
  181. MOVL XAR1, #rt_interrupt_from_thread
  182. MOVL ACC, *XAR1
  183. BF switch_to_thread, EQ ; skip register save at the first time
  184. PUSH XAR3
  185. PUSH XAR4
  186. PUSH XAR5
  187. PUSH XAR6
  188. PUSH XAR7
  189. PUSH XT
  190. PUSH RPC
  191. .if __FPU32__
  192. PUSH RB
  193. MOV32 *SP++, STF
  194. MOV32 *SP++, R0H
  195. MOV32 *SP++, R1H
  196. MOV32 *SP++, R2H
  197. MOV32 *SP++, R3H
  198. MOV32 *SP++, R4H
  199. MOV32 *SP++, R5H
  200. MOV32 *SP++, R6H
  201. MOV32 *SP++, R7H
  202. .endif
  203. .if __FPU64__
  204. MOV32 *SP++, R0L
  205. MOV32 *SP++, R1L
  206. MOV32 *SP++, R2L
  207. MOV32 *SP++, R3L
  208. MOV32 *SP++, R4L
  209. MOV32 *SP++, R5L
  210. MOV32 *SP++, R6L
  211. MOV32 *SP++, R7L
  212. .endif
  213. .if __VCRC__
  214. VMOV32 *SP++, VCRC
  215. VMOV32 *SP++, VSTATUS
  216. VMOV32 *SP++, VCRCPOLY
  217. VMOV32 *SP++, VCRCSIZE
  218. .endif
  219. MOVL ACC, *XAR1
  220. MOVL XAR1, ACC
  221. MOVZ AR2, @SP ; get from thread stack pointer
  222. MOVL *XAR1, XAR2 ; update from thread stack pointer
  223. switch_to_thread:
  224. MOVL XAR1, #rt_interrupt_to_thread
  225. MOVL ACC, *XAR1
  226. MOVL XAR1, ACC
  227. MOVL ACC, *XAR1
  228. MOV @SP, AL ; load thread stack pointer
  229. .if __VCRC__
  230. VMOV32 VCRCSIZE, *--SP
  231. VMOV32 VCRCPOLY, *--SP
  232. VMOV32 VSTATUS, *--SP
  233. VMOV32 VCRC, *--SP
  234. .endif
  235. .if __FPU64__
  236. MOV32 R7L, *--SP
  237. MOV32 R6L, *--SP
  238. MOV32 R5L, *--SP
  239. MOV32 R4L, *--SP
  240. MOV32 R3L, *--SP
  241. MOV32 R2L, *--SP
  242. MOV32 R1L, *--SP
  243. MOV32 R0L, *--SP
  244. .endif
  245. .if __FPU32__
  246. MOV32 R7H, *--SP
  247. MOV32 R6H, *--SP
  248. MOV32 R5H, *--SP
  249. MOV32 R4H, *--SP
  250. MOV32 R3H, *--SP
  251. MOV32 R2H, *--SP
  252. MOV32 R1H, *--SP
  253. MOV32 R0H, *--SP
  254. MOV32 STF, *--SP
  255. POP RB
  256. .endif
  257. POP RPC
  258. POP XT
  259. POP XAR7
  260. POP XAR6
  261. POP XAR5
  262. POP XAR4
  263. POP XAR3
  264. rtosint_exit:
  265. ; do not restore interrupt here: to be restored according to the
  266. ; switched-to context during IRET (automaticlly by hardware)
  267. POP XAR2
  268. POP AR1H:AR0H
  269. MOVL ACC , *-SP[4]
  270. MOV AL, AR0
  271. MOVL *-SP[4], ACC
  272. IRET
  273. .endasmfunc
  274. .asmfunc
  275. rt_hw_get_st0:
  276. PUSH ST0
  277. POP AL
  278. LRETR
  279. .endasmfunc
  280. .asmfunc
  281. rt_hw_get_st1:
  282. PUSH ST1
  283. POP AL
  284. LRETR
  285. .endasmfunc
  286. ; C28x do not have a build-in "__ffs" func in its C compiler.
  287. ; We can use the "Count Sign Bits" (CSB) instruction to make one.
  288. ; CSB will return the number of 0's minus 1 above the highest set bit.
  289. ; The count is placed in T. For example:
  290. ; ACC T maxbit
  291. ; 0x00000001 30 0
  292. ; 0x00000010 26 4
  293. ; 0x000001FF 22 8
  294. ; 0x000001F0 22 8
  295. .asmfunc
  296. rt_hw_calc_csb:
  297. MOV AH, #0
  298. CSB ACC ; T = no. of sign bits - 1
  299. MOVU ACC, T ; ACC = no. of sign bits - 1
  300. SUBB ACC, #30 ; ACC = ACC - 30
  301. ABS ACC ; ACC = |ACC|
  302. LRETR
  303. .endasmfunc
  304. ; compatible with old version
  305. .asmfunc
  306. rt_hw_interrupt_thread_switch:
  307. LRETR
  308. NOP
  309. .endasmfunc
  310. .end