tbisoft.S 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * tbisoft.S
  3. *
  4. * Copyright (C) 2001, 2002, 2007, 2012 Imagination Technologies.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it under
  7. * the terms of the GNU General Public License version 2 as published by the
  8. * Free Software Foundation.
  9. *
  10. * Support for soft threads and soft context switches
  11. */
  12. .file "tbisoft.S"
  13. #include <asm/tbx.h>
  14. #ifdef METAC_1_0
  15. /* Ax.4 is saved in TBICTX */
  16. #define A0_4 ,A0.4
  17. #define D0_5 ,D0.5
  18. #else
  19. /* Ax.4 is NOT saved in TBICTX */
  20. #define A0_4
  21. #define D0_5
  22. #endif
  23. /* Size of the TBICTX structure */
  24. #define TBICTX_BYTES ((TBICTX_AX_REGS*8)+TBICTX_AX)
  25. .text
  26. .balign 4
  27. .global ___TBISwitchTail
  28. .type ___TBISwitchTail,function
  29. ___TBISwitchTail:
  30. B $LSwitchTail
  31. .size ___TBISwitchTail,.-___TBISwitchTail
  32. /*
  33. * TBIRES __TBIJumpX( TBIX64 ArgsA, PTBICTX *rpSaveCtx, int TrigsMask,
  34. * void (*fnMain)(), void *pStack );
  35. *
  36. * This is a combination of __TBISwitch and __TBIJump with the context of
  37. * the calling thread being saved in the rpSaveCtx location with a drop-thru
  38. * effect into the __TBIJump logic. ArgsB passes via __TBIJump to the
  39. * routine eventually invoked will reflect the rpSaveCtx value specified.
  40. */
  41. .text
  42. .balign 4
  43. .global ___TBIJumpX
  44. .type ___TBIJumpX,function
  45. ___TBIJumpX:
  46. CMP D1RtP,#-1
  47. B $LSwitchStart
  48. .size ___TBIJumpX,.-___TBIJumpX
  49. /*
  50. * TBIRES __TBISwitch( TBIRES Switch, PTBICTX *rpSaveCtx )
  51. *
  52. * Software syncronous context switch between soft threads, save only the
  53. * registers which are actually valid on call entry.
  54. *
  55. * A0FrP, D0RtP, D0.5, D0.6, D0.7 - Saved on stack
  56. * A1GbP is global to all soft threads so not virtualised
  57. * A0StP is then saved as the base of the TBICTX of the thread
  58. *
  59. */
  60. .text
  61. .balign 4
  62. .global ___TBISwitch
  63. .type ___TBISwitch,function
  64. ___TBISwitch:
  65. XORS D0Re0,D0Re0,D0Re0 /* Set ZERO flag */
  66. $LSwitchStart:
  67. MOV D0FrT,A0FrP /* Boing entry sequence */
  68. ADD A0FrP,A0StP,#0
  69. SETL [A0StP+#8++],D0FrT,D1RtP
  70. /*
  71. * Save current frame state - we save all regs because we don't want
  72. * uninitialised crap in the TBICTX structure that the asyncronous resumption
  73. * of a thread will restore.
  74. */
  75. MOVT D1Re0,#HI($LSwitchExit) /* ASync resume point here */
  76. ADD D1Re0,D1Re0,#LO($LSwitchExit)
  77. SETD [D1Ar3],A0StP /* Record pCtx of this thread */
  78. MOVT D0Re0,#TBICTX_SOFT_BIT /* Only soft thread state */
  79. SETL [A0StP++],D0Re0,D1Re0 /* Push header fields */
  80. ADD D0FrT,A0StP,#TBICTX_AX-TBICTX_DX /* Address AX save area */
  81. MOV D0Re0,#0 /* Setup 0:0 result for ASync */
  82. MOV D1Re0,#0 /* resume of the thread */
  83. MSETL [A0StP],D0Re0,D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7
  84. SETL [A0StP++],D0Re0,D1Re0 /* Zero CurrRPT, CurrBPOBITS, */
  85. SETL [A0StP++],D0Re0,D1Re0 /* Zero CurrMODE, CurrDIVTIME */
  86. ADD A0StP,A0StP,#(TBICTX_AX_REGS*8) /* Reserve AX save space */
  87. MSETL [D0FrT],A0StP,A0FrP,A0.2,A0.3 A0_4 /* Save AX regs */
  88. BNZ ___TBIJump
  89. /*
  90. * NextThread MUST be in TBICTX_SOFT_BIT state!
  91. */
  92. $LSwitchTail:
  93. MOV D0Re0,D0Ar2 /* Result from args */
  94. MOV D1Re0,D1Ar1
  95. ADD D1RtP,D1Ar1,#TBICTX_AX
  96. MGETL A0StP,A0FrP,[D1RtP] /* Get frame values */
  97. $LSwitchCmn:
  98. ADD A0.2,D1Ar1,#TBICTX_DX+(8*5)
  99. MGETL D0.5,D0.6,D0.7,[A0.2] /* Get caller-saved DX regs */
  100. $LSwitchExit:
  101. GETL D0FrT,D1RtP,[A0FrP++] /* Restore state from frame */
  102. SUB A0StP,A0FrP,#8 /* Unwind stack */
  103. MOV A0FrP,D0FrT /* Last memory read completes */
  104. MOV PC,D1RtP /* Return to caller */
  105. .size ___TBISwitch,.-___TBISwitch
  106. /*
  107. * void __TBISyncResume( TBIRES State, int TrigMask );
  108. *
  109. * This routine causes the TBICTX structure specified in State.Sig.pCtx to
  110. * be restored. This implies that execution will not return to the caller.
  111. * The State.Sig.TrigMask field will be ored into TXMASKI during the
  112. * context switch such that any immediately occuring interrupts occur in
  113. * the context of the newly specified task. The State.Sig.SaveMask parameter
  114. * is ignored.
  115. */
  116. .text
  117. .balign 4
  118. .global ___TBISyncResume
  119. .type ___TBISyncResume,function
  120. ___TBISyncResume:
  121. MOV D0Re0,D0Ar2 /* Result from args */
  122. MOV D1Re0,D1Ar1
  123. XOR D1Ar5,D1Ar5,D1Ar5 /* D1Ar5 = 0 */
  124. ADD D1RtP,D1Ar1,#TBICTX_AX
  125. SWAP D1Ar5,TXMASKI /* D1Ar5 <-> TXMASKI */
  126. MGETL A0StP,A0FrP,[D1RtP] /* Get frame values */
  127. OR TXMASKI,D1Ar5,D1Ar3 /* New TXMASKI */
  128. B $LSwitchCmn
  129. .size ___TBISyncResume,.-___TBISyncResume
  130. /*
  131. * void __TBIJump( TBIX64 ArgsA, TBIX32 ArgsB, int TrigsMask,
  132. * void (*fnMain)(), void *pStack );
  133. *
  134. * Jump directly to a new routine on an arbitrary stack with arbitrary args
  135. * oring bits back into TXMASKI on route.
  136. */
  137. .text
  138. .balign 4
  139. .global ___TBIJump
  140. .type ___TBIJump,function
  141. ___TBIJump:
  142. XOR D0Re0,D0Re0,D0Re0 /* D0Re0 = 0 */
  143. MOV A0StP,D0Ar6 /* Stack = Frame */
  144. SWAP D0Re0,TXMASKI /* D0Re0 <-> TXMASKI */
  145. MOV A0FrP,D0Ar6
  146. MOVT A1LbP,#HI(__exit)
  147. ADD A1LbP,A1LbP,#LO(__exit)
  148. MOV D1RtP,A1LbP /* D1RtP = __exit */
  149. OR TXMASKI,D0Re0,D0Ar4 /* New TXMASKI */
  150. MOV PC,D1Ar5 /* Jump to fnMain */
  151. .size ___TBIJump,.-___TBIJump
  152. /*
  153. * PTBICTX __TBISwitchInit( void *pStack, int (*fnMain)(),
  154. * .... 4 extra 32-bit args .... );
  155. *
  156. * Generate a new soft thread context ready for it's first outing.
  157. *
  158. * D1Ar1 - Region of memory to be used as the new soft thread stack
  159. * D0Ar2 - Main line routine for new soft thread
  160. * D1Ar3, D0Ar4, D1Ar5, D0Ar6 - arguments to be passed on stack
  161. * The routine returns the initial PTBICTX value for the new thread
  162. */
  163. .text
  164. .balign 4
  165. .global ___TBISwitchInit
  166. .type ___TBISwitchInit,function
  167. ___TBISwitchInit:
  168. MOV D0FrT,A0FrP /* Need save return point */
  169. ADD A0FrP,A0StP,#0
  170. SETL [A0StP++],D0FrT,D1RtP /* Save return to caller */
  171. MOVT A1LbP,#HI(__exit)
  172. ADD A1LbP,A1LbP,#LO(__exit)
  173. MOV D1RtP,A1LbP /* Get address of __exit */
  174. ADD D1Ar1,D1Ar1,#7 /* Align stack to 64-bits */
  175. ANDMB D1Ar1,D1Ar1,#0xfff8 /* by rounding base up */
  176. MOV A0.2,D1Ar1 /* A0.2 is new stack */
  177. MOV D0FrT,D1Ar1 /* Initial puesdo-frame pointer */
  178. SETL [A0.2++],D0FrT,D1RtP /* Save return to __exit */
  179. MOV D1RtP,D0Ar2
  180. SETL [A0.2++],D0FrT,D1RtP /* Save return to fnMain */
  181. ADD D0FrT,D0FrT,#8 /* Advance puesdo-frame pointer */
  182. MSETL [A0.2],D0Ar6,D0Ar4 /* Save extra initial args */
  183. MOVT D1RtP,#HI(___TBIStart) /* Start up code for new stack */
  184. ADD D1RtP,D1RtP,#LO(___TBIStart)
  185. SETL [A0.2++],D0FrT,D1RtP /* Save return to ___TBIStart */
  186. ADD D0FrT,D0FrT,#(8*3) /* Advance puesdo-frame pointer */
  187. MOV D0Re0,A0.2 /* Return pCtx for new thread */
  188. MOV D1Re0,#0 /* pCtx:0 is default Arg1:Arg2 */
  189. /*
  190. * Generate initial TBICTX state
  191. */
  192. MOVT D1Ar1,#HI($LSwitchExit) /* Async restore code */
  193. ADD D1Ar1,D1Ar1,#LO($LSwitchExit)
  194. MOVT D0Ar2,#TBICTX_SOFT_BIT /* Only soft thread state */
  195. ADD D0Ar6,A0.2,#TBICTX_BYTES /* New A0StP */
  196. MOV D1Ar5,A1GbP /* Same A1GbP */
  197. MOV D0Ar4,D0FrT /* Initial A0FrP */
  198. MOV D1Ar3,A1LbP /* Same A1LbP */
  199. SETL [A0.2++],D0Ar2,D1Ar1 /* Set header fields */
  200. MSETL [A0.2],D0Re0,D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7
  201. MOV D0Ar2,#0 /* Zero values */
  202. MOV D1Ar1,#0
  203. SETL [A0.2++],D0Ar2,D1Ar1 /* Zero CurrRPT, CurrBPOBITS, */
  204. SETL [A0.2++],D0Ar2,D1Ar1 /* CurrMODE, and pCurrCBuf */
  205. MSETL [A0.2],D0Ar6,D0Ar4,D0Ar2,D0FrT D0_5 /* Set DX and then AX regs */
  206. B $LSwitchExit /* All done! */
  207. .size ___TBISwitchInit,.-___TBISwitchInit
  208. .text
  209. .balign 4
  210. .global ___TBIStart
  211. .type ___TBIStart,function
  212. ___TBIStart:
  213. MOV D1Ar1,D1Re0 /* Pass TBIRES args to call */
  214. MOV D0Ar2,D0Re0
  215. MGETL D0Re0,D0Ar6,D0Ar4,[A0FrP] /* Get hidden args */
  216. SUB A0StP,A0FrP,#(8*3) /* Entry stack pointer */
  217. MOV A0FrP,D0Re0 /* Entry frame pointer */
  218. MOVT A1LbP,#HI(__exit)
  219. ADD A1LbP,A1LbP,#LO(__exit)
  220. MOV D1RtP,A1LbP /* D1RtP = __exit */
  221. MOV PC,D1Re0 /* Jump into fnMain */
  222. .size ___TBIStart,.-___TBIStart
  223. /*
  224. * End of tbisoft.S
  225. */