4 * Copyright (C) 2001, 2002, 2007, 2012 Imagination Technologies.
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.
10 * Explicit state save and restore routines forming part of the thread binary
11 * interface for META processors
15 #include <asm/metag_regs.h>
19 /* Ax.4 is NOT saved in XAX3 */
22 /* Ax.4 is saved in XAX4 */
27 /* Size of the TBICTX structure */
28 #define TBICTX_BYTES ((TBICTX_AX_REGS*8)+TBICTX_AX)
31 * TBIRES __TBINestInts( TBIRES State, void *pExt, int NoNestMask )
35 .global ___TBINestInts
36 .type ___TBINestInts,function
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
54 * Drop thru into sub-function-
56 .global ___TBINestInts2
57 .type ___TBINestInts2,function
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 */
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 */
71 MGETL D0FrT,D0.5,D0.6,[A0FrP] /* Full exit sequence */
72 SUB A0StP,A0FrP,#(8*3)
75 .size ___TBINestInts2,.-___TBINestInts2
78 * void *__TBICtxSave( TBIRES State, void *pExt )
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.
84 * Virtually all possible scratch registers are used.
86 * The D1Ar1 parameter is only used as the basis for saving
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.
98 .type ___TBICtxSave,function
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? */
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 */
115 TSTT D0Ar2,#TBICTX_XDX8_BIT /* Save extended DX regs? */
118 * Save 8 extra DX registers
120 MSETL [A0.2],D0.8,D0.9,D0.10,D0.11,D0.12,D0.13,D0.14,D0.15
122 TSTT D0Ar2,#TBICTX_XAXX_BIT /* Save extended AX regs? */
123 SWAP D0Re0,A0.2 /* pDst into D0Re0 */
126 * Save 4 extra AX registers
128 MSETL [D0Re0], A0_4 A0.5,A0.6,A0.7 /* Save 8*3 bytes */
130 TSTT D0Ar2,#TBICTX_XHL2_BIT /* Save hardware-loop regs? */
131 SWAP D0Re0,A0.2 /* pDst back into A0.2 */
136 * Save hardware loop registers
138 SETL [A0.2++],D0Ar6,D1Ar5 /* Save 8*1 bytes */
143 MSETL [A0.2],D0Ar6,D0FrT /* Save 8*2 bytes */
145 * Clear loop counters to disable any current loops
147 XOR TXL1COUNT,D0FrT,D0FrT
148 XOR TXL2COUNT,D1RtP,D1RtP
150 TSTT D0Ar2,#TBICTX_XTDP_BIT /* Save per-thread DSP regs? */
153 * Save per-thread DSP registers; ACC.0, PR.0, PI.1-3 (PI.0 is zero)
156 D SETL [A0.2++],AC0.0,AC1.0 /* Save ACx.0 lower 32-bits */
157 DH SETL [A0.2++],AC0.0,AC1.0 /* Save ACx.0 upper 32-bits */
158 D SETL [A0.2++],D0AR.0,D1AR.0 /* Save DSP RAM registers */
159 D SETL [A0.2++],D0AR.1,D1AR.1
160 D SETL [A0.2++],D0AW.0,D1AW.0
161 D SETL [A0.2++],D0AW.1,D1AW.1
162 D SETL [A0.2++],D0BR.0,D1BR.0
163 D SETL [A0.2++],D0BR.1,D1BR.1
164 D SETL [A0.2++],D0BW.0,D1BW.0
165 D SETL [A0.2++],D0BW.1,D1BW.1
166 D SETL [A0.2++],D0ARI.0,D1ARI.0
167 D SETL [A0.2++],D0ARI.1,D1ARI.1
168 D SETL [A0.2++],D0AWI.0,D1AWI.0
169 D SETL [A0.2++],D0AWI.1,D1AWI.1
170 D SETL [A0.2++],D0BRI.0,D1BRI.0
171 D SETL [A0.2++],D0BRI.1,D1BRI.1
172 D SETL [A0.2++],D0BWI.0,D1BWI.0
173 D SETL [A0.2++],D0BWI.1,D1BWI.1
191 ADD A0.2,A0.2,#(8*18+4*16)
195 SETL [A0.2++],D0Ar6,D1Ar5 /* Save 8*1 bytes */
199 MOV D0Ar4,D0Re0 /* Copy Ctx Flags */
200 ANDT D0Ar4,D0Ar4,#TBICTX_XCBF_BIT /* mask XCBF if already set */
202 AND D0Ar2,D0Ar2,D0Ar4 /* remove XCBF if already set */
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 */
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
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 */
233 MOV PC,A1.2 /* Return */
234 .size ___TBICtxSave,.-___TBICtxSave
237 * void *__TBICtxRestore( TBIRES State, void *pExt )
239 * D0Ar2 contains TBICTX_*_BIT values that control what
240 * extended data is to be recovered from D1Ar3 (pExt).
242 * Virtually all possible scratch registers are used.
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.
251 .global ___TBICtxRestore
252 .type ___TBICtxRestore,function
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 */
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 */
268 SETD [D1Ar1+#TBICTX_Ext_AX2_U0],D0Ar6
270 SETD [D0Ar6+#TBICTX_Ext_AX2_U1],D1Ar5
272 SETL [D1Ar1+#TBICTX_Ext_AX2],D0Ar6,D1Ar5
275 TSTT D1Re0,#TBICTX_XDX8_BIT /* Get extended DX regs? */
276 MOV A1.2,D1RtP /* Free off D1RtP register */
279 * Restore 8 extra DX registers
281 MGETL D0.8,D0.9,D0.10,D0.11,D0.12,D0.13,D0.14,D0.15,[D0Re0]
283 TSTT D1Re0,#TBICTX_XAXX_BIT /* Get extended AX regs? */
286 * Restore 3 extra AX registers
288 MGETL A0_4 A0.5,A0.6,A0.7,[D0Re0] /* Get 8*3 bytes */
290 TSTT D1Re0,#TBICTX_XHL2_BIT /* Get hardware-loop regs? */
293 * Get hardware loop registers
295 MGETL D0Ar6,D0Ar4,D0Ar2,[D0Re0] /* Get 8*3 bytes */
303 TSTT D1Re0,#TBICTX_XTDP_BIT /* Get per-thread DSP regs? */
304 MOVZ PC,A1.2 /* No: Early return */
306 * Get per-thread DSP registers; ACC.0, PR.0, PI.1-3 (PI.0 is zero)
309 GETL D0Ar6,D1Ar5,[D0Re0++#((16*4)+(18*8))]
311 D GETL AC0.0,AC1.0,[A0.2++] /* Restore ACx.0 lower 32-bits */
312 DH GETL AC0.0,AC1.0,[A0.2++] /* Restore ACx.0 upper 32-bits */
316 ADD D0Re0,D0Re0,#(2*4)
317 MOV TXMODE,A0.3 /* Some TXMODE bits needed */
321 D GETL D0AR.0,D1AR.0,[A0.2++] /* Restore DSP RAM registers */
322 D GETL D0AR.1,D1AR.1,[A0.2++]
323 D GETL D0AW.0,D1AW.0,[A0.2++]
324 D GETL D0AW.1,D1AW.1,[A0.2++]
325 D GETL D0BR.0,D1BR.0,[A0.2++]
326 D GETL D0BR.1,D1BR.1,[A0.2++]
327 D GETL D0BW.0,D1BW.0,[A0.2++]
328 D GETL D0BW.1,D1BW.1,[A0.2++]
332 MOV TXMODE,#0 /* Restore TXMODE */
334 D GETL D0ARI.0,D1ARI.0,[A0.2++]
335 D GETL D0ARI.1,D1ARI.1,[A0.2++]
336 D GETL D0AWI.0,D1AWI.0,[A0.2++]
337 D GETL D0AWI.1,D1AWI.1,[A0.2++]
338 D GETL D0BRI.0,D1BRI.0,[A0.2++]
339 D GETL D0BRI.1,D1BRI.1,[A0.2++]
340 D GETL D0BWI.0,D1BWI.0,[A0.2++]
341 D GETL D0BWI.1,D1BWI.1,[A0.2++]
359 ADD A0.2,A0.2,#(8*8+4*16)
361 MOV PC,A1.2 /* Return */
362 .size ___TBICtxRestore,.-___TBICtxRestore