Merge branch 'for-3.9/upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / metag / tbx / tbisoft.S
CommitLineData
027f891f
JH
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 */