Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
[linux-2.6-block.git] / arch / metag / tbx / tbictx.S
CommitLineData
027f891f
JH
1/*
2 * tbictx.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 * Explicit state save and restore routines forming part of the thread binary
11 * interface for META processors
12 */
13
14 .file "tbictx.S"
15#include <asm/metag_regs.h>
16#include <asm/tbx.h>
17
18#ifdef METAC_1_0
19/* Ax.4 is NOT saved in XAX3 */
20#define A0_4
21#else
22/* Ax.4 is saved in XAX4 */
23#define A0_4 A0.4,
24#endif
25
26
27/* Size of the TBICTX structure */
28#define TBICTX_BYTES ((TBICTX_AX_REGS*8)+TBICTX_AX)
29
30/*
31 * TBIRES __TBINestInts( TBIRES State, void *pExt, int NoNestMask )
32 */
33 .text
34 .balign 4
35 .global ___TBINestInts
36 .type ___TBINestInts,function
37___TBINestInts:
38 XOR D0Ar4,D0Ar4,#-1 /* D0Ar4 = ~TrigBit */
39 AND D0Ar4,D0Ar4,#0xFFFF /* D0Ar4 &= 0xFFFF */
40 MOV D0Ar6,TXMASKI /* BGNDHALT currently enabled? */
41 TSTT D0Ar2,#TBICTX_XDX8_BIT+TBICTX_XAXX_BIT+TBICTX_XHL2_BIT+TBICTX_XTDP_BIT+TBICTX_XCBF_BIT
42 AND D0Ar4,D0Ar2,D0Ar4 /* D0Ar4 = Ints to allow */
43 XOR D0Ar2,D0Ar2,D0Ar4 /* Less Ints in TrigMask */
44 BNZ ___TBINestInts2 /* Jump if ctx save required! */
45 TSTT D0Ar2,#TBICTX_CBUF_BIT+TBICTX_CBRP_BIT /* Is catch state dirty? */
46 OR D0Ar4,D0Ar4,D0Ar6 /* Or in TXMASKI BGNDHALT if set */
47 TSTNZ D0Ar4,D0Ar4 /* Yes: AND triggers enabled */
48 MOV D0Re0,D0Ar2 /* Update State argument */
49 MOV D1Re0,D1Ar1 /* with less Ints in TrigMask */
50 MOVZ TXMASKI,D0Ar4 /* Early return: Enable Ints */
51 MOVZ PC,D1RtP /* Early return */
52 .size ___TBINestInts,.-___TBINestInts
53/*
54 * Drop thru into sub-function-
55 */
56 .global ___TBINestInts2
57 .type ___TBINestInts2,function
58___TBINestInts2:
59 MOV D0FrT,A0FrP /* Full entry sequence so we */
60 ADD A0FrP,A0StP,#0 /* can make sub-calls */
61 MSETL [A0StP],D0FrT,D0.5,D0.6 /* and preserve our result */
62 ORT D0Ar2,D0Ar2,#TBICTX_XCBF_BIT /* Add in XCBF save request */
63 MOV D0.5,D0Ar2 /* Save State in DX.5 */
64 MOV D1.5,D1Ar1
65 OR D0.6,D0Ar4,D0Ar6 /* Save TrigMask in D0.6 */
66 MOVT D1RtP,#HI(___TBICtxSave) /* Save catch buffer */
67 CALL D1RtP,#LO(___TBICtxSave)
68 MOV TXMASKI,D0.6 /* Allow Ints */
69 MOV D0Re0,D0.5 /* Return State */
70 MOV D1Re0,D1.5
71 MGETL D0FrT,D0.5,D0.6,[A0FrP] /* Full exit sequence */
72 SUB A0StP,A0FrP,#(8*3)
73 MOV A0FrP,D0FrT
74 MOV PC,D1RtP
75 .size ___TBINestInts2,.-___TBINestInts2
76
77/*
78 * void *__TBICtxSave( TBIRES State, void *pExt )
79 *
80 * D0Ar2 contains TBICTX_*_BIT values that control what
81 * extended data is to be saved beyond the end of D1Ar1.
82 * These bits must be ored into the SaveMask of this structure.
83 *
84 * Virtually all possible scratch registers are used.
85 *
86 * The D1Ar1 parameter is only used as the basis for saving
87 * CBUF state.
88 */
89/*
90 * If TBICTX_XEXT_BIT is specified in State. then State.pCtx->Ext is
91 * utilised to save the base address of the context save area and
92 * the extended states saved. The XEXT flag then indicates that the
93 * original state of the A0.2 and A1.2 registers from TBICTX.Ext.AX2
94 * are stored as the first part of the extended state structure.
95 */
96 .balign 4
97 .global ___TBICtxSave
98 .type ___TBICtxSave,function
99___TBICtxSave:
100 GETD D0Re0,[D1Ar1+#TBICTX_SaveMask-2] /* Get SaveMask */
101 TSTT D0Ar2,#TBICTX_XDX8_BIT+TBICTX_XAXX_BIT+TBICTX_XHL2_BIT+TBICTX_XTDP_BIT+TBICTX_XEXT_BIT
102 /* Just XCBF to save? */
103 MOV A0.2,D1Ar3 /* Save pointer into A0.2 */
104 MOV A1.2,D1RtP /* Free off D0FrT:D1RtP pair */
105 BZ $LCtxSaveCBUF /* Yes: Only XCBF may be saved */
106 TSTT D0Ar2,#TBICTX_XEXT_BIT /* Extended base-state model? */
107 BZ $LCtxSaveXDX8
108 GETL D0Ar6,D1Ar5,[D1Ar1+#TBICTX_Ext_AX2] /* Get A0.2, A1.2 state */
109 MOV D0Ar4,D0Ar2 /* Extract Ctx.SaveFlags value */
110 ANDMT D0Ar4,D0Ar4,#TBICTX_XDX8_BIT+TBICTX_XAXX_BIT+TBICTX_XHL2_BIT+TBICTX_XTDP_BIT+TBICTX_XEXT_BIT
111 SETD [D1Ar1+#TBICTX_Ext_Ctx_pExt],A0.2
112 SETD [D1Ar1+#TBICTX_Ext_Ctx_SaveMask-2],D0Ar4
113 SETL [A0.2++],D0Ar6,D1Ar5 /* Save A0.2, A1.2 state */
114$LCtxSaveXDX8:
115 TSTT D0Ar2,#TBICTX_XDX8_BIT /* Save extended DX regs? */
116 BZ $LCtxSaveXAXX
117/*
118 * Save 8 extra DX registers
119 */
120 MSETL [A0.2],D0.8,D0.9,D0.10,D0.11,D0.12,D0.13,D0.14,D0.15
121$LCtxSaveXAXX:
122 TSTT D0Ar2,#TBICTX_XAXX_BIT /* Save extended AX regs? */
123 SWAP D0Re0,A0.2 /* pDst into D0Re0 */
124 BZ $LCtxSaveXHL2
125/*
126 * Save 4 extra AX registers
127 */
128 MSETL [D0Re0], A0_4 A0.5,A0.6,A0.7 /* Save 8*3 bytes */
129$LCtxSaveXHL2:
130 TSTT D0Ar2,#TBICTX_XHL2_BIT /* Save hardware-loop regs? */
131 SWAP D0Re0,A0.2 /* pDst back into A0.2 */
132 MOV D0Ar6,TXL1START
133 MOV D1Ar5,TXL2START
134 BZ $LCtxSaveXTDP
135/*
136 * Save hardware loop registers
137 */
138 SETL [A0.2++],D0Ar6,D1Ar5 /* Save 8*1 bytes */
139 MOV D0Ar6,TXL1END
140 MOV D1Ar5,TXL2END
141 MOV D0FrT,TXL1COUNT
142 MOV D1RtP,TXL2COUNT
143 MSETL [A0.2],D0Ar6,D0FrT /* Save 8*2 bytes */
144/*
145 * Clear loop counters to disable any current loops
146 */
147 XOR TXL1COUNT,D0FrT,D0FrT
148 XOR TXL2COUNT,D1RtP,D1RtP
149$LCtxSaveXTDP:
150 TSTT D0Ar2,#TBICTX_XTDP_BIT /* Save per-thread DSP regs? */
151 BZ $LCtxSaveCBUF
152/*
153 * Save per-thread DSP registers; ACC.0, PR.0, PI.1-3 (PI.0 is zero)
154 */
155#ifndef CTX_NO_DSP
156D SETL [A0.2++],AC0.0,AC1.0 /* Save ACx.0 lower 32-bits */
157DH SETL [A0.2++],AC0.0,AC1.0 /* Save ACx.0 upper 32-bits */
158D SETL [A0.2++],D0AR.0,D1AR.0 /* Save DSP RAM registers */
159D SETL [A0.2++],D0AR.1,D1AR.1
160D SETL [A0.2++],D0AW.0,D1AW.0
161D SETL [A0.2++],D0AW.1,D1AW.1
162D SETL [A0.2++],D0BR.0,D1BR.0
163D SETL [A0.2++],D0BR.1,D1BR.1
164D SETL [A0.2++],D0BW.0,D1BW.0
165D SETL [A0.2++],D0BW.1,D1BW.1
166D SETL [A0.2++],D0ARI.0,D1ARI.0
167D SETL [A0.2++],D0ARI.1,D1ARI.1
168D SETL [A0.2++],D0AWI.0,D1AWI.0
169D SETL [A0.2++],D0AWI.1,D1AWI.1
170D SETL [A0.2++],D0BRI.0,D1BRI.0
171D SETL [A0.2++],D0BRI.1,D1BRI.1
172D SETL [A0.2++],D0BWI.0,D1BWI.0
173D SETL [A0.2++],D0BWI.1,D1BWI.1
174D SETD [A0.2++],T0
175D SETD [A0.2++],T1
176D SETD [A0.2++],T2
177D SETD [A0.2++],T3
178D SETD [A0.2++],T4
179D SETD [A0.2++],T5
180D SETD [A0.2++],T6
181D SETD [A0.2++],T7
182D SETD [A0.2++],T8
183D SETD [A0.2++],T9
184D SETD [A0.2++],TA
185D SETD [A0.2++],TB
186D SETD [A0.2++],TC
187D SETD [A0.2++],TD
188D SETD [A0.2++],TE
189D SETD [A0.2++],TF
190#else
191 ADD A0.2,A0.2,#(8*18+4*16)
192#endif
193 MOV D0Ar6,TXMRSIZE
194 MOV D1Ar5,TXDRSIZE
195 SETL [A0.2++],D0Ar6,D1Ar5 /* Save 8*1 bytes */
196
197$LCtxSaveCBUF:
198#ifdef TBI_1_3
199 MOV D0Ar4,D0Re0 /* Copy Ctx Flags */
200 ANDT D0Ar4,D0Ar4,#TBICTX_XCBF_BIT /* mask XCBF if already set */
201 XOR D0Ar4,D0Ar4,#-1
202 AND D0Ar2,D0Ar2,D0Ar4 /* remove XCBF if already set */
203#endif
204 TSTT D0Ar2,#TBICTX_XCBF_BIT /* Want to save CBUF? */
205 ANDT D0Ar2,D0Ar2,#TBICTX_XDX8_BIT+TBICTX_XAXX_BIT+TBICTX_XHL2_BIT+TBICTX_XTDP_BIT+TBICTX_XEXT_BIT
206 OR D0Ar2,D0Ar2,D0Re0 /* Generate new SaveMask */
207 SETD [D1Ar1+#TBICTX_SaveMask-2],D0Ar2/* Add in bits saved to TBICTX */
208 MOV D0Re0,A0.2 /* Return end of save area */
209 MOV D0Ar4,TXDIVTIME /* Get TXDIVTIME */
210 MOVZ PC,A1.2 /* No: Early return */
211 TSTT D0Ar2,#TBICTX_CBUF_BIT+TBICTX_CBRP_BIT /* Need to save CBUF? */
212 MOVZ PC,A1.2 /* No: Early return */
213 ORT D0Ar2,D0Ar2,#TBICTX_XCBF_BIT
214 SETD [D1Ar1+#TBICTX_SaveMask-2],D0Ar2/* Add in XCBF bit to TBICTX */
215 ADD A0.2,D1Ar1,#TBICTX_BYTES /* Dump CBUF state after TBICTX */
216/*
217 * Save CBUF
218 */
219 SETD [A0.2+# 0],TXCATCH0 /* Restore TXCATCHn */
220 SETD [A0.2+# 4],TXCATCH1
221 TSTT D0Ar2,#TBICTX_CBRP_BIT /* ... RDDIRTY was/is set */
222 SETD [A0.2+# 8],TXCATCH2
223 SETD [A0.2+#12],TXCATCH3
224 BZ $LCtxSaveComplete
225 SETL [A0.2+#(2*8)],RD /* Save read pipeline */
226 SETL [A0.2+#(3*8)],RD /* Save read pipeline */
227 SETL [A0.2+#(4*8)],RD /* Save read pipeline */
228 SETL [A0.2+#(5*8)],RD /* Save read pipeline */
229 SETL [A0.2+#(6*8)],RD /* Save read pipeline */
230 SETL [A0.2+#(7*8)],RD /* Save read pipeline */
231 AND TXDIVTIME,D0Ar4,#TXDIVTIME_DIV_BITS /* Clear RPDIRTY */
232$LCtxSaveComplete:
233 MOV PC,A1.2 /* Return */
234 .size ___TBICtxSave,.-___TBICtxSave
235
236/*
237 * void *__TBICtxRestore( TBIRES State, void *pExt )
238 *
239 * D0Ar2 contains TBICTX_*_BIT values that control what
240 * extended data is to be recovered from D1Ar3 (pExt).
241 *
242 * Virtually all possible scratch registers are used.
243 */
244/*
245 * If TBICTX_XEXT_BIT is specified in State. Then the saved state of
246 * the orginal A0.2 and A1.2 is restored from pExt and the XEXT
247 * related flags are removed from State.pCtx->SaveMask.
248 *
249 */
250 .balign 4
251 .global ___TBICtxRestore
252 .type ___TBICtxRestore,function
253___TBICtxRestore:
254 GETD D0Ar6,[D1Ar1+#TBICTX_CurrMODE] /* Get TXMODE Value */
255 ANDST D0Ar2,D0Ar2,#TBICTX_XDX8_BIT+TBICTX_XAXX_BIT+TBICTX_XHL2_BIT+TBICTX_XTDP_BIT+TBICTX_XEXT_BIT
256 MOV D1Re0,D0Ar2 /* Keep flags in D1Re0 */
257 MOV D0Re0,D1Ar3 /* D1Ar3 is default result */
258 MOVZ PC,D1RtP /* Early return, nothing to do */
259 ANDT D0Ar6,D0Ar6,#0xE000 /* Top bits of TXMODE required */
260 MOV A0.3,D0Ar6 /* Save TXMODE for later */
261 TSTT D1Re0,#TBICTX_XEXT_BIT /* Check for XEXT bit */
262 BZ $LCtxRestXDX8
263 GETD D0Ar4,[D1Ar1+#TBICTX_SaveMask-2]/* Get current SaveMask */
264 GETL D0Ar6,D1Ar5,[D0Re0++] /* Restore A0.2, A1.2 state */
265 ANDMT D0Ar4,D0Ar4,#(0xFFFF-(TBICTX_XDX8_BIT+TBICTX_XAXX_BIT+TBICTX_XHL2_BIT+TBICTX_XTDP_BIT+TBICTX_XEXT_BIT))
266 SETD [D1Ar1+#TBICTX_SaveMask-2],D0Ar4/* New SaveMask */
267#ifdef METAC_1_0
268 SETD [D1Ar1+#TBICTX_Ext_AX2_U0],D0Ar6
269 MOV D0Ar6,D1Ar1
270 SETD [D0Ar6+#TBICTX_Ext_AX2_U1],D1Ar5
271#else
272 SETL [D1Ar1+#TBICTX_Ext_AX2],D0Ar6,D1Ar5
273#endif
274$LCtxRestXDX8:
275 TSTT D1Re0,#TBICTX_XDX8_BIT /* Get extended DX regs? */
276 MOV A1.2,D1RtP /* Free off D1RtP register */
277 BZ $LCtxRestXAXX
278/*
279 * Restore 8 extra DX registers
280 */
281 MGETL D0.8,D0.9,D0.10,D0.11,D0.12,D0.13,D0.14,D0.15,[D0Re0]
282$LCtxRestXAXX:
283 TSTT D1Re0,#TBICTX_XAXX_BIT /* Get extended AX regs? */
284 BZ $LCtxRestXHL2
285/*
286 * Restore 3 extra AX registers
287 */
288 MGETL A0_4 A0.5,A0.6,A0.7,[D0Re0] /* Get 8*3 bytes */
289$LCtxRestXHL2:
290 TSTT D1Re0,#TBICTX_XHL2_BIT /* Get hardware-loop regs? */
291 BZ $LCtxRestXTDP
292/*
293 * Get hardware loop registers
294 */
295 MGETL D0Ar6,D0Ar4,D0Ar2,[D0Re0] /* Get 8*3 bytes */
296 MOV TXL1START,D0Ar6
297 MOV TXL2START,D1Ar5
298 MOV TXL1END,D0Ar4
299 MOV TXL2END,D1Ar3
300 MOV TXL1COUNT,D0Ar2
301 MOV TXL2COUNT,D1Ar1
302$LCtxRestXTDP:
303 TSTT D1Re0,#TBICTX_XTDP_BIT /* Get per-thread DSP regs? */
304 MOVZ PC,A1.2 /* No: Early return */
305/*
306 * Get per-thread DSP registers; ACC.0, PR.0, PI.1-3 (PI.0 is zero)
307 */
308 MOV A0.2,D0Re0
309 GETL D0Ar6,D1Ar5,[D0Re0++#((16*4)+(18*8))]
310#ifndef CTX_NO_DSP
311D GETL AC0.0,AC1.0,[A0.2++] /* Restore ACx.0 lower 32-bits */
312DH GETL AC0.0,AC1.0,[A0.2++] /* Restore ACx.0 upper 32-bits */
313#else
314 ADD A0.2,A0.2,#(2*8)
315#endif
316 ADD D0Re0,D0Re0,#(2*4)
317 MOV TXMODE,A0.3 /* Some TXMODE bits needed */
318 MOV TXMRSIZE,D0Ar6
319 MOV TXDRSIZE,D1Ar5
320#ifndef CTX_NO_DSP
321D GETL D0AR.0,D1AR.0,[A0.2++] /* Restore DSP RAM registers */
322D GETL D0AR.1,D1AR.1,[A0.2++]
323D GETL D0AW.0,D1AW.0,[A0.2++]
324D GETL D0AW.1,D1AW.1,[A0.2++]
325D GETL D0BR.0,D1BR.0,[A0.2++]
326D GETL D0BR.1,D1BR.1,[A0.2++]
327D GETL D0BW.0,D1BW.0,[A0.2++]
328D GETL D0BW.1,D1BW.1,[A0.2++]
329#else
330 ADD A0.2,A0.2,#(8*8)
331#endif
332 MOV TXMODE,#0 /* Restore TXMODE */
333#ifndef CTX_NO_DSP
334D GETL D0ARI.0,D1ARI.0,[A0.2++]
335D GETL D0ARI.1,D1ARI.1,[A0.2++]
336D GETL D0AWI.0,D1AWI.0,[A0.2++]
337D GETL D0AWI.1,D1AWI.1,[A0.2++]
338D GETL D0BRI.0,D1BRI.0,[A0.2++]
339D GETL D0BRI.1,D1BRI.1,[A0.2++]
340D GETL D0BWI.0,D1BWI.0,[A0.2++]
341D GETL D0BWI.1,D1BWI.1,[A0.2++]
342D GETD T0,[A0.2++]
343D GETD T1,[A0.2++]
344D GETD T2,[A0.2++]
345D GETD T3,[A0.2++]
346D GETD T4,[A0.2++]
347D GETD T5,[A0.2++]
348D GETD T6,[A0.2++]
349D GETD T7,[A0.2++]
350D GETD T8,[A0.2++]
351D GETD T9,[A0.2++]
352D GETD TA,[A0.2++]
353D GETD TB,[A0.2++]
354D GETD TC,[A0.2++]
355D GETD TD,[A0.2++]
356D GETD TE,[A0.2++]
357D GETD TF,[A0.2++]
358#else
359 ADD A0.2,A0.2,#(8*8+4*16)
360#endif
361 MOV PC,A1.2 /* Return */
362 .size ___TBICtxRestore,.-___TBICtxRestore
363
364/*
365 * End of tbictx.S
366 */