context.asm 9.8 KB

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