hpsa: add PMC to copyright
[linux/fpc-iii.git] / arch / metag / tbx / tbisoft.S
blob0346fe8a53b1c7f8f5e738ecec6e39ea322bf37e
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  */
13         .file   "tbisoft.S"
15 #include <asm/tbx.h>
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
27 /* Size of the TBICTX structure */
28 #define TBICTX_BYTES ((TBICTX_AX_REGS*8)+TBICTX_AX)
30         .text
31         .balign 4
32         .global ___TBISwitchTail
33         .type   ___TBISwitchTail,function
34 ___TBISwitchTail:
35         B       $LSwitchTail
36         .size   ___TBISwitchTail,.-___TBISwitchTail
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
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
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
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
115  * void __TBISyncResume( TBIRES State, int TrigMask );
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
140  * void __TBIJump( TBIX64 ArgsA, TBIX32 ArgsB, int TrigsMask,
141  *                               void (*fnMain)(), void *pStack );
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
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.
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 */
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
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
236  * End of tbisoft.S
237  */