context.asm 7.5 KB

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