aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2012-09-21 12:40:06 -0400
committerJames Hogan <james.hogan@imgtec.com>2013-03-02 15:09:18 -0500
commit027f891f7640144d4b7b15113f3ae9af2c8b095d (patch)
treecee318450f4782ca3a471f83ef3fd3557e8c3a9d /arch
parent4ca151b20803eb2e31bb6d840d01eec461158e14 (diff)
metag: TBX source
Add source files from the Thread Binary Interface (TBI) library which provides useful low level operations and traps/context management. Among other things it handles interrupt/exception/syscall entry (in tbipcx.S). Signed-off-by: James Hogan <james.hogan@imgtec.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/metag/tbx/tbicore.S136
-rw-r--r--arch/metag/tbx/tbictx.S366
-rw-r--r--arch/metag/tbx/tbictxfpu.S190
-rw-r--r--arch/metag/tbx/tbidefr.S175
-rw-r--r--arch/metag/tbx/tbidspram.S161
-rw-r--r--arch/metag/tbx/tbilogf.S48
-rw-r--r--arch/metag/tbx/tbipcx.S451
-rw-r--r--arch/metag/tbx/tbiroot.S87
-rw-r--r--arch/metag/tbx/tbisoft.S237
-rw-r--r--arch/metag/tbx/tbistring.c114
-rw-r--r--arch/metag/tbx/tbitimer.S207
11 files changed, 2172 insertions, 0 deletions
diff --git a/arch/metag/tbx/tbicore.S b/arch/metag/tbx/tbicore.S
new file mode 100644
index 000000000000..a0838ebcb433
--- /dev/null
+++ b/arch/metag/tbx/tbicore.S
@@ -0,0 +1,136 @@
1/*
2 * tbicore.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 * Core functions needed to support use of the thread binary interface for META
11 * processors
12 */
13
14 .file "tbicore.S"
15/* Get data structures and defines from the TBI C header */
16#include <asm/metag_mem.h>
17#include <asm/metag_regs.h>
18#include <asm/tbx.h>
19
20 .data
21 .balign 8
22 .global ___pTBISegs
23 .type ___pTBISegs,object
24___pTBISegs:
25 .quad 0 /* Segment list pointer with it's */
26 .size ___pTBISegs,.-___pTBISegs
27 /* own id or spin-lock location */
28/*
29 * Return ___pTBISegs value specific to privilege level - not very complicated
30 * at the moment
31 *
32 * Register Usage: D0Re0 is the result, D1Re0 is used as a scratch
33 */
34 .text
35 .balign 4
36 .global ___TBISegList
37 .type ___TBISegList,function
38___TBISegList:
39 MOVT A1LbP,#HI(___pTBISegs)
40 ADD A1LbP,A1LbP,#LO(___pTBISegs)
41 GETL D0Re0,D1Re0,[A1LbP]
42 MOV PC,D1RtP
43 .size ___TBISegList,.-___TBISegList
44
45/*
46 * Search the segment list for a match given Id, pStart can be NULL
47 *
48 * Register Usage: D1Ar1 is pSeg, D0Ar2 is Id, D0Re0 is the result
49 * D0Ar4, D1Ar3 are used as a scratch
50 * NB: The PSTAT bit if Id in D0Ar2 may be toggled
51 */
52 .text
53 .balign 4
54 .global ___TBIFindSeg
55 .type ___TBIFindSeg,function
56___TBIFindSeg:
57 MOVT A1LbP,#HI(___pTBISegs)
58 ADD A1LbP,A1LbP,#LO(___pTBISegs)
59 GETL D1Ar3,D0Ar4,[A1LbP] /* Read segment list head */
60 MOV D0Re0,TXSTATUS /* What priv level are we at? */
61 CMP D1Ar1,#0 /* Is pStart provided? */
62/* Disable privilege adaption for now */
63 ANDT D0Re0,D0Re0,#0 /*HI(TXSTATUS_PSTAT_BIT) ; Is PSTAT set? Zero if not */
64 LSL D0Re0,D0Re0,#(TBID_PSTAT_S-TXSTATUS_PSTAT_S)
65 XOR D0Ar2,D0Ar2,D0Re0 /* Toggle Id PSTAT if privileged */
66 MOVNZ D1Ar3,D1Ar1 /* Use pStart if provided */
67$LFindSegLoop:
68 ADDS D0Re0,D1Ar3,#0 /* End of list? Load result into D0Re0 */
69 MOVZ PC,D1RtP /* If result is NULL we leave */
70 GETL D1Ar3,D0Ar4,[D1Ar3] /* Read pLink and Id */
71 CMP D0Ar4,D0Ar2 /* Does it match? */
72 BNZ $LFindSegLoop /* Loop if there is no match */
73 TST D0Re0,D0Re0 /* Clear zero flag - we found it! */
74 MOV PC,D1RtP /* Return */
75 .size ___TBIFindSeg,.-___TBIFindSeg
76
77/* Useful offsets to encode the lower bits of the lock/unlock addresses */
78#define UON (LINSYSEVENT_WR_ATOMIC_LOCK & 0xFFF8)
79#define UOFF (LINSYSEVENT_WR_ATOMIC_UNLOCK & 0xFFF8)
80
81/*
82 * Perform a whole spin-lock sequence as used by the TBISignal routine
83 *
84 * Register Usage: D1Ar1 is pLock, D0Ar2 is Mask, D0Re0 is the result
85 * (All other usage due to ___TBIPoll - D0Ar6, D1Re0)
86 */
87 .text
88 .balign 4
89 .global ___TBISpin
90 .type ___TBISpin,function
91___TBISpin:
92 SETL [A0StP++],D0FrT,D1RtP /* Save our return address */
93 ORS D0Re0,D0Re0,#1 /* Clear zero flag */
94 MOV D1RtP,PC /* Setup return address to form loop */
95$LSpinLoop:
96 BNZ ___TBIPoll /* Keep repeating if fail to set */
97 GETL D0FrT,D1RtP,[--A0StP] /* Restore return address */
98 MOV PC,D1RtP /* Return */
99 .size ___TBISpin,.-___TBISpin
100
101/*
102 * Perform an attempt to gain access to a spin-lock and set some bits
103 *
104 * Register Usage: D1Ar1 is pLock, D0Ar2 is Mask, D0Re0 is the result
105 * !!On return Zero flag is SET if we are sucessfull!!
106 * A0.3 is used to hold base address of system event region
107 * D1Re0 use to hold TXMASKI while interrupts are off
108 */
109 .text
110 .balign 4
111 .global ___TBIPoll
112 .type ___TBIPoll,function
113___TBIPoll:
114 MOV D1Re0,#0 /* Prepare to disable ints */
115 MOVT A0.3,#HI(LINSYSEVENT_WR_ATOMIC_LOCK)
116 SWAP D1Re0,TXMASKI /* Really stop ints */
117 LOCK2 /* Gain all locks */
118 SET [A0.3+#UON],D1RtP /* Stop shared memory access too */
119 DCACHE [D1Ar1],A0.3 /* Flush Cache line */
120 GETD D0Re0,[D1Ar1] /* Get new state from memory or hit */
121 DCACHE [D1Ar1],A0.3 /* Flush Cache line */
122 GETD D0Re0,[D1Ar1] /* Get current state */
123 TST D0Re0,D0Ar2 /* Are we clear to send? */
124 ORZ D0Re0,D0Re0,D0Ar2 /* Yes: So set bits and */
125 SETDZ [D1Ar1],D0Re0 /* transmit new state */
126 SET [A0.3+#UOFF],D1RtP /* Allow shared memory access */
127 LOCK0 /* Release all locks */
128 MOV TXMASKI,D1Re0 /* Allow ints */
129$LPollEnd:
130 XORNZ D0Re0,D0Re0,D0Re0 /* No: Generate zero result */
131 MOV PC,D1RtP /* Return (NZ indicates failure) */
132 .size ___TBIPoll,.-___TBIPoll
133
134/*
135 * End of tbicore.S
136 */
diff --git a/arch/metag/tbx/tbictx.S b/arch/metag/tbx/tbictx.S
new file mode 100644
index 000000000000..19af983a13ae
--- /dev/null
+++ b/arch/metag/tbx/tbictx.S
@@ -0,0 +1,366 @@
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 */
diff --git a/arch/metag/tbx/tbictxfpu.S b/arch/metag/tbx/tbictxfpu.S
new file mode 100644
index 000000000000..e773bea3e7bd
--- /dev/null
+++ b/arch/metag/tbx/tbictxfpu.S
@@ -0,0 +1,190 @@
1/*
2 * tbictxfpu.S
3 *
4 * Copyright (C) 2009, 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 "tbifpuctx.S"
15
16#include <asm/metag_regs.h>
17#include <asm/tbx.h>
18
19#ifdef TBI_1_4
20/*
21 * void *__TBICtxFPUSave( TBIRES State, void *pExt )
22 *
23 * D0Ar2 contains TBICTX_*_BIT values that control what
24 * extended data is to be saved.
25 * These bits must be ored into the SaveMask of this structure.
26 *
27 * Virtually all possible scratch registers are used.
28 */
29 .text
30 .balign 4
31 .global ___TBICtxFPUSave
32 .type ___TBICtxFPUSave,function
33___TBICtxFPUSave:
34
35 /* D1Ar1:D0Ar2 - State
36 * D1Ar3 - pExt
37 * D0Ar4 - Value of METAC_CORE_ID
38 * D1Ar5 - Scratch
39 * D0Ar6 - Scratch
40 */
41
42 /* If the FPAC bit isnt set then there is nothing to do */
43 TSTT D0Ar2,#TBICTX_FPAC_BIT
44 MOVZ PC, D1RtP
45
46 /* Obtain the Core config */
47 MOVT D0Ar4, #HI(METAC_CORE_ID)
48 ADD D0Ar4, D0Ar4, #LO(METAC_CORE_ID)
49 GETD D0Ar4, [D0Ar4]
50
51 /* Detect FX.8 - FX.15 and add to core config */
52 MOV D0Ar6, TXENABLE
53 AND D0Ar6, D0Ar6, #(TXENABLE_CLASSALT_FPUR8 << TXENABLE_CLASS_S)
54 AND D0Ar4, D0Ar4, #LO(0x0000FFFF)
55 ORT D0Ar4, D0Ar4, #HI(TBICTX_CFGFPU_FX16_BIT)
56 XOR D0Ar4, D0Ar4, D0Ar6
57
58 /* Save the relevant bits to the buffer */
59 SETD [D1Ar3++], D0Ar4
60
61 /* Save the relevant bits of TXDEFR (Assumes TXDEFR is coherent) ... */
62 MOV D0Ar6, TXDEFR
63 LSR D0Re0, D0Ar6, #8
64 AND D0Re0, D0Re0, #LO(TXDEFR_FPE_FE_BITS>>8)
65 AND D0Ar6, D0Ar6, #LO(TXDEFR_FPE_ICTRL_BITS)
66 OR D0Re0, D0Re0, D0Ar6
67
68 /* ... along with relevant bits of TXMODE to buffer */
69 MOV D0Ar6, TXMODE
70 ANDT D0Ar6, D0Ar6, #HI(TXMODE_FPURMODE_BITS)
71 ORT D0Ar6, D0Ar6, #HI(TXMODE_FPURMODEWRITE_BIT)
72 OR D0Ar6, D0Ar6, D0Re0
73 SETD [D1Ar3++], D0Ar6
74
75 GETD D0Ar6,[D1Ar1+#TBICTX_SaveMask-2] /* Get the current SaveMask */
76 /* D0Ar6 - pCtx->SaveMask */
77
78 TSTT D0Ar4, #HI(TBICTX_CFGFPU_FX16_BIT) /* Perform test here for extended FPU registers
79 * to avoid stalls
80 */
81 /* Save the standard FPU registers */
82F MSETL [D1Ar3++], FX.0, FX.2, FX.4, FX.6
83
84 /* Save the extended FPU registers if they are present */
85 BZ $Lskip_save_fx8_fx16
86F MSETL [D1Ar3++], FX.8, FX.10, FX.12, FX.14
87$Lskip_save_fx8_fx16:
88
89 /* Save the FPU Accumulator if it is present */
90 TST D0Ar4, #METAC_COREID_NOFPACC_BIT
91 BNZ $Lskip_save_fpacc
92F SETL [D1Ar3++], ACF.0
93F SETL [D1Ar3++], ACF.1
94F SETL [D1Ar3++], ACF.2
95$Lskip_save_fpacc:
96
97 /* Update pCtx->SaveMask */
98 ANDT D0Ar2, D0Ar2, #TBICTX_FPAC_BIT
99 OR D0Ar6, D0Ar6, D0Ar2
100 SETD [D1Ar1+#TBICTX_SaveMask-2],D0Ar6/* Add in XCBF bit to TBICTX */
101
102 MOV D0Re0, D1Ar3 /* Return end of save area */
103 MOV PC, D1RtP
104
105 .size ___TBICtxFPUSave,.-___TBICtxFPUSave
106
107/*
108 * void *__TBICtxFPURestore( TBIRES State, void *pExt )
109 *
110 * D0Ar2 contains TBICTX_*_BIT values that control what
111 * extended data is to be recovered from D1Ar3 (pExt).
112 *
113 * Virtually all possible scratch registers are used.
114 */
115/*
116 * If TBICTX_XEXT_BIT is specified in State. Then the saved state of
117 * the orginal A0.2 and A1.2 is restored from pExt and the XEXT
118 * related flags are removed from State.pCtx->SaveMask.
119 *
120 */
121 .balign 4
122 .global ___TBICtxFPURestore
123 .type ___TBICtxFPURestore,function
124___TBICtxFPURestore:
125
126 /* D1Ar1:D0Ar2 - State
127 * D1Ar3 - pExt
128 * D0Ar4 - Value of METAC_CORE_ID
129 * D1Ar5 - Scratch
130 * D0Ar6 - Scratch
131 * D1Re0 - Scratch
132 */
133
134 /* If the FPAC bit isnt set then there is nothing to do */
135 TSTT D0Ar2,#TBICTX_FPAC_BIT
136 MOVZ PC, D1RtP
137
138 /* Obtain the relevant bits of the Core config */
139 GETD D0Ar4, [D1Ar3++]
140
141 /* Restore FPU related parts of TXDEFR. Assumes TXDEFR is coherent */
142 GETD D1Ar5, [D1Ar3++]
143 MOV D0Ar6, D1Ar5
144 LSL D1Re0, D1Ar5, #8
145 ANDT D1Re0, D1Re0, #HI(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS)
146 AND D1Ar5, D1Ar5, #LO(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS)
147 OR D1Re0, D1Re0, D1Ar5
148
149 MOV D1Ar5, TXDEFR
150 ANDMT D1Ar5, D1Ar5, #HI(~(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS))
151 ANDMB D1Ar5, D1Ar5, #LO(~(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS))
152 OR D1Re0, D1Re0, D1Ar5
153 MOV TXDEFR, D1Re0
154
155 /* Restore relevant bits of TXMODE */
156 MOV D1Ar5, TXMODE
157 ANDMT D1Ar5, D1Ar5, #HI(~TXMODE_FPURMODE_BITS)
158 ANDT D0Ar6, D0Ar6, #HI(TXMODE_FPURMODE_BITS|TXMODE_FPURMODEWRITE_BIT)
159 OR D0Ar6, D0Ar6, D1Ar5
160 MOV TXMODE, D0Ar6
161
162 TSTT D0Ar4, #HI(TBICTX_CFGFPU_FX16_BIT) /* Perform test here for extended FPU registers
163 * to avoid stalls
164 */
165 /* Save the standard FPU registers */
166F MGETL FX.0, FX.2, FX.4, FX.6, [D1Ar3++]
167
168 /* Save the extended FPU registers if they are present */
169 BZ $Lskip_restore_fx8_fx16
170F MGETL FX.8, FX.10, FX.12, FX.14, [D1Ar3++]
171$Lskip_restore_fx8_fx16:
172
173 /* Save the FPU Accumulator if it is present */
174 TST D0Ar4, #METAC_COREID_NOFPACC_BIT
175 BNZ $Lskip_restore_fpacc
176F GETL ACF.0, [D1Ar3++]
177F GETL ACF.1, [D1Ar3++]
178F GETL ACF.2, [D1Ar3++]
179$Lskip_restore_fpacc:
180
181 MOV D0Re0, D1Ar3 /* Return end of save area */
182 MOV PC, D1RtP
183
184 .size ___TBICtxFPURestore,.-___TBICtxFPURestore
185
186#endif /* TBI_1_4 */
187
188/*
189 * End of tbictx.S
190 */
diff --git a/arch/metag/tbx/tbidefr.S b/arch/metag/tbx/tbidefr.S
new file mode 100644
index 000000000000..3eb165ebf540
--- /dev/null
+++ b/arch/metag/tbx/tbidefr.S
@@ -0,0 +1,175 @@
1/*
2 * tbidefr.S
3 *
4 * Copyright (C) 2009, 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 * Routing deferred exceptions
11 */
12
13#include <asm/metag_regs.h>
14#include <asm/tbx.h>
15
16 .text
17 .balign 4
18 .global ___TBIHandleDFR
19 .type ___TBIHandleDFR,function
20/* D1Ar1:D0Ar2 -- State
21 * D0Ar3 -- SigNum
22 * D0Ar4 -- Triggers
23 * D1Ar5 -- InstOrSWSId
24 * D0Ar6 -- pTBI (volatile)
25 */
26___TBIHandleDFR:
27#ifdef META_BUG_MBN100212
28 MSETL [A0StP++], D0FrT, D0.5
29
30 /* D1Ar1,D0Ar2,D1Ar5,D0Ar6 -- Arguments to handler, must be preserved
31 * D0Ar4 -- The deferred exceptions
32 * D1Ar3 -- As per D0Ar4 but just the trigger bits
33 * D0.5 -- The bgnd deferred exceptions
34 * D1.5 -- TXDEFR with bgnd re-added
35 */
36
37 /* - Collect the pending deferred exceptions using TXSTAT,
38 * (ack's the bgnd exceptions as a side-effect)
39 * - Manually collect remaining (interrupt) deferred exceptions
40 * using TXDEFR
41 * - Replace the triggers (from TXSTATI) with the int deferred
42 * exceptions DEFR ..., TXSTATI would have returned if it was valid
43 * from bgnd code
44 * - Reconstruct TXDEFR by or'ing bgnd deferred exceptions (except
45 * the DEFER bit) and the int deferred exceptions. This will be
46 * restored later
47 */
48 DEFR D0.5, TXSTAT
49 MOV D1.5, TXDEFR
50 ANDT D0.5, D0.5, #HI(0xFFFF0000)
51 MOV D1Ar3, D1.5
52 ANDT D1Ar3, D1Ar3, #HI(0xFFFF0000)
53 OR D0Ar4, D1Ar3, #TXSTAT_DEFER_BIT
54 OR D1.5, D1.5, D0.5
55
56 /* Mask off anything unrelated to the deferred exception triggers */
57 ANDT D1Ar3, D1Ar3, #HI(TXSTAT_BUSERR_BIT | TXSTAT_FPE_BITS)
58
59 /* Can assume that at least one exception happened since this
60 * handler wouldnt have been called otherwise.
61 *
62 * Replace the signal number and at the same time, prepare
63 * the mask to acknowledge the exception
64 *
65 * D1Re0 -- The bits to acknowledge
66 * D1Ar3 -- The signal number
67 * D1RtP -- Scratch to deal with non-conditional insns
68 */
69 MOVT D1Re0, #HI(TXSTAT_FPE_BITS & ~TXSTAT_FPE_DENORMAL_BIT)
70 MOV D1RtP, #TXSTAT_FPE_INVALID_S
71 FFB D1Ar3, D1Ar3
72 CMP D1Ar3, #TXSTAT_FPE_INVALID_S
73 MOVLE D1Ar3, D1RtP /* Collapse FPE triggers to a single signal */
74 MOV D1RtP, #1
75 LSLGT D1Re0, D1RtP, D1Ar3
76
77 /* Get the handler using the signal number
78 *
79 * D1Ar3 -- The signal number
80 * D0Re0 -- Offset into TBI struct containing handler address
81 * D1Re0 -- Mask of triggers to keep
82 * D1RtP -- Address of handler
83 */
84 SUB D1Ar3, D1Ar3, #(TXSTAT_FPE_INVALID_S - TBID_SIGNUM_FPE)
85 LSL D0Re0, D1Ar3, #2
86 XOR D1Re0, D1Re0, #-1 /* Prepare mask for acknowledge (avoids stall) */
87 ADD D0Re0,D0Re0,#TBI_fnSigs
88 GETD D1RtP, [D0Ar6+D0Re0]
89
90 /* Acknowledge triggers */
91 AND D1.5, D1.5, D1Re0
92
93 /* Restore remaining exceptions
94 * Do this here in case the handler enables nested interrupts
95 *
96 * D1.5 -- TXDEFR with this exception ack'd
97 */
98 MOV TXDEFR, D1.5
99
100 /* Call the handler */
101 SWAP D1RtP, PC
102
103 GETL D0.5, D1.5, [--A0StP]
104 GETL D0FrT, D1RtP, [--A0StP]
105 MOV PC,D1RtP
106#else /* META_BUG_MBN100212 */
107
108 /* D1Ar1,D0Ar2,D1Ar5,D0Ar6 -- Arguments to handler, must be preserved
109 * D0Ar4 -- The deferred exceptions
110 * D1Ar3 -- As per D0Ar4 but just the trigger bits
111 */
112
113 /* - Collect the pending deferred exceptions using TXSTAT,
114 * (ack's the interrupt exceptions as a side-effect)
115 */
116 DEFR D0Ar4, TXSTATI
117
118 /* Mask off anything unrelated to the deferred exception triggers */
119 MOV D1Ar3, D0Ar4
120 ANDT D1Ar3, D1Ar3, #HI(TXSTAT_BUSERR_BIT | TXSTAT_FPE_BITS)
121
122 /* Can assume that at least one exception happened since this
123 * handler wouldnt have been called otherwise.
124 *
125 * Replace the signal number and at the same time, prepare
126 * the mask to acknowledge the exception
127 *
128 * The unusual code for 1<<D1Ar3 may need explanation.
129 * Normally this would be done using 'MOV rs,#1' and 'LSL rd,rs,D1Ar3'
130 * but only D1Re0 is available in D1 and no crossunit insns are available
131 * Even worse, there is no conditional 'MOV r,#uimm8'.
132 * Since the CMP proves that D1Ar3 >= 20, we can reuse the bottom 12-bits
133 * of D1Re0 (using 'ORGT r,#1') in the knowledge that the top 20-bits will
134 * be discarded without affecting the result.
135 *
136 * D1Re0 -- The bits to acknowledge
137 * D1Ar3 -- The signal number
138 */
139 MOVT D1Re0, #HI(TXSTAT_FPE_BITS & ~TXSTAT_FPE_DENORMAL_BIT)
140 MOV D0Re0, #TXSTAT_FPE_INVALID_S
141 FFB D1Ar3, D1Ar3
142 CMP D1Ar3, #TXSTAT_FPE_INVALID_S
143 MOVLE D1Ar3, D0Re0 /* Collapse FPE triggers to a single signal */
144 ORGT D1Re0, D1Re0, #1
145 LSLGT D1Re0, D1Re0, D1Ar3
146
147 SUB D1Ar3, D1Ar3, #(TXSTAT_FPE_INVALID_S - TBID_SIGNUM_FPE)
148
149 /* Acknowledge triggers and restore remaining exceptions
150 * Do this here in case the handler enables nested interrupts
151 *
152 * (x | y) ^ y == x & ~y. It avoids the restrictive XOR ...,#-1 insn
153 * and is the same length
154 */
155 MOV D0Re0, TXDEFR
156 OR D0Re0, D0Re0, D1Re0
157 XOR TXDEFR, D0Re0, D1Re0
158
159 /* Get the handler using the signal number
160 *
161 * D1Ar3 -- The signal number
162 * D0Re0 -- Address of handler
163 */
164 LSL D0Re0, D1Ar3, #2
165 ADD D0Re0,D0Re0,#TBI_fnSigs
166 GETD D0Re0, [D0Ar6+D0Re0]
167
168 /* Tailcall the handler */
169 MOV PC,D0Re0
170
171#endif /* META_BUG_MBN100212 */
172 .size ___TBIHandleDFR,.-___TBIHandleDFR
173/*
174 * End of tbidefr.S
175 */
diff --git a/arch/metag/tbx/tbidspram.S b/arch/metag/tbx/tbidspram.S
new file mode 100644
index 000000000000..2f27c0372212
--- /dev/null
+++ b/arch/metag/tbx/tbidspram.S
@@ -0,0 +1,161 @@
1/*
2 * tbidspram.S
3 *
4 * Copyright (C) 2009, 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 "tbidspram.S"
15
16/* These aren't generally useful to a user so for now, they arent publically available */
17#define _TBIECH_DSPRAM_DUA_S 8
18#define _TBIECH_DSPRAM_DUA_BITS 0x7f00
19#define _TBIECH_DSPRAM_DUB_S 0
20#define _TBIECH_DSPRAM_DUB_BITS 0x007f
21
22/*
23 * void *__TBIDspramSaveA( short DspramSizes, void *pExt )
24 */
25 .text
26 .balign 4
27 .global ___TBIDspramSaveA
28 .type ___TBIDspramSaveA,function
29___TBIDspramSaveA:
30
31 SETL [A0StP++], D0.5, D1.5
32 MOV A0.3, D0Ar2
33
34 /* D1Ar1 - Dspram Sizes
35 * A0.4 - Pointer to buffer
36 */
37
38 /* Save the specified amount of dspram DUA */
39DL MOV D0AR.0, #0
40 LSR D1Ar1, D1Ar1, #_TBIECH_DSPRAM_DUA_S
41 AND D1Ar1, D1Ar1, #(_TBIECH_DSPRAM_DUA_BITS >> _TBIECH_DSPRAM_DUA_S)
42 SUB TXRPT, D1Ar1, #1
43$L1:
44DL MOV D0Re0, [D0AR.0++]
45DL MOV D0Ar6, [D0AR.0++]
46DL MOV D0Ar4, [D0AR.0++]
47DL MOV D0.5, [D0AR.0++]
48 MSETL [A0.3++], D0Re0, D0Ar6, D0Ar4, D0.5
49
50 BR $L1
51
52 GETL D0.5, D1.5, [--A0StP]
53 MOV PC, D1RtP
54
55 .size ___TBIDspramSaveA,.-___TBIDspramSaveA
56
57/*
58 * void *__TBIDspramSaveB( short DspramSizes, void *pExt )
59 */
60 .balign 4
61 .global ___TBIDspramSaveB
62 .type ___TBIDspramSaveB,function
63___TBIDspramSaveB:
64
65 SETL [A0StP++], D0.5, D1.5
66 MOV A0.3, D0Ar2
67
68 /* D1Ar1 - Dspram Sizes
69 * A0.3 - Pointer to buffer
70 */
71
72 /* Save the specified amount of dspram DUA */
73DL MOV D0BR.0, #0
74 LSR D1Ar1, D1Ar1, #_TBIECH_DSPRAM_DUB_S
75 AND D1Ar1, D1Ar1, #(_TBIECH_DSPRAM_DUB_BITS >> _TBIECH_DSPRAM_DUB_S)
76 SUB TXRPT, D1Ar1, #1
77$L2:
78DL MOV D0Re0, [D0BR.0++]
79DL MOV D0Ar6, [D0BR.0++]
80DL MOV D0Ar4, [D0BR.0++]
81DL MOV D0.5, [D0BR.0++]
82 MSETL [A0.3++], D0Re0, D0Ar6, D0Ar4, D0.5
83
84 BR $L2
85
86 GETL D0.5, D1.5, [--A0StP]
87 MOV PC, D1RtP
88
89 .size ___TBIDspramSaveB,.-___TBIDspramSaveB
90
91/*
92 * void *__TBIDspramRestoreA( short DspramSizes, void *pExt )
93 */
94 .balign 4
95 .global ___TBIDspramRestoreA
96 .type ___TBIDspramRestoreA,function
97___TBIDspramRestoreA:
98
99 SETL [A0StP++], D0.5, D1.5
100 MOV A0.3, D0Ar2
101
102 /* D1Ar1 - Dspram Sizes
103 * A0.3 - Pointer to buffer
104 */
105
106 /* Restore the specified amount of dspram DUA */
107DL MOV D0AW.0, #0
108 LSR D1Ar1, D1Ar1, #_TBIECH_DSPRAM_DUA_S
109 AND D1Ar1, D1Ar1, #(_TBIECH_DSPRAM_DUA_BITS >> _TBIECH_DSPRAM_DUA_S)
110 SUB TXRPT, D1Ar1, #1
111$L3:
112 MGETL D0Re0, D0Ar6, D0Ar4, D0.5, [A0.3++]
113DL MOV [D0AW.0++], D0Re0
114DL MOV [D0AW.0++], D0Ar6
115DL MOV [D0AW.0++], D0Ar4
116DL MOV [D0AW.0++], D0.5
117
118 BR $L3
119
120 GETL D0.5, D1.5, [--A0StP]
121 MOV PC, D1RtP
122
123 .size ___TBIDspramRestoreA,.-___TBIDspramRestoreA
124
125/*
126 * void *__TBIDspramRestoreB( short DspramSizes, void *pExt )
127 */
128 .balign 4
129 .global ___TBIDspramRestoreB
130 .type ___TBIDspramRestoreB,function
131___TBIDspramRestoreB:
132
133 SETL [A0StP++], D0.5, D1.5
134 MOV A0.3, D0Ar2
135
136 /* D1Ar1 - Dspram Sizes
137 * A0.3 - Pointer to buffer
138 */
139
140 /* Restore the specified amount of dspram DUA */
141DL MOV D0BW.0, #0
142 LSR D1Ar1, D1Ar1, #_TBIECH_DSPRAM_DUB_S
143 AND D1Ar1, D1Ar1, #(_TBIECH_DSPRAM_DUB_BITS >> _TBIECH_DSPRAM_DUB_S)
144 SUB TXRPT, D1Ar1, #1
145$L4:
146 MGETL D0Re0, D0Ar6, D0Ar4, D0.5, [A0.3++]
147DL MOV [D0BW.0++], D0Re0
148DL MOV [D0BW.0++], D0Ar6
149DL MOV [D0BW.0++], D0Ar4
150DL MOV [D0BW.0++], D0.5
151
152 BR $L4
153
154 GETL D0.5, D1.5, [--A0StP]
155 MOV PC, D1RtP
156
157 .size ___TBIDspramRestoreB,.-___TBIDspramRestoreB
158
159/*
160 * End of tbidspram.S
161 */
diff --git a/arch/metag/tbx/tbilogf.S b/arch/metag/tbx/tbilogf.S
new file mode 100644
index 000000000000..4a34d80657db
--- /dev/null
+++ b/arch/metag/tbx/tbilogf.S
@@ -0,0 +1,48 @@
1/*
2 * tbilogf.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 * Defines __TBILogF trap code for debugging messages and __TBICont for debug
11 * assert to be implemented on.
12 */
13
14 .file "tbilogf.S"
15
16/*
17 * Perform console printf using external debugger or host support
18 */
19 .text
20 .balign 4
21 .global ___TBILogF
22 .type ___TBILogF,function
23___TBILogF:
24 MSETL [A0StP],D0Ar6,D0Ar4,D0Ar2
25 SWITCH #0xC10020
26 MOV D0Re0,#0
27 SUB A0StP,A0StP,#24
28 MOV PC,D1RtP
29 .size ___TBILogF,.-___TBILogF
30
31/*
32 * Perform wait for continue under control of the debugger
33 */
34 .text
35 .balign 4
36 .global ___TBICont
37 .type ___TBICont,function
38___TBICont:
39 MOV D0Ar6,#1
40 MSETL [A0StP],D0Ar6,D0Ar4,D0Ar2
41 SWITCH #0xC30006 /* Returns if we are to continue */
42 SUB A0StP,A0StP,#(8*3)
43 MOV PC,D1RtP /* Return */
44 .size ___TBICont,.-___TBICont
45
46/*
47 * End of tbilogf.S
48 */
diff --git a/arch/metag/tbx/tbipcx.S b/arch/metag/tbx/tbipcx.S
new file mode 100644
index 000000000000..de0626fdad25
--- /dev/null
+++ b/arch/metag/tbx/tbipcx.S
@@ -0,0 +1,451 @@
1/*
2 * tbipcx.S
3 *
4 * Copyright (C) 2001, 2002, 2007, 2009, 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 * Asyncronous trigger handling including exceptions
11 */
12
13 .file "tbipcx.S"
14#include <asm/metag_regs.h>
15#include <asm/tbx.h>
16
17/* BEGIN HACK */
18/* define these for now while doing inital conversion to GAS
19 will fix properly later */
20
21/* Signal identifiers always have the TBID_SIGNAL_BIT set and contain the
22 following related bit-fields */
23#define TBID_SIGNUM_S 2
24
25/* END HACK */
26
27#ifdef METAC_1_0
28/* Ax.4 is saved in TBICTX */
29#define A0_4 ,A0.4
30#else
31/* Ax.4 is NOT saved in TBICTX */
32#define A0_4
33#endif
34
35/* Size of the TBICTX structure */
36#define TBICTX_BYTES ((TBICTX_AX_REGS*8)+TBICTX_AX)
37
38#ifdef METAC_1_1
39#ifndef BOOTROM
40#ifndef SPECIAL_BUILD
41/* Jump straight into the boot ROM version of this code */
42#define CODE_USES_BOOTROM
43#endif
44#endif
45#endif
46
47/* Define space needed for CATCH buffer state in traditional units */
48#define CATCH_ENTRIES 5
49#define CATCH_ENTRY_BYTES 16
50
51#ifndef CODE_USES_BOOTROM
52#define A0GblIStP A0.15 /* PTBICTX for current thread in PRIV system */
53#define A1GblIGbP A1.15 /* Interrupt A1GbP value in PRIV system */
54#endif
55
56/*
57 * TBIRES __TBIASyncTrigger( TBIRES State )
58 */
59 .text
60 .balign 4
61 .global ___TBIASyncTrigger
62 .type ___TBIASyncTrigger,function
63___TBIASyncTrigger:
64#ifdef CODE_USES_BOOTROM
65 MOVT D0Re0,#HI(LINCORE_BASE)
66 JUMP D0Re0,#0xA0
67#else
68 MOV D0FrT,A0FrP /* Boing entry sequence */
69 ADD A0FrP,A0StP,#0
70 SETL [A0StP++],D0FrT,D1RtP
71 MOV D0Re0,PCX /* Check for repeat call */
72 MOVT D0FrT,#HI(___TBIBoingRTI+4)
73 ADD D0FrT,D0FrT,#LO(___TBIBoingRTI+4)
74 CMP D0Re0,D0FrT
75 BEQ ___TBIBoingExit /* Already set up - come out */
76 ADD D1Ar1,D1Ar1,#7 /* PRIV system stack here */
77 MOV A0.2,A0StP /* else push context here */
78 MOVS D0Re0,D0Ar2 /* Return in user mode? */
79 ANDMB D1Ar1,D1Ar1,#0xfff8 /* align priv stack to 64-bit */
80 MOV D1Re0,D1Ar1 /* and set result to arg */
81 MOVMI A0.2,D1Ar1 /* use priv stack if PRIV set */
82/*
83 * Generate an initial TBICTX to return to our own current call context
84 */
85 MOVT D1Ar5,#HI(___TBIBoingExit) /* Go here to return */
86 ADD D1Ar5,D1Ar5,#LO(___TBIBoingExit)
87 ADD A0.3,A0.2,#TBICTX_DX /* DX Save area */
88 ANDT D0Ar2,D0Ar2,#TBICTX_PRIV_BIT /* Extract PRIV bit */
89 MOVT D0Ar6,#TBICTX_SOFT_BIT /* Only soft thread state */
90 ADD D0Ar6,D0Ar6,D0Ar2 /* Add in PRIV bit if requested */
91 SETL [A0.2],D0Ar6,D1Ar5 /* Push header fields */
92 ADD D0FrT,A0.2,#TBICTX_AX /* Address AX save area */
93 MSETL [A0.3],D0Re0,D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7
94 MOV D0Ar6,#0
95 MOV D1Ar5,#0
96 SETL [A0.3++],D0Ar6,D1Ar5 /* Zero CT register states */
97 SETL [A0.3++],D0Ar6,D1Ar5
98 MSETL [D0FrT],A0StP,A0FrP,A0.2,A0.3 A0_4 /* Save AX regs */
99 MOV A0FrP,A0.2 /* Restore me! */
100 B ___TBIResume
101 .size ___TBIASyncTrigger,.-___TBIASyncTrigger
102
103/*
104 * Optimised return to handler for META Core
105 */
106___TBIBoingRTH:
107 RTH /* Go to background level */
108 MOVT A0.2, #HI($Lpcx_target)
109 ADD A0.2,A0.2,#LO($Lpcx_target)
110 MOV PCX,A0.2 /* Setup PCX for interrupts */
111 MOV PC,D1Re0 /* Jump to handler */
112/*
113 * This is where the code below needs to jump to wait for outermost interrupt
114 * event in a non-privilege mode system (single shared interrupt stack).
115 */
116___TBIBoingPCX:
117 MGETL A0StP,A0FrP,A0.2,A0.3 A0_4,[D1Re0] /* Restore AX regs */
118 MOV TXSTATUS,D0Re0 /* Restore flags */
119 GETL D0Re0,D1Re0,[D1Re0+#TBICTX_DX-TBICTX_BYTES]
120___TBIBoingRTI:
121 RTI /* Wait for interrupt */
122$Lpcx_target:
123/*
124 * Save initial interrupt state on current stack
125 */
126 SETL [A0StP+#TBICTX_DX],D0Re0,D1Re0 /* Save key registers */
127 ADD D1Re0,A0StP,#TBICTX_AX /* Address AX save area */
128 MOV D0Re0,TXSTATUS /* Read TXSTATUS into D0Re0 */
129 MOV TXSTATUS,#0 /* Clear TXSTATUS */
130 MSETL [D1Re0],A0StP,A0FrP,A0.2,A0.3 A0_4 /* Save AX critical regs */
131/*
132 * Register state at this point is-
133 *
134 * D0Re0 - Old TXSTATUS with PRIV and CBUF bits set if appropriate
135 * A0StP - Is call stack frame and base of TBICTX being generated
136 * A1GbP - Is valid static access link
137 */
138___TBIBoing:
139 LOCK0 /* Make sure we have no locks! */
140 ADD A1.2,A0StP,#TBICTX_DX+(8*1) /* Address DX.1 save area */
141 MOV A0FrP,A0StP /* Setup frame pointer */
142 MSETL [A1.2],D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7
143 MOV D0Ar4,TXRPT /* Save critical CT regs */
144 MOV D1Ar3,TXBPOBITS
145 MOV D1Ar1,TXDIVTIME /* Calc catch buffer pSrc */
146 MOV D0Ar2,TXMODE
147 MOV TXMODE,#0 /* Clear TXMODE */
148#ifdef TXDIVTIME_RPDIRTY_BIT
149 TSTT D1Ar1,#HI(TXDIVTIME_RPDIRTY_BIT)/* NZ = RPDIRTY */
150 MOVT D0Ar6,#TBICTX_CBRP_BIT
151 ORNZ D0Re0,D0Re0,D0Ar6 /* Set CBRP if RPDIRTY set */
152#endif
153 MSETL [A1.2],D0Ar4,D0Ar2 /* Save CT regs state */
154 MOV D0Ar2,D0Re0 /* Copy TXSTATUS */
155 ANDMT D0Ar2,D0Ar2,#TBICTX_CBUF_BIT+TBICTX_CBRP_BIT
156#ifdef TBI_1_4
157 MOVT D1Ar1,#TBICTX_FPAC_BIT /* Copy FPActive into FPAC */
158 TSTT D0Re0,#HI(TXSTATUS_FPACTIVE_BIT)
159 ORNZ D0Ar2,D0Ar2,D1Ar1
160#endif
161 MOV D1Ar1,PCX /* Read CurrPC */
162 ORT D0Ar2,D0Ar2,#TBICTX_CRIT_BIT /* SaveMask + CRIT bit */
163 SETL [A0FrP+#TBICTX_Flags],D0Ar2,D1Ar1 /* Set pCtx header fields */
164/*
165 * Completed context save, now we need to make a call to an interrupt handler
166 *
167 * D0Re0 - holds PRIV, WAIT, CBUF flags, HALT reason if appropriate
168 * A0FrP - interrupt stack frame and base of TBICTX being generated
169 * A0StP - same as A0FrP
170 */
171___TBIBoingWait:
172 /* Reserve space for TBICTX and CBUF */
173 ADD A0StP,A0StP,#TBICTX_BYTES+(CATCH_ENTRY_BYTES*CATCH_ENTRIES)
174 MOV D0Ar4,TXSTATI /* Read the Triggers data */
175 MOV D1Ar3,TXDIVTIME /* Read IRQEnc bits */
176 MOV D0Ar2,D0Re0 /* Copy PRIV and WAIT flags */
177 ANDT D0Ar2,D0Ar2,#TBICTX_PRIV_BIT+TBICTX_WAIT_BIT+TBICTX_CBUF_BIT
178#ifdef TBI_1_4
179 MOVT D1Ar5,#TBICTX_FPAC_BIT /* Copy FPActive into FPAC */
180 TSTT D0Re0,#HI(TXSTATUS_FPACTIVE_BIT)
181 ORNZ D0Ar2,D0Ar2,D1Ar5
182#endif
183 ANDT D1Ar3,D1Ar3,#HI(TXDIVTIME_IRQENC_BITS)
184 LSR D1Ar3,D1Ar3,#TXDIVTIME_IRQENC_S
185 AND TXSTATI,D0Ar4,#TXSTATI_BGNDHALT_BIT/* Ack any HALT seen */
186 ANDS D0Ar4,D0Ar4,#0xFFFF-TXSTATI_BGNDHALT_BIT /* Only seen HALT? */
187 ORT D0Ar2,D0Ar2,#TBICTX_CRIT_BIT /* Set CRIT */
188#ifndef BOOTROM
189 MOVT A1LbP,#HI(___pTBIs)
190 ADD A1LbP,A1LbP,#LO(___pTBIs)
191 GETL D1Ar5,D0Ar6,[A1LbP] /* D0Ar6 = ___pTBIs[1] */
192#else
193/*
194 * For BOOTROM support ___pTBIs must be allocated at offset 0 vs A1GbP
195 */
196 GETL D1Ar5,D0Ar6,[A1GbP] /* D0Ar6 = ___pTBIs[1] */
197#endif
198 BZ ___TBIBoingHalt /* Yes: Service HALT */
199/*
200 * Encode interrupt as signal vector, strip away same/lower TXMASKI bits
201 */
202 MOV D1Ar1,#1 /* Generate mask for this bit */
203 MOV D0Re0,TXMASKI /* Get interrupt mask */
204 LSL TXSTATI,D1Ar1,D1Ar3 /* Acknowledge trigger */
205 AND TXMASKI,D0Re0,#TXSTATI_BGNDHALT_BIT /* Only allow HALTs */
206 OR D0Ar2,D0Ar2,D0Re0 /* Set TBIRES.Sig.TrigMask */
207 ADD D1Ar3,D1Ar3,#TBID_SIGNUM_TRT /* Offset into interrupt sigs */
208 LSL D0Re0,D1Ar3,#TBID_SIGNUM_S /* Generate offset from SigNum */
209/*
210 * This is a key moment we are about to call the handler, register state is
211 * as follows-
212 *
213 * D0Re0 - Handler vector (SigNum<<TBID_SIGNUM_S)
214 * D0Ar2 - TXMASKI:TBICTX_CRIT_BIT with optional CBUF and PRIV bits
215 * D1Ar3 - SigNum
216 * D0Ar4 - State read from TXSTATI
217 * D1Ar5 - Inst for SWITCH trigger case only, otherwise undefined
218 * D0Ar6 - pTBI
219 */
220___TBIBoingVec:
221 ADD D0Re0,D0Re0,#TBI_fnSigs /* Offset into signal table */
222 GETD D1Re0,[D0Ar6+D0Re0] /* Get address for Handler */
223/*
224 * Call handler at interrupt level, when it returns simply resume execution
225 * of state indicated by D1Re0.
226 */
227 MOV D1Ar1,A0FrP /* Pass in pCtx */
228 CALLR D1RtP,___TBIBoingRTH /* Use RTH to invoke handler */
229
230/*
231 * Perform critical state restore and execute background thread.
232 *
233 * A0FrP - is pointer to TBICTX structure to resume
234 * D0Re0 - contains additional TXMASKI triggers
235 */
236 .text
237 .balign 4
238#ifdef BOOTROM
239 .global ___TBIResume
240#endif
241___TBIResume:
242/*
243 * New META IP method
244 */
245 RTH /* Go to interrupt level */
246 MOV D0Ar4,TXMASKI /* Read TXMASKI */
247 OR TXMASKI,D0Ar4,D0Re0 /* -Write-Modify TXMASKI */
248 GETL D0Re0,D1Re0,[A0FrP+#TBICTX_Flags]/* Get Flags:SaveMask, CurrPC */
249 MOV A0StP,A0FrP /* Position stack pointer */
250 MOV D0Ar2,TXPOLLI /* Read pending triggers */
251 MOV PCX,D1Re0 /* Set resumption PC */
252 TST D0Ar2,#0xFFFF /* Any pending triggers? */
253 BNZ ___TBIBoingWait /* Yes: Go for triggers */
254 TSTT D0Re0,#TBICTX_WAIT_BIT /* Do we WAIT anyway? */
255 BNZ ___TBIBoingWait /* Yes: Go for triggers */
256 LSLS D1Ar5,D0Re0,#1 /* Test XCBF (MI) & PRIV (CS)? */
257 ADD D1Re0,A0FrP,#TBICTX_CurrRPT /* Address CT save area */
258 ADD A0StP,A0FrP,#TBICTX_DX+(8*1) /* Address DX.1 save area */
259 MGETL A0.2,A0.3,[D1Re0] /* Get CT reg states */
260 MOV D1Ar3,A1.3 /* Copy old TXDIVTIME */
261 BPL ___TBIResCrit /* No: Skip logic */
262 ADD D0Ar4,A0FrP,#TBICTX_BYTES /* Source is after TBICTX */
263 ANDST D1Ar3,D1Ar3,#HI(TXDIVTIME_RPMASK_BITS)/* !Z if RPDIRTY */
264 MGETL D0.5,D0.6,[D0Ar4] /* Read Catch state */
265 MOV TXCATCH0,D0.5 /* Restore TXCATCHn */
266 MOV TXCATCH1,D1.5
267 MOV TXCATCH2,D0.6
268 MOV TXCATCH3,D1.6
269 BZ ___TBIResCrit
270 MOV D0Ar2,#(1*8)
271 LSRS D1Ar3,D1Ar3,#TXDIVTIME_RPMASK_S+1 /* 2nd RPMASK bit -> bit 0 */
272 ADD RA,D0Ar4,#(0*8) /* Re-read read pipeline */
273 ADDNZ RA,D0Ar4,D0Ar2 /* If Bit 0 set issue RA */
274 LSRS D1Ar3,D1Ar3,#2 /* Bit 1 -> C, Bit 2 -> Bit 0 */
275 ADD D0Ar2,D0Ar2,#8
276 ADDCS RA,D0Ar4,D0Ar2 /* If C issue RA */
277 ADD D0Ar2,D0Ar2,#8
278 ADDNZ RA,D0Ar4,D0Ar2 /* If Bit 0 set issue RA */
279 LSRS D1Ar3,D1Ar3,#2 /* Bit 1 -> C, Bit 2 -> Bit 0 */
280 ADD D0Ar2,D0Ar2,#8
281 ADDCS RA,D0Ar4,D0Ar2 /* If C issue RA */
282 ADD D0Ar2,D0Ar2,#8
283 ADDNZ RA,D0Ar4,D0Ar2 /* If Bit 0 set issue RA */
284 MOV TXDIVTIME,A1.3 /* Set RPDIRTY again */
285___TBIResCrit:
286 LSLS D1Ar5,D0Re0,#1 /* Test XCBF (MI) & PRIV (CS)? */
287#ifdef TBI_1_4
288 ANDT D1Ar5,D1Ar5,#(TBICTX_FPAC_BIT*2)
289 LSL D0Ar6,D1Ar5,#3 /* Convert FPAC into FPACTIVE */
290#endif
291 ANDMT D0Re0,D0Re0,#TBICTX_CBUF_BIT /* Keep CBUF bit from SaveMask */
292#ifdef TBI_1_4
293 OR D0Re0,D0Re0,D0Ar6 /* Combine FPACTIVE with others */
294#endif
295 MGETL D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7,[A0StP] /* Restore DX */
296 MOV TXRPT,A0.2 /* Restore CT regs */
297 MOV TXBPOBITS,A1.2
298 MOV TXMODE,A0.3
299 BCC ___TBIBoingPCX /* Do non-PRIV wait! */
300 MOV A1GblIGbP,A1GbP /* Save A1GbP too */
301 MGETL A0StP,A0FrP,A0.2,A0.3 A0_4,[D1Re0] /* Restore AX regs */
302/*
303 * Wait for the first interrupt/exception trigger in a privilege mode system
304 * (interrupt stack area for current TASK to be pointed to by A0GblIStP
305 * or per_cpu__stack_save[hwthread_id]).
306 */
307 MOV TXSTATUS,D0Re0 /* Restore flags */
308 MOV D0Re0,TXPRIVEXT /* Set TXPRIVEXT_TXTOGGLEI_BIT */
309 SUB D1Re0,D1Re0,#TBICTX_BYTES /* TBICTX is top of int stack */
310#ifdef TBX_PERCPU_SP_SAVE
311 SWAP D1Ar3,A1GbP
312 MOV D1Ar3,TXENABLE /* Which thread are we? */
313 AND D1Ar3,D1Ar3,#TXENABLE_THREAD_BITS
314 LSR D1Ar3,D1Ar3,#TXENABLE_THREAD_S-2
315 ADDT D1Ar3,D1Ar3,#HI(_per_cpu__stack_save)
316 ADD D1Ar3,D1Ar3,#LO(_per_cpu__stack_save)
317 SETD [D1Ar3],D1Re0
318 SWAP D1Ar3,A1GbP
319#else
320 MOV A0GblIStP, D1Re0
321#endif
322 OR D0Re0,D0Re0,#TXPRIVEXT_TXTOGGLEI_BIT
323 MOV TXPRIVEXT,D0Re0 /* Cannot set TXPRIVEXT if !priv */
324 GETL D0Re0,D1Re0,[D1Re0+#TBICTX_DX]
325 RTI /* Wait for interrupt */
326/*
327 * Save initial interrupt state on A0GblIStP, switch to A0GblIStP if
328 * BOOTROM code, save and switch to [A1GbP] otherwise.
329 */
330___TBIBoingPCXP:
331#ifdef TBX_PERCPU_SP_SAVE
332 SWAP D1Ar3,A1GbP /* Get PRIV stack base */
333 MOV D1Ar3,TXENABLE /* Which thread are we? */
334 AND D1Ar3,D1Ar3,#TXENABLE_THREAD_BITS
335 LSR D1Ar3,D1Ar3,#TXENABLE_THREAD_S-2
336 ADDT D1Ar3,D1Ar3,#HI(_per_cpu__stack_save)
337 ADD D1Ar3,D1Ar3,#LO(_per_cpu__stack_save)
338 GETD D1Ar3,[D1Ar3]
339#else
340 SWAP D1Ar3,A0GblIStP /* Get PRIV stack base */
341#endif
342 SETL [D1Ar3+#TBICTX_DX],D0Re0,D1Re0 /* Save key registers */
343 MOV D0Re0,TXPRIVEXT /* Clear TXPRIVEXT_TXTOGGLEI_BIT */
344 ADD D1Re0,D1Ar3,#TBICTX_AX /* Address AX save area */
345 ANDMB D0Re0,D0Re0,#0xFFFF-TXPRIVEXT_TXTOGGLEI_BIT
346 MOV TXPRIVEXT,D0Re0 /* Cannot set TXPRIVEXT if !priv */
347 MOV D0Re0,TXSTATUS /* Read TXSTATUS into D0Re0 */
348 MOV TXSTATUS,#0 /* Clear TXSTATUS */
349 MSETL [D1Re0],A0StP,A0FrP,A0.2,A0.3 A0_4 /* Save AX critical regs */
350 MOV A0StP,D1Ar3 /* Switch stacks */
351#ifdef TBX_PERCPU_SP_SAVE
352 MOV D1Ar3,A1GbP /* Get D1Ar2 back */
353#else
354 MOV D1Ar3,A0GblIStP /* Get D1Ar2 back */
355#endif
356 ORT D0Re0,D0Re0,#TBICTX_PRIV_BIT /* Add PRIV to TXSTATUS */
357 MOV A1GbP,A1GblIGbP /* Restore A1GbP */
358 B ___TBIBoing /* Enter common handler code */
359/*
360 * At this point we know it's a background HALT case we are handling.
361 * The restored TXSTATUS always needs to have zero in the reason bits.
362 */
363___TBIBoingHalt:
364 MOV D0Ar4,TXMASKI /* Get interrupt mask */
365 ANDST D0Re0,D0Re0,#HI(TXSTATUS_MAJOR_HALT_BITS+TXSTATUS_MEM_FAULT_BITS)
366 AND TXMASKI,D0Ar4,#TXSTATI_BGNDHALT_BIT /* Only allow HALTs */
367 AND D0Ar4,D0Ar4,#0xFFFF-TXSTATI_BGNDHALT_BIT /* What ints are off? */
368 OR D0Ar2,D0Ar2,D0Ar4 /* Set TBIRES.Sig.TrigMask */
369 MOV D0Ar4,#TXSTATI_BGNDHALT_BIT /* This was the trigger state */
370 LSR D1Ar3,D0Re0,#TXSTATUS_MAJOR_HALT_S
371 MOV D0Re0,#TBID_SIGNUM_XXF<<TBID_SIGNUM_S
372 BNZ ___TBIBoingVec /* Jump to XXF exception handler */
373/*
374 * Only the SWITCH cases are left, PCX must be valid
375 */
376#ifdef TBI_1_4
377 MOV D1Ar5,TXPRIVEXT
378 TST D1Ar5,#TXPRIVEXT_MINIMON_BIT
379 LSR D1Ar3,D1Ar1,#1 /* Shift needed for MINIM paths (fill stall) */
380 BZ $Lmeta /* If META only, skip */
381 TSTT D1Ar1,#HI(0x00800000)
382 ANDMT D1Ar3,D1Ar3,#HI(0x007FFFFF >> 1)/* Shifted mask for large MINIM */
383 ANDT D1Ar1,D1Ar1,#HI(0xFFE00000) /* Static mask for small MINIM */
384 BZ $Llarge_minim /* If large MINIM */
385$Lsmall_minim:
386 TSTT D1Ar3,#HI(0x00100000 >> 1)
387 ANDMT D1Ar3,D1Ar3,#HI(0x001FFFFF >> 1)/* Correct shifted mask for large MINIM */
388 ADDZ D1Ar1,D1Ar1,D1Ar3 /* If META rgn, add twice to undo LSR #1 */
389 B $Lrecombine
390$Llarge_minim:
391 ANDST D1Ar1,D1Ar1,#HI(0xFF800000) /* Correct static mask for small MINIM */
392 /* Z=0 (Cannot place code at NULL) */
393$Lrecombine:
394 ADD D1Ar1,D1Ar1,D1Ar3 /* Combine static and shifted parts */
395$Lmeta:
396 GETW D1Ar5,[D1Ar1++] /* META: lo-16, MINIM: lo-16 (all-16 if short) */
397 GETW D1Ar3,[D1Ar1] /* META: hi-16, MINIM: hi-16 (only if long) */
398 MOV D1Re0,D1Ar5
399 XOR D1Re0,D1Re0,#0x4000
400 LSLSNZ D1Re0,D1Re0,#(32-14) /* MINIM: If long C=0, if short C=1 */
401 LSLCC D1Ar3,D1Ar3,#16 /* META/MINIM long: Move hi-16 up */
402 LSLCS D1Ar3,D1Ar5,#16 /* MINIM short: Dup all-16 */
403 ADD D1Ar5,D1Ar5,D1Ar3 /* ALL: Combine both 16-bit parts */
404#else
405 GETD D1Ar5,[D1Ar1] /* Read instruction for switch */
406#endif
407 LSR D1Ar3,D1Ar5,#22 /* Convert into signal number */
408 AND D1Ar3,D1Ar3,#TBID_SIGNUM_SW3-TBID_SIGNUM_SW0
409 LSL D0Re0,D1Ar3,#TBID_SIGNUM_S /* Generate offset from SigNum */
410 B ___TBIBoingVec /* Jump to switch handler */
411/*
412 * Exit from TBIASyncTrigger call
413 */
414___TBIBoingExit:
415 GETL D0FrT,D1RtP,[A0FrP++] /* Restore state from frame */
416 SUB A0StP,A0FrP,#8 /* Unwind stack */
417 MOV A0FrP,D0FrT /* Last memory read completes */
418 MOV PC,D1RtP /* Return to caller */
419#endif /* ifdef CODE_USES_BOOTROM */
420 .size ___TBIResume,.-___TBIResume
421
422#ifndef BOOTROM
423/*
424 * void __TBIASyncResume( TBIRES State )
425 */
426 .text
427 .balign 4
428 .global ___TBIASyncResume
429 .type ___TBIASyncResume,function
430___TBIASyncResume:
431/*
432 * Perform CRIT|SOFT state restore and execute background thread.
433 */
434 MOV D1Ar3,D1Ar1 /* Restore this context */
435 MOV D0Re0,D0Ar2 /* Carry in additional triggers */
436 /* Reserve space for TBICTX */
437 ADD D1Ar3,D1Ar3,#TBICTX_BYTES+(CATCH_ENTRY_BYTES*CATCH_ENTRIES)
438 MOV A0StP,D1Ar3 /* Enter with protection of */
439 MOV A0FrP,D1Ar1 /* TBICTX on our stack */
440#ifdef CODE_USES_BOOTROM
441 MOVT D1Ar1,#HI(LINCORE_BASE)
442 JUMP D1Ar1,#0xA4
443#else
444 B ___TBIResume
445#endif
446 .size ___TBIASyncResume,.-___TBIASyncResume
447#endif /* ifndef BOOTROM */
448
449/*
450 * End of tbipcx.S
451 */
diff --git a/arch/metag/tbx/tbiroot.S b/arch/metag/tbx/tbiroot.S
new file mode 100644
index 000000000000..7d84daf1340b
--- /dev/null
+++ b/arch/metag/tbx/tbiroot.S
@@ -0,0 +1,87 @@
1/*
2 * tbiroot.S
3 *
4 * Copyright (C) 2001, 2002, 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 * Module that creates and via ___TBI function returns a TBI Root Block for
11 * interrupt and background processing on the current thread.
12 */
13
14 .file "tbiroot.S"
15#include <asm/metag_regs.h>
16
17/*
18 * Get data structures and defines from the TBI C header
19 */
20#include <asm/tbx.h>
21
22
23/* If signals need to be exchanged we must create a TBI Root Block */
24
25 .data
26 .balign 8
27 .global ___pTBIs
28 .type ___pTBIs,object
29___pTBIs:
30 .long 0 /* Bgnd+Int root block ptrs */
31 .long 0
32 .size ___pTBIs,.-___pTBIs
33
34
35/*
36 * Return ___pTBIs value specific to execution level with promotion/demotion
37 *
38 * Register Usage: D1Ar1 is Id, D0Re0 is the primary result
39 * D1Re0 is secondary result (___pTBIs for other exec level)
40 */
41 .text
42 .balign 4
43 .global ___TBI
44 .type ___TBI,function
45___TBI:
46 TSTT D1Ar1,#HI(TBID_ISTAT_BIT) /* Bgnd or Int level? */
47 MOVT A1LbP,#HI(___pTBIs)
48 ADD A1LbP,A1LbP,#LO(___pTBIs)
49 GETL D0Re0,D1Re0,[A1LbP] /* Base of root block table */
50 SWAPNZ D0Re0,D1Re0 /* Swap if asked */
51 MOV PC,D1RtP
52 .size ___TBI,.-___TBI
53
54
55/*
56 * Return identifier of the current thread in TBI segment or signal format with
57 * secondary mask to indicate privilege and interrupt level of thread
58 */
59 .text
60 .balign 4
61 .global ___TBIThrdPrivId
62 .type ___TBIThrdPrivId,function
63___TBIThrdPrivId:
64 .global ___TBIThreadId
65 .type ___TBIThreadId,function
66___TBIThreadId:
67#ifndef METAC_0_1
68 MOV D1Re0,TXSTATUS /* Are we privileged or int? */
69 MOV D0Re0,TXENABLE /* Which thread are we? */
70/* Disable privilege adaption for now */
71 ANDT D1Re0,D1Re0,#HI(TXSTATUS_ISTAT_BIT) /* +TXSTATUS_PSTAT_BIT) */
72 LSL D1Re0,D1Re0,#TBID_ISTAT_S-TXSTATUS_ISTAT_S
73 AND D0Re0,D0Re0,#TXENABLE_THREAD_BITS
74 LSL D0Re0,D0Re0,#TBID_THREAD_S-TXENABLE_THREAD_S
75#else
76/* Thread 0 only */
77 XOR D0Re0,D0Re0,D0Re0
78 XOR D1Re0,D1Re0,D1Re0
79#endif
80 MOV PC,D1RtP /* Return */
81 .size ___TBIThrdPrivId,.-___TBIThrdPrivId
82 .size ___TBIThreadId,.-___TBIThreadId
83
84
85/*
86 * End of tbiroot.S
87 */
diff --git a/arch/metag/tbx/tbisoft.S b/arch/metag/tbx/tbisoft.S
new file mode 100644
index 000000000000..0346fe8a53b1
--- /dev/null
+++ b/arch/metag/tbx/tbisoft.S
@@ -0,0 +1,237 @@
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 */
diff --git a/arch/metag/tbx/tbistring.c b/arch/metag/tbx/tbistring.c
new file mode 100644
index 000000000000..f90cd0822065
--- /dev/null
+++ b/arch/metag/tbx/tbistring.c
@@ -0,0 +1,114 @@
1/*
2 * tbistring.c
3 *
4 * Copyright (C) 2001, 2002, 2003, 2005, 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 * String table functions provided as part of the thread binary interface for
11 * Meta processors
12 */
13
14#include <linux/export.h>
15#include <linux/string.h>
16#include <asm/tbx.h>
17
18/*
19 * There are not any functions to modify the string table currently, if these
20 * are required at some later point I suggest having a seperate module and
21 * ensuring that creating new entries does not interfere with reading old
22 * entries in any way.
23 */
24
25const TBISTR *__TBIFindStr(const TBISTR *start,
26 const char *str, int match_len)
27{
28 const TBISTR *search = start;
29 bool exact = true;
30 const TBISEG *seg;
31
32 if (match_len < 0) {
33 /* Make match_len always positive for the inner loop */
34 match_len = -match_len;
35 exact = false;
36 } else {
37 /*
38 * Also support historic behaviour, which expected match_len to
39 * include null terminator
40 */
41 if (match_len && str[match_len-1] == '\0')
42 match_len--;
43 }
44
45 if (!search) {
46 /* Find global string table segment */
47 seg = __TBIFindSeg(NULL, TBID_SEG(TBID_THREAD_GLOBAL,
48 TBID_SEGSCOPE_GLOBAL,
49 TBID_SEGTYPE_STRING));
50
51 if (!seg || seg->Bytes < sizeof(TBISTR))
52 /* No string table! */
53 return NULL;
54
55 /* Start of string table */
56 search = seg->pGAddr;
57 }
58
59 for (;;) {
60 while (!search->Tag)
61 /* Allow simple gaps which are just zero initialised */
62 search = (const TBISTR *)((const char *)search + 8);
63
64 if (search->Tag == METAG_TBI_STRE) {
65 /* Reached the end of the table */
66 search = NULL;
67 break;
68 }
69
70 if ((search->Len >= match_len) &&
71 (!exact || (search->Len == match_len + 1)) &&
72 (search->Tag != METAG_TBI_STRG)) {
73 /* Worth searching */
74 if (!strncmp(str, (const char *)search->String,
75 match_len))
76 break;
77 }
78
79 /* Next entry */
80 search = (const TBISTR *)((const char *)search + search->Bytes);
81 }
82
83 return search;
84}
85
86const void *__TBITransStr(const char *str, int len)
87{
88 const TBISTR *search = NULL;
89 const void *res = NULL;
90
91 for (;;) {
92 /* Search onwards */
93 search = __TBIFindStr(search, str, len);
94
95 /* No translation returns NULL */
96 if (!search)
97 break;
98
99 /* Skip matching entries with no translation data */
100 if (search->TransLen != METAG_TBI_STRX) {
101 /* Calculate base of translation string */
102 res = (const char *)search->String +
103 ((search->Len + 7) & ~7);
104 break;
105 }
106
107 /* Next entry */
108 search = (const TBISTR *)((const char *)search + search->Bytes);
109 }
110
111 /* Return base address of translation data or NULL */
112 return res;
113}
114EXPORT_SYMBOL(__TBITransStr);
diff --git a/arch/metag/tbx/tbitimer.S b/arch/metag/tbx/tbitimer.S
new file mode 100644
index 000000000000..5dbeddeee7ba
--- /dev/null
+++ b/arch/metag/tbx/tbitimer.S
@@ -0,0 +1,207 @@
1/*
2 * tbitimer.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 * TBI timer support routines and data values
11 */
12
13 .file "tbitimer.S"
14/*
15 * Get data structures and defines from the main C header
16 */
17#include <asm/tbx.h>
18
19 .data
20 .balign 8
21 .global ___TBITimeB
22 .type ___TBITimeB,object
23___TBITimeB:
24 .quad 0 /* Background 'lost' ticks */
25 .size ___TBITimeB,.-___TBITimeB
26
27 .data
28 .balign 8
29 .global ___TBITimeI
30 .type ___TBITimeI,object
31___TBITimeI:
32 .quad 0 /* Interrupt 'lost' ticks */
33 .size ___TBITimeI,.-___TBITimeI
34
35 .data
36 .balign 8
37 .global ___TBITimes
38 .type ___TBITimes,object
39___TBITimes:
40 .long ___TBITimeB /* Table of 'lost' tick values */
41 .long ___TBITimeI
42 .size ___TBITimes,.-___TBITimes
43
44/*
45 * Flag bits for control of ___TBITimeCore
46 */
47#define TIMER_SET_BIT 1
48#define TIMER_ADD_BIT 2
49
50/*
51 * Initialise or stop timer support
52 *
53 * Register Usage: D1Ar1 holds Id, D1Ar2 is initial delay or 0
54 * D0FrT is used to call ___TBITimeCore
55 * D0Re0 is used for the result which is TXSTAT_TIMER_BIT
56 * D0Ar4, D1Ar5, D0Ar6 are all used as scratch
57 * Other registers are those set by ___TBITimeCore
58 * A0.3 is assumed to point at ___TBITime(I/B)
59 */
60 .text
61 .balign 4
62 .global ___TBITimerCtrl
63 .type ___TBITimerCtrl,function
64___TBITimerCtrl:
65 MOV D1Ar5,#TIMER_SET_BIT /* Timer SET request */
66 MOVT D0FrT,#HI(___TBITimeCore) /* Get timer core reg values */
67 CALL D0FrT,#LO(___TBITimeCore) /* and perform register update */
68 NEGS D0Ar6,D0Ar2 /* Set flags from time-stamp */
69 ASR D1Ar5,D0Ar6,#31 /* Sign extend D0Ar6 into D1Ar5 */
70 SETLNZ [A0.3],D0Ar6,D1Ar5 /* ___TBITime(B/I)=-Start if enable */
71 MOV PC,D1RtP /* Return */
72 .size ___TBITimerCtrl,.-___TBITimerCtrl
73
74/*
75 * Return ___TBITimeStamp value
76 *
77 * Register Usage: D1Ar1 holds Id
78 * D0FrT is used to call ___TBITimeCore
79 * D0Re0, D1Re0 is used for the result
80 * D1Ar3, D0Ar4, D1Ar5
81 * Other registers are those set by ___TBITimeCore
82 * D0Ar6 is assumed to be the timer value read
83 * A0.3 is assumed to point at ___TBITime(I/B)
84 */
85 .text
86 .balign 4
87 .global ___TBITimeStamp
88 .type ___TBITimeStamp,function
89___TBITimeStamp:
90 MOV D1Ar5,#0 /* Timer GET request */
91 MOVT D0FrT,#HI(___TBITimeCore) /* Get timer core reg values */
92 CALL D0FrT,#LO(___TBITimeCore) /* with no register update */
93 ADDS D0Re0,D0Ar4,D0Ar6 /* Add current time value */
94 ADD D1Re0,D1Ar3,D1Ar5 /* to 64-bit signed extend time */
95 ADDCS D1Re0,D1Re0,#1 /* Support borrow too */
96 MOV PC,D1RtP /* Return */
97 .size ___TBITimeStamp,.-___TBITimeStamp
98
99/*
100 * Perform ___TBITimerAdd logic
101 *
102 * Register Usage: D1Ar1 holds Id, D0Ar2 holds value to be added to the timer
103 * D0Re0 is used for the result - new TIMER value
104 * D1Ar5, D0Ar6 are used as scratch
105 * Other registers are those set by ___TBITimeCore
106 * D0Ar6 is assumed to be the timer value read
107 * D0Ar4, D1Ar3 is the current value of ___TBITime(B/I)
108 */
109 .text
110 .balign 4
111 .global ___TBITimerAdd
112 .type ___TBITimerAdd,function
113___TBITimerAdd:
114 MOV D1Ar5,#TIMER_ADD_BIT /* Timer ADD request */
115 MOVT D0FrT,#HI(___TBITimeCore) /* Get timer core reg values */
116 CALL D0FrT,#LO(___TBITimeCore) /* with no register update */
117 ADD D0Re0,D0Ar2,D0Ar6 /* Regenerate new value = result */
118 NEG D0Ar2,D0Ar2 /* Negate delta */
119 ASR D1Re0,D0Ar2,#31 /* Sign extend negated delta */
120 ADDS D0Ar4,D0Ar4,D0Ar2 /* Add time added to ... */
121 ADD D1Ar3,D1Ar3,D1Re0 /* ... real timer ... */
122 ADDCS D1Ar3,D1Ar3,#1 /* ... with carry */
123 SETL [A0.3],D0Ar4,D1Ar3 /* Update ___TBITime(B/I) */
124 MOV PC,D1RtP /* Return */
125 .size ___TBITimerAdd,.-___TBITimerAdd
126
127#ifdef TBI_1_4
128/*
129 * Perform ___TBITimerDeadline logic
130 * NB: Delays are positive compared to the Wait values which are -ive
131 *
132 * Register Usage: D1Ar1 holds Id
133 * D0Ar2 holds Delay requested
134 * D0Re0 is used for the result - old TIMER Delay value
135 * D1Ar5, D0Ar6 are used as scratch
136 * Other registers are those set by ___TBITimeCore
137 * D0Ar6 is assumed to be the timer value read
138 * D0Ar4, D1Ar3 is the current value of ___TBITime(B/I)
139 *
140 */
141 .text
142 .type ___TBITimerDeadline,function
143 .global ___TBITimerDeadline
144 .align 2
145___TBITimerDeadline:
146 MOV D1Ar5,#TIMER_SET_BIT /* Timer SET request */
147 MOVT D0FrT,#HI(___TBITimeCore) /* Get timer core reg values */
148 CALL D0FrT,#LO(___TBITimeCore) /* with no register update */
149 MOV D0Re0,D0Ar6 /* Old value read = result */
150 SUB D0Ar2,D0Ar6,D0Ar2 /* Delta from (old - new) */
151 ASR D1Re0,D0Ar2,#31 /* Sign extend delta */
152 ADDS D0Ar4,D0Ar4,D0Ar2 /* Add time added to ... */
153 ADD D1Ar3,D1Ar3,D1Re0 /* ... real timer ... */
154 ADDCS D1Ar3,D1Ar3,#1 /* ... with carry */
155 SETL [A0.3],D0Ar4,D1Ar3 /* Update ___TBITime(B/I) */
156 MOV PC,D1RtP /* Return */
157 .size ___TBITimerDeadline,.-___TBITimerDeadline
158#endif /* TBI_1_4 */
159
160/*
161 * Perform core timer access logic
162 *
163 * Register Usage: D1Ar1 holds Id, D0Ar2 holds input value for SET and
164 * input value for ADD
165 * D1Ar5 controls op as SET or ADD as bit values
166 * On return D0Ar6, D1Ar5 holds the old 64-bit timer value
167 * A0.3 is setup to point at ___TBITime(I/B)
168 * A1.3 is setup to point at ___TBITimes
169 * D0Ar4, D1Ar3 is setup to value of ___TBITime(I/B)
170 */
171 .text
172 .balign 4
173 .global ___TBITimeCore
174 .type ___TBITimeCore,function
175___TBITimeCore:
176#ifndef METAC_0_1
177 TSTT D1Ar1,#HI(TBID_ISTAT_BIT) /* Interrupt level timer? */
178#endif
179 MOVT A1LbP,#HI(___TBITimes)
180 ADD A1LbP,A1LbP,#LO(___TBITimes)
181 MOV A1.3,A1LbP /* Get ___TBITimes address */
182#ifndef METAC_0_1
183 BNZ $LTimeCoreI /* Yes: Service TXTIMERI! */
184#endif
185 LSRS D1Ar5,D1Ar5,#1 /* Carry = SET, Zero = !ADD */
186 GETD A0.3,[A1.3+#0] /* A0.3 == &___TBITimeB */
187 MOV D0Ar6,TXTIMER /* Always GET old value */
188 MOVCS TXTIMER,D0Ar2 /* Conditional SET operation */
189 ADDNZ TXTIMER,D0Ar2,D0Ar6 /* Conditional ADD operation */
190#ifndef METAC_0_1
191 B $LTimeCoreEnd
192$LTimeCoreI:
193 LSRS D1Ar5,D1Ar5,#1 /* Carry = SET, Zero = !ADD */
194 GETD A0.3,[A1.3+#4] /* A0.3 == &___TBITimeI */
195 MOV D0Ar6,TXTIMERI /* Always GET old value */
196 MOVCS TXTIMERI,D0Ar2 /* Conditional SET operation */
197 ADDNZ TXTIMERI,D0Ar2,D0Ar6 /* Conditional ADD operation */
198$LTimeCoreEnd:
199#endif
200 ASR D1Ar5,D0Ar6,#31 /* Sign extend D0Ar6 into D1Ar5 */
201 GETL D0Ar4,D1Ar3,[A0.3] /* Read ___TBITime(B/I) */
202 MOV PC,D0FrT /* Return quickly */
203 .size ___TBITimeCore,.-___TBITimeCore
204
205/*
206 * End of tbitimer.S
207 */