1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
/*
* tbisoft.S
*
* Copyright (C) 2001, 2002, 2007, 2012 Imagination Technologies.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*
* Support for soft threads and soft context switches
*/
.file "tbisoft.S"
#include <asm/tbx.h>
#ifdef METAC_1_0
/* Ax.4 is saved in TBICTX */
#define A0_4 ,A0.4
#define D0_5 ,D0.5
#else
/* Ax.4 is NOT saved in TBICTX */
#define A0_4
#define D0_5
#endif
/* Size of the TBICTX structure */
#define TBICTX_BYTES ((TBICTX_AX_REGS*8)+TBICTX_AX)
.text
.balign 4
.global ___TBISwitchTail
.type ___TBISwitchTail,function
___TBISwitchTail:
B $LSwitchTail
.size ___TBISwitchTail,.-___TBISwitchTail
/*
* TBIRES __TBIJumpX( TBIX64 ArgsA, PTBICTX *rpSaveCtx, int TrigsMask,
* void (*fnMain)(), void *pStack );
*
* This is a combination of __TBISwitch and __TBIJump with the context of
* the calling thread being saved in the rpSaveCtx location with a drop-thru
* effect into the __TBIJump logic. ArgsB passes via __TBIJump to the
* routine eventually invoked will reflect the rpSaveCtx value specified.
*/
.text
.balign 4
.global ___TBIJumpX
.type ___TBIJumpX,function
___TBIJumpX:
CMP D1RtP,#-1
B $LSwitchStart
.size ___TBIJumpX,.-___TBIJumpX
/*
* TBIRES __TBISwitch( TBIRES Switch, PTBICTX *rpSaveCtx )
*
* Software synchronous context switch between soft threads, save only the
* registers which are actually valid on call entry.
*
* A0FrP, D0RtP, D0.5, D0.6, D0.7 - Saved on stack
* A1GbP is global to all soft threads so not virtualised
* A0StP is then saved as the base of the TBICTX of the thread
*
*/
.text
.balign 4
.global ___TBISwitch
.type ___TBISwitch,function
___TBISwitch:
XORS D0Re0,D0Re0,D0Re0 /* Set ZERO flag */
$LSwitchStart:
MOV D0FrT,A0FrP /* Boing entry sequence */
ADD A0FrP,A0StP,#0
SETL [A0StP+#8++],D0FrT,D1RtP
/*
* Save current frame state - we save all regs because we don't want
* uninitialised crap in the TBICTX structure that the asynchronous resumption
* of a thread will restore.
*/
MOVT D1Re0,#HI($LSwitchExit) /* ASync resume point here */
ADD D1Re0,D1Re0,#LO($LSwitchExit)
SETD [D1Ar3],A0StP /* Record pCtx of this thread */
MOVT D0Re0,#TBICTX_SOFT_BIT /* Only soft thread state */
SETL [A0StP++],D0Re0,D1Re0 /* Push header fields */
ADD D0FrT,A0StP,#TBICTX_AX-TBICTX_DX /* Address AX save area */
MOV D0Re0,#0 /* Setup 0:0 result for ASync */
MOV D1Re0,#0 /* resume of the thread */
MSETL [A0StP],D0Re0,D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7
SETL [A0StP++],D0Re0,D1Re0 /* Zero CurrRPT, CurrBPOBITS, */
SETL [A0StP++],D0Re0,D1Re0 /* Zero CurrMODE, CurrDIVTIME */
ADD A0StP,A0StP,#(TBICTX_AX_REGS*8) /* Reserve AX save space */
MSETL [D0FrT],A0StP,A0FrP,A0.2,A0.3 A0_4 /* Save AX regs */
BNZ ___TBIJump
/*
* NextThread MUST be in TBICTX_SOFT_BIT state!
*/
$LSwitchTail:
MOV D0Re0,D0Ar2 /* Result from args */
MOV D1Re0,D1Ar1
ADD D1RtP,D1Ar1,#TBICTX_AX
MGETL A0StP,A0FrP,[D1RtP] /* Get frame values */
$LSwitchCmn:
ADD A0.2,D1Ar1,#TBICTX_DX+(8*5)
MGETL D0.5,D0.6,D0.7,[A0.2] /* Get caller-saved DX regs */
$LSwitchExit:
GETL D0FrT,D1RtP,[A0FrP++] /* Restore state from frame */
SUB A0StP,A0FrP,#8 /* Unwind stack */
MOV A0FrP,D0FrT /* Last memory read completes */
MOV PC,D1RtP /* Return to caller */
.size ___TBISwitch,.-___TBISwitch
/*
* void __TBISyncResume( TBIRES State, int TrigMask );
*
* This routine causes the TBICTX structure specified in State.Sig.pCtx to
* be restored. This implies that execution will not return to the caller.
* The State.Sig.TrigMask field will be ored into TXMASKI during the
* context switch such that any immediately occurring interrupts occur in
* the context of the newly specified task. The State.Sig.SaveMask parameter
* is ignored.
*/
.text
.balign 4
.global ___TBISyncResume
.type ___TBISyncResume,function
___TBISyncResume:
MOV D0Re0,D0Ar2 /* Result from args */
MOV D1Re0,D1Ar1
XOR D1Ar5,D1Ar5,D1Ar5 /* D1Ar5 = 0 */
ADD D1RtP,D1Ar1,#TBICTX_AX
SWAP D1Ar5,TXMASKI /* D1Ar5 <-> TXMASKI */
MGETL A0StP,A0FrP,[D1RtP] /* Get frame values */
OR TXMASKI,D1Ar5,D1Ar3 /* New TXMASKI */
B $LSwitchCmn
.size ___TBISyncResume,.-___TBISyncResume
/*
* void __TBIJump( TBIX64 ArgsA, TBIX32 ArgsB, int TrigsMask,
* void (*fnMain)(), void *pStack );
*
* Jump directly to a new routine on an arbitrary stack with arbitrary args
* oring bits back into TXMASKI on route.
*/
.text
.balign 4
.global ___TBIJump
.type ___TBIJump,function
___TBIJump:
XOR D0Re0,D0Re0,D0Re0 /* D0Re0 = 0 */
MOV A0StP,D0Ar6 /* Stack = Frame */
SWAP D0Re0,TXMASKI /* D0Re0 <-> TXMASKI */
MOV A0FrP,D0Ar6
MOVT A1LbP,#HI(__exit)
ADD A1LbP,A1LbP,#LO(__exit)
MOV D1RtP,A1LbP /* D1RtP = __exit */
OR TXMASKI,D0Re0,D0Ar4 /* New TXMASKI */
MOV PC,D1Ar5 /* Jump to fnMain */
.size ___TBIJump,.-___TBIJump
/*
* PTBICTX __TBISwitchInit( void *pStack, int (*fnMain)(),
* .... 4 extra 32-bit args .... );
*
* Generate a new soft thread context ready for it's first outing.
*
* D1Ar1 - Region of memory to be used as the new soft thread stack
* D0Ar2 - Main line routine for new soft thread
* D1Ar3, D0Ar4, D1Ar5, D0Ar6 - arguments to be passed on stack
* The routine returns the initial PTBICTX value for the new thread
*/
.text
.balign 4
.global ___TBISwitchInit
.type ___TBISwitchInit,function
___TBISwitchInit:
MOV D0FrT,A0FrP /* Need save return point */
ADD A0FrP,A0StP,#0
SETL [A0StP++],D0FrT,D1RtP /* Save return to caller */
MOVT A1LbP,#HI(__exit)
ADD A1LbP,A1LbP,#LO(__exit)
MOV D1RtP,A1LbP /* Get address of __exit */
ADD D1Ar1,D1Ar1,#7 /* Align stack to 64-bits */
ANDMB D1Ar1,D1Ar1,#0xfff8 /* by rounding base up */
MOV A0.2,D1Ar1 /* A0.2 is new stack */
MOV D0FrT,D1Ar1 /* Initial puesdo-frame pointer */
SETL [A0.2++],D0FrT,D1RtP /* Save return to __exit */
MOV D1RtP,D0Ar2
SETL [A0.2++],D0FrT,D1RtP /* Save return to fnMain */
ADD D0FrT,D0FrT,#8 /* Advance puesdo-frame pointer */
MSETL [A0.2],D0Ar6,D0Ar4 /* Save extra initial args */
MOVT D1RtP,#HI(___TBIStart) /* Start up code for new stack */
ADD D1RtP,D1RtP,#LO(___TBIStart)
SETL [A0.2++],D0FrT,D1RtP /* Save return to ___TBIStart */
ADD D0FrT,D0FrT,#(8*3) /* Advance puesdo-frame pointer */
MOV D0Re0,A0.2 /* Return pCtx for new thread */
MOV D1Re0,#0 /* pCtx:0 is default Arg1:Arg2 */
/*
* Generate initial TBICTX state
*/
MOVT D1Ar1,#HI($LSwitchExit) /* Async restore code */
ADD D1Ar1,D1Ar1,#LO($LSwitchExit)
MOVT D0Ar2,#TBICTX_SOFT_BIT /* Only soft thread state */
ADD D0Ar6,A0.2,#TBICTX_BYTES /* New A0StP */
MOV D1Ar5,A1GbP /* Same A1GbP */
MOV D0Ar4,D0FrT /* Initial A0FrP */
MOV D1Ar3,A1LbP /* Same A1LbP */
SETL [A0.2++],D0Ar2,D1Ar1 /* Set header fields */
MSETL [A0.2],D0Re0,D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7
MOV D0Ar2,#0 /* Zero values */
MOV D1Ar1,#0
SETL [A0.2++],D0Ar2,D1Ar1 /* Zero CurrRPT, CurrBPOBITS, */
SETL [A0.2++],D0Ar2,D1Ar1 /* CurrMODE, and pCurrCBuf */
MSETL [A0.2],D0Ar6,D0Ar4,D0Ar2,D0FrT D0_5 /* Set DX and then AX regs */
B $LSwitchExit /* All done! */
.size ___TBISwitchInit,.-___TBISwitchInit
.text
.balign 4
.global ___TBIStart
.type ___TBIStart,function
___TBIStart:
MOV D1Ar1,D1Re0 /* Pass TBIRES args to call */
MOV D0Ar2,D0Re0
MGETL D0Re0,D0Ar6,D0Ar4,[A0FrP] /* Get hidden args */
SUB A0StP,A0FrP,#(8*3) /* Entry stack pointer */
MOV A0FrP,D0Re0 /* Entry frame pointer */
MOVT A1LbP,#HI(__exit)
ADD A1LbP,A1LbP,#LO(__exit)
MOV D1RtP,A1LbP /* D1RtP = __exit */
MOV PC,D1Re0 /* Jump into fnMain */
.size ___TBIStart,.-___TBIStart
/*
* End of tbisoft.S
*/
|