context.asm 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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. MVC .S2 B11,RILC ; Restore RILC
  128. MVC .S2 B10,ILC ; Restore ILC
  129. MV B13,B3 ; Restore PC
  130. MVC .S2 B12,CSR ; Restore CSR
  131. LDDW .D2T2 *++SP[1],B11:B10
  132. LDDW .D2T2 *++SP[1],B13:B12
  133. LDDW .D2T1 *++SP[1],A11:A10
  134. LDDW .D2T1 *++SP[1],A13:A12
  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. ; if rt_switch_interrupt_flag set, jump to rt_hw_context_switch_interrupt and don't return
  218. MVKL rt_thread_switch_interrupt_flag,A3
  219. MVKH rt_thread_switch_interrupt_flag,A3
  220. LDW *A3,A1
  221. NOP 4
  222. CMPEQ 1,A1,A2
  223. [A2] BNOP rt_preempt_context_restore,5
  224. NOP 5
  225. LDDW .D2T2 *++SP[1],B9:B8 ; get TSR (B9)
  226. LDDW .D2T2 *++SP[1],B11:B10 ; get RILC (B11) and ILC (B10)
  227. LDDW .D2T2 *++SP[1],B13:B12 ; get PC (B13) and CSR (B12)
  228. ADDAW .D1X SP,30,A15
  229. LDDW .D1T1 *++A15[1],A17:A16
  230. || LDDW .D2T2 *++SP[1],B17:B16
  231. LDDW .D1T1 *++A15[1],A19:A18
  232. || LDDW .D2T2 *++SP[1],B19:B18
  233. LDDW .D1T1 *++A15[1],A21:A20
  234. || LDDW .D2T2 *++SP[1],B21:B20
  235. LDDW .D1T1 *++A15[1],A23:A22
  236. || LDDW .D2T2 *++SP[1],B23:B22
  237. LDDW .D1T1 *++A15[1],A25:A24
  238. || LDDW .D2T2 *++SP[1],B25:B24
  239. LDDW .D1T1 *++A15[1],A27:A26
  240. || LDDW .D2T2 *++SP[1],B27:B26
  241. LDDW .D1T1 *++A15[1],A29:A28
  242. || LDDW .D2T2 *++SP[1],B29:B28
  243. LDDW .D1T1 *++A15[1],A31:A30
  244. || LDDW .D2T2 *++SP[1],B31:B30
  245. LDDW .D1T1 *++A15[1],A1:A0
  246. || LDDW .D2T2 *++SP[1],B1:B0
  247. LDDW .D1T1 *++A15[1],A3:A2
  248. || LDDW .D2T2 *++SP[1],B3:B2
  249. || MVC .S2 B9,ITSR
  250. LDDW .D1T1 *++A15[1],A5:A4
  251. || LDDW .D2T2 *++SP[1],B5:B4
  252. || MVC .S2 B11,RILC
  253. LDDW .D1T1 *++A15[1],A7:A6
  254. || LDDW .D2T2 *++SP[1],B7:B6
  255. || MVC .S2 B10,ILC
  256. LDDW .D1T1 *++A15[1],A9:A8
  257. || LDDW .D2T2 *++SP[1],B9:B8
  258. || MVC .S2 B13,IRP
  259. LDDW .D1T1 *++A15[1],A11:A10
  260. || LDDW .D2T2 *++SP[1],B11:B10
  261. || MVC .S2 B12,CSR
  262. LDDW .D1T1 *++A15[1],A13:A12
  263. || LDDW .D2T2 *++SP[1],B13:B12
  264. MV .D2X A15,SP
  265. || MVKL .S1 rt_system_stack_top,A15
  266. MVKH .S1 rt_system_stack_top,A15
  267. || ADDAW .D1X SP,6,A14
  268. STW .D1T1 A14,*A15 ; save system stack pointer
  269. LDDW .D2T1 *++SP[1],A15:A14
  270. B .S2 IRP ; return from interruption
  271. LDDW .D2T2 *+SP[1],SP:DP
  272. NOP 4
  273. rt_preempt_context_restore:
  274. ZERO A12
  275. STW A12,*A3 ; clear rt_thread_switch_interrupt_flag
  276. ;
  277. ; restore saved registers by system stack
  278. ;
  279. RESTORE_ALL IRP,ITSR
  280. ;
  281. ; store registers to thread stack
  282. ;
  283. THREAD_SAVE_ALL IRP,ITSR
  284. MVKL rt_interrupt_from_thread,A11
  285. MVKH rt_interrupt_from_thread,A11
  286. LDW *A11,A10
  287. NOP
  288. MVKL rt_interrupt_to_thread,B10
  289. MVKH rt_interrupt_to_thread,B10
  290. LDW *B10,B11
  291. NOP 3
  292. STW SP,*A10 ; store sp in preempted tasks's TCB
  293. B rt_hw_context_switch_to
  294. MV B11,A4 ;
  295. NOP 4
  296. ;}
  297. .end