context.asm 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. ;
  2. ; Copyright (c) 2021, Shenzhen Academy of Aerospace Technology
  3. ;
  4. ; SPDX-License-Identifier: Apache-2.0
  5. ;
  6. ; Change Logs:
  7. ; Date Author Notes
  8. ; 2021-11-16 Dystopia the first version
  9. ;
  10. ;-----------------------------------------------------------
  11. ; context switch for C6000 DSP
  12. ;-----------------------------------------------------------
  13. .include "contextinc.asm"
  14. ;-----------------------------------------------------------
  15. ; macro definition
  16. ;-----------------------------------------------------------
  17. DP .set B14
  18. SP .set B15
  19. ;-----------------------------------------------------------
  20. ; extern variable
  21. ;-----------------------------------------------------------
  22. .ref rt_system_stack_top
  23. ;
  24. ;-----------------------------------------------------------
  25. ;
  26. ;-----------------------------------------------------------
  27. ; global variable
  28. ;-----------------------------------------------------------
  29. .global rt_interrupt_from_thread
  30. .global rt_interrupt_to_thread
  31. .global rt_thread_switch_interrupt_flag
  32. ;
  33. ;-----------------------------------------------------------
  34. ;
  35. .sect ".text"
  36. ;-----------------------------------------------------------
  37. ; void rt_hw_enable_exception(void)
  38. ;-----------------------------------------------------------
  39. .global rt_hw_enable_exception
  40. rt_hw_enable_exception:
  41. DINT
  42. MVC .S2 TSR,B0
  43. MVC .S2 B3,NRP
  44. MVK .L2 0xC,B1
  45. OR .D2 B0,B1,B0
  46. MVC .S2 B0,TSR ; Set GEE and XEN in TSR
  47. B .S2 NRP
  48. NOP 5
  49. ;-----------------------------------------------------------
  50. ; rt_base_t rt_hw_interrupt_enable(void)
  51. ;-----------------------------------------------------------
  52. .global rt_hw_interrupt_disable
  53. rt_hw_interrupt_disable:
  54. ;{
  55. MVC CSR,B4
  56. MV B4,A4
  57. AND 1,B4,B0
  58. [!B0] CLR B4,1,1,B4
  59. [B0] SET B4,1,1,B4
  60. CLR B4,0,0,B4
  61. MVC B4,CSR
  62. B B3
  63. NOP 5
  64. ;}
  65. ;-----------------------------------------------------------
  66. ; void rt_hw_interrupt_enable(rt_base_t scr)
  67. ;-----------------------------------------------------------
  68. .global rt_hw_interrupt_enable
  69. rt_hw_interrupt_enable:
  70. ;{
  71. MVC A4,CSR
  72. B B3
  73. NOP 5
  74. ;}
  75. ;
  76. ;-----------------------------------------------------------
  77. ;
  78. ;
  79. ; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  80. ; A4 --> from
  81. ; B4 --> to
  82. ;
  83. .global rt_hw_context_switch
  84. rt_hw_context_switch:
  85. ; {
  86. SUBAW .D2 SP,2,SP
  87. ADD .D1X SP,-8,A15
  88. || STDW .D2T1 A15:A14,*SP--[3] ; Store A15:A14
  89. STDW .D2T2 B13:B12,*SP--[1] ; Store B13:B12
  90. || STDW .D1T1 A13:A12,*A15--[1] ; Store A13:A12
  91. || MV B3,B13
  92. STDW .D2T2 B11:B10,*SP--[1] ; Store B11:B10
  93. || STDW .D1T1 A11:A10,*A15--[1] ; Store A11:A10
  94. || MVC .S2 CSR,B12
  95. STDW .D2T2 B13:B12,*SP--[1] ; Store PC:CSR
  96. || MVC .S2 TSR,B5
  97. MVC .S2 ILC,B11
  98. MVC .S2 RILC,B10
  99. STDW .D2T2 B11:B10,*SP--[1] ; Store RILC:ILC
  100. || MV .S1X B5,A3
  101. ZERO A2 ;
  102. STDW .D2T1 A3:A2,*SP--[1] ; Store TSR:stack type
  103. STW SP,*A4 ; Save thread's stack pointer
  104. B rt_hw_context_switch_to
  105. MV B4,A4
  106. NOP 4
  107. ;}
  108. ;
  109. ; void rt_hw_context_switch_to(rt_uint32 to);
  110. ; A4 --> to
  111. ;
  112. .global rt_hw_context_switch_to
  113. rt_hw_context_switch_to:
  114. ;{
  115. LDW *A4,SP
  116. NOP 4
  117. LDDW .D2T2 *++SP[1],B9:B8 ; get TSR (B9) and stack frame type (B8)
  118. LDDW .D2T2 *++SP[1],B11:B10 ; get RILC (B11) and ILC (B10)
  119. LDDW .D2T2 *++SP[1],B13:B12 ; get PC (B13) and CSR (B12)
  120. NOP 2
  121. MV B8,B0
  122. [B0] B _rt_thread_interrupt_stack
  123. NOP 5
  124. ;
  125. ; this maybe do better
  126. ;
  127. LDDW .D2T2 *++SP[1],B11:B10
  128. || MVC .S2 B11,RILC ; Restore RILC
  129. LDDW .D2T2 *++SP[1],B13:B12
  130. || MVC .S2 B10,ILC ; Restore ILC
  131. LDDW .D2T1 *++SP[1],A11:A10
  132. || MV B13,B3 ; Restore PC
  133. LDDW .D2T1 *++SP[1],A13:A12
  134. || MVC .S2 B12,CSR ; Restore CSR
  135. LDDW .D2T1 *++SP[1],A15:A14
  136. B B3 ; Return to caller
  137. ADDAW .D2 SP,2,SP
  138. NOP 4 ; Delay slots
  139. _rt_thread_interrupt_stack:
  140. ADDAW .D1X SP,30,A15
  141. LDDW .D1T1 *++A15[1],A17:A16
  142. || LDDW .D2T2 *++SP[1],B17:B16
  143. LDDW .D1T1 *++A15[1],A19:A18
  144. || LDDW .D2T2 *++SP[1],B19:B18
  145. LDDW .D1T1 *++A15[1],A21:A20
  146. || LDDW .D2T2 *++SP[1],B21:B20
  147. LDDW .D1T1 *++A15[1],A23:A22
  148. || LDDW .D2T2 *++SP[1],B23:B22
  149. LDDW .D1T1 *++A15[1],A25:A24
  150. || LDDW .D2T2 *++SP[1],B25:B24
  151. LDDW .D1T1 *++A15[1],A27:A26
  152. || LDDW .D2T2 *++SP[1],B27:B26
  153. LDDW .D1T1 *++A15[1],A29:A28
  154. || LDDW .D2T2 *++SP[1],B29:B28
  155. LDDW .D1T1 *++A15[1],A31:A30
  156. || LDDW .D2T2 *++SP[1],B31:B30
  157. LDDW .D1T1 *++A15[1],A1:A0
  158. || LDDW .D2T2 *++SP[1],B1:B0
  159. LDDW .D1T1 *++A15[1],A3:A2
  160. || LDDW .D2T2 *++SP[1],B3:B2
  161. || MVC .S2 B9,ITSR ; Restore ITSR
  162. LDDW .D1T1 *++A15[1],A5:A4
  163. || LDDW .D2T2 *++SP[1],B5:B4
  164. || MVC .S2 B11,RILC ; Restore RILC
  165. LDDW .D1T1 *++A15[1],A7:A6
  166. || LDDW .D2T2 *++SP[1],B7:B6
  167. || MVC .S2 B10,ILC ; Restore ILC
  168. LDDW .D1T1 *++A15[1],A9:A8
  169. || LDDW .D2T2 *++SP[1],B9:B8
  170. || MVC .S2 B13,IRP ; Restore IPR
  171. LDDW .D1T1 *++A15[1],A11:A10
  172. || LDDW .D2T2 *++SP[1],B11:B10
  173. || MVC .S2 B12,CSR ; Restore CSR
  174. LDDW .D1T1 *++A15[1],A13:A12
  175. || LDDW .D2T2 *++SP[1],B13:B12
  176. MV .D2X A15,SP
  177. LDDW .D2T1 *++SP[1],A15:A14
  178. B IRP ; Return to point of interrupt
  179. LDDW .D2T2 *+SP[1],SP:DP
  180. NOP 4 ; Delay slots
  181. ;}
  182. ;
  183. ;-----------------------------------------------------------
  184. ;
  185. ;
  186. ; void rt_hw_context_switch_interrupt(rt_uint32_t from, rt_uint32_t to)
  187. ; A4 --> from
  188. ; B4 --> to
  189. ;{
  190. .global rt_hw_context_switch_interrupt
  191. rt_hw_context_switch_interrupt:
  192. SUB B15,0x8,B15
  193. STW B4,*B15[2]
  194. STW A4,*B15[1]
  195. LDW *+B14(rt_thread_switch_interrupt_flag),B4
  196. NOP 4
  197. CMPEQ 1,B4,B0
  198. [ B0] BNOP _reswitch,5
  199. MVK 1,B4
  200. STW B4,*+B14(rt_thread_switch_interrupt_flag)
  201. MV A4,B4
  202. STW B4,*+B14(rt_interrupt_from_thread)
  203. _reswitch:
  204. LDW *B15[2],B4
  205. NOP 4
  206. STW B4,*+B14(rt_interrupt_to_thread)
  207. ADD 8,B15,B15
  208. BNOP B3,5
  209. ;}
  210. ;-----------------------------------------------------------
  211. ;
  212. ;void rt_interrupt_context_restore(void)
  213. ;
  214. .global rt_interrupt_context_restore
  215. rt_interrupt_context_restore:
  216. ;{
  217. MVKL rt_thread_switch_interrupt_flag,A3
  218. MVKH rt_thread_switch_interrupt_flag,A3
  219. LDW *A3,A1
  220. NOP 4
  221. CMPEQ 1,A1,A2
  222. [A2] BNOP rt_preempt_context_restore,5
  223. NOP 5
  224. LDDW .D2T2 *++SP[1],B9:B8 ; get TSR (B9)
  225. LDDW .D2T2 *++SP[1],B11:B10 ; get RILC (B11) and ILC (B10)
  226. LDDW .D2T2 *++SP[1],B13:B12 ; get PC (B13) and CSR (B12)
  227. ADDAW .D1X SP,30,A15
  228. LDDW .D1T1 *++A15[1],A17:A16
  229. || LDDW .D2T2 *++SP[1],B17:B16
  230. LDDW .D1T1 *++A15[1],A19:A18
  231. || LDDW .D2T2 *++SP[1],B19:B18
  232. LDDW .D1T1 *++A15[1],A21:A20
  233. || LDDW .D2T2 *++SP[1],B21:B20
  234. LDDW .D1T1 *++A15[1],A23:A22
  235. || LDDW .D2T2 *++SP[1],B23:B22
  236. LDDW .D1T1 *++A15[1],A25:A24
  237. || LDDW .D2T2 *++SP[1],B25:B24
  238. LDDW .D1T1 *++A15[1],A27:A26
  239. || LDDW .D2T2 *++SP[1],B27:B26
  240. LDDW .D1T1 *++A15[1],A29:A28
  241. || LDDW .D2T2 *++SP[1],B29:B28
  242. LDDW .D1T1 *++A15[1],A31:A30
  243. || LDDW .D2T2 *++SP[1],B31:B30
  244. LDDW .D1T1 *++A15[1],A1:A0
  245. || LDDW .D2T2 *++SP[1],B1:B0
  246. LDDW .D1T1 *++A15[1],A3:A2
  247. || LDDW .D2T2 *++SP[1],B3:B2
  248. || MVC .S2 B9,ITSR
  249. LDDW .D1T1 *++A15[1],A5:A4
  250. || LDDW .D2T2 *++SP[1],B5:B4
  251. || MVC .S2 B11,RILC
  252. LDDW .D1T1 *++A15[1],A7:A6
  253. || LDDW .D2T2 *++SP[1],B7:B6
  254. || MVC .S2 B10,ILC
  255. LDDW .D1T1 *++A15[1],A9:A8
  256. || LDDW .D2T2 *++SP[1],B9:B8
  257. || MVC .S2 B13,IRP
  258. LDDW .D1T1 *++A15[1],A11:A10
  259. || LDDW .D2T2 *++SP[1],B11:B10
  260. || MVC .S2 B12,CSR
  261. LDDW .D1T1 *++A15[1],A13:A12
  262. || LDDW .D2T2 *++SP[1],B13:B12
  263. MV .D2X A15,SP
  264. || MVKL .S1 rt_system_stack_top,A15
  265. MVKH .S1 rt_system_stack_top,A15
  266. || ADDAW .D1X SP,6,A14
  267. STW .D1T1 A14,*A15 ; save system stack pointer
  268. LDDW .D2T1 *++SP[1],A15:A14
  269. B .S2 IRP ; return from interruption
  270. LDDW .D2T2 *+SP[1],SP:DP
  271. NOP 4
  272. rt_preempt_context_restore:
  273. ZERO A12
  274. STW A12,*A3 ; clear rt_thread_switch_interrupt_flag
  275. ;
  276. ; restore saved registers by system stack
  277. ;
  278. RESTORE_ALL IRP,ITSR
  279. ;
  280. ; store registers to thread stack
  281. ;
  282. THREAD_SAVE_ALL IRP,ITSR
  283. MVKL rt_interrupt_from_thread,A11
  284. MVKH rt_interrupt_from_thread,A11
  285. LDW *A11,A10
  286. NOP
  287. MVKL rt_interrupt_to_thread,B10
  288. MVKH rt_interrupt_to_thread,B10
  289. LDW *B10,B11
  290. NOP 3
  291. STW SP,*A10 ; store sp in preempted tasks's TCB
  292. B rt_hw_context_switch_to
  293. MV B11,A4
  294. NOP 4
  295. ;}
  296. .end