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