• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
238