context.asm 8.9 KB

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