|
0
|
1 ##============================================================================= |
|
|
2 ## |
|
|
3 ## context.S |
|
|
4 ## |
|
|
5 ## PowerPC context switch code |
|
|
6 ## |
|
|
7 ##============================================================================= |
|
|
8 #####COPYRIGHTBEGIN#### |
|
|
9 # |
|
|
10 # ------------------------------------------- |
|
|
11 # The contents of this file are subject to the Cygnus eCos Public License |
|
|
12 # Version 1.0 (the "License"); you may not use this file except in |
|
|
13 # compliance with the License. You may obtain a copy of the License at |
|
|
14 # http://sourceware.cygnus.com/ecos |
|
|
15 # |
|
|
16 # Software distributed under the License is distributed on an "AS IS" |
|
|
17 # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
|
18 # License for the specific language governing rights and limitations under |
|
|
19 # the License. |
|
|
20 # |
|
|
21 # The Original Code is eCos - Embedded Cygnus Operating System, released |
|
|
22 # September 30, 1998. |
|
|
23 # |
|
|
24 # The Initial Developer of the Original Code is Cygnus. Portions created |
|
|
25 # by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. |
|
|
26 # ------------------------------------------- |
|
|
27 # |
|
|
28 #####COPYRIGHTEND#### |
|
|
29 ##============================================================================= |
|
|
30 #######DESCRIPTIONBEGIN#### |
|
|
31 ## |
|
|
32 ## Author(s): nickg |
|
|
33 ## Contributors: nickg |
|
|
34 ## Date: 1998-04-27 |
|
|
35 ## Purpose: PowerPC context switch code |
|
|
36 ## Description: This file contains implementations of the thread context |
|
|
37 ## switch routines. It also contains the longjmp() and setjmp() |
|
|
38 ## routines. |
|
|
39 ## |
|
|
40 ######DESCRIPTIONEND#### |
|
|
41 ## |
|
|
42 ##============================================================================= |
|
|
43 |
|
|
44 #include <pkgconf/hal.h> |
|
|
45 |
|
|
46 #include "cyg/hal/ppc.inc" |
|
|
47 |
|
|
48 #------------------------------------------------------------------------------ |
|
|
49 # function declaration macro |
|
|
50 |
|
|
51 #define FUNC_START(name) \ |
|
|
52 .type name,@function; \ |
|
|
53 .globl name; \ |
|
|
54 name: |
|
|
55 |
|
|
56 #------------------------------------------------------------------------------ |
|
|
57 # Configure to use either a minimal or maximal thread state |
|
|
58 |
|
|
59 #ifdef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM |
|
|
60 |
|
|
61 #define MIN_SAVE_REG 13 |
|
|
62 #define MAX_SAVE_REG 31 |
|
|
63 |
|
|
64 .macro save_special |
|
|
65 .endm |
|
|
66 |
|
|
67 .macro load_special |
|
|
68 .endm |
|
|
69 #else |
|
|
70 |
|
|
71 #define MIN_SAVE_REG 6 |
|
|
72 #define MAX_SAVE_REG 31 |
|
|
73 |
|
|
74 .macro save_special |
|
|
75 mfxer r6 |
|
|
76 mfctr r7 |
|
|
77 stw r6,ppcreg_xer(sp) |
|
|
78 stw r7,ppcreg_ctr(sp) |
|
|
79 .endm |
|
|
80 |
|
|
81 .macro load_special |
|
|
82 lwz r6,ppcreg_xer(sp) |
|
|
83 lwz r7,ppcreg_ctr(sp) |
|
|
84 mtxer r6 |
|
|
85 mtctr r7 |
|
|
86 .endm |
|
|
87 |
|
|
88 #endif |
|
|
89 |
|
|
90 #------------------------------------------------------------------------------ |
|
|
91 # hal_thread_switch_context |
|
|
92 # Switch thread contexts |
|
|
93 # R3 = address of sp of next thread to execute |
|
|
94 # R4 = address of sp save location of current thread |
|
|
95 |
|
|
96 |
|
|
97 FUNC_START(hal_thread_switch_context) |
|
|
98 mr r5,sp # R5 = saved stack pointer |
|
|
99 subi sp,sp,ppcreg_context_size # space for state |
|
|
100 |
|
|
101 # Save registers MIN..MAX |
|
|
102 .set _reg,MIN_SAVE_REG |
|
|
103 .rept MAX_SAVE_REG+1-MIN_SAVE_REG |
|
|
104 stw _reg,(ppcreg_regs+_reg*4)(sp) |
|
|
105 .set _reg,_reg+1 |
|
|
106 .endr |
|
|
107 |
|
|
108 stw r0,0(sp) # R0 |
|
|
109 stw r5,4(sp) # R5 = real SP, save in R1 slot |
|
|
110 stw r2,8(sp) # R2 = TOC |
|
|
111 |
|
|
112 # CR cannot be treated as a special register since GCC will only |
|
|
113 # do partial restore of CR at function exit, depending on which |
|
|
114 # of CR2, CR3, and CR4 have been used in the given function. |
|
|
115 mfcr r5 # save CR. |
|
|
116 stw r5,ppcreg_cr(sp) |
|
|
117 |
|
|
118 save_special # save special regs |
|
|
119 |
|
|
120 mflr r5 # save LR == return link for this fn |
|
|
121 stw r5,ppcreg_lr(sp) |
|
|
122 |
|
|
123 stw sp,0(r4) # save SP into save location |
|
|
124 |
|
|
125 # Now load the destination thread by dropping through |
|
|
126 # to hal_thread_load_context |
|
|
127 |
|
|
128 #------------------------------------------------------------------------------ |
|
|
129 # hal_thread_load_context |
|
|
130 # Load thread context |
|
|
131 # R3 = address of sp of next thread to execute |
|
|
132 # Note that this function is also the second half of hal_thread_switch_context |
|
|
133 # and is simply dropped into from it. |
|
|
134 |
|
|
135 FUNC_START(hal_thread_load_context) |
|
|
136 |
|
|
137 lwz sp,0(r3) # load state directly into SP |
|
|
138 |
|
|
139 load_special # load special registers |
|
|
140 |
|
|
141 lwz r5,ppcreg_cr(sp) # restore CR |
|
|
142 mtcr r5 |
|
|
143 |
|
|
144 lwz r5,ppcreg_lr(sp) # get LR as set as return link |
|
|
145 mtlr r5 |
|
|
146 |
|
|
147 # Load registers MIN..MAX |
|
|
148 .set _reg,MIN_SAVE_REG |
|
|
149 .rept MAX_SAVE_REG+1-MIN_SAVE_REG |
|
|
150 lwz _reg,(ppcreg_regs+_reg*4)(sp) |
|
|
151 .set _reg,_reg+1 |
|
|
152 .endr |
|
|
153 |
|
|
154 lwz r0,0(sp) # R0 |
|
|
155 lwz r2,8(sp) # R2 = TOC |
|
|
156 lwz r3,12(sp) # load r3 |
|
|
157 # lwz r4,16(sp) # load r4 |
|
|
158 # lwz r5,20(sp) # load r5 |
|
|
159 |
|
|
160 lwz sp,4(sp) # finally restore true SP |
|
|
161 |
|
|
162 blr # jump to LR |
|
|
163 |
|
|
164 #------------------------------------------------------------------------------ |
|
|
165 # HAL longjmp, setjmp implementations |
|
|
166 # hal_setjmp saves only to callee save registers 13-31, r1[sp],r2, cr[2-4] |
|
|
167 # and lr into buffer supplied in r3[arg0] |
|
|
168 |
|
|
169 FUNC_START(hal_setjmp) |
|
|
170 mfcr r5 |
|
|
171 stw r5,88(r3) |
|
|
172 mflr r5 |
|
|
173 stw r5,84(r3) |
|
|
174 stw r31,80(r3) |
|
|
175 stw r30,76(r3) |
|
|
176 stw r29,72(r3) |
|
|
177 stw r28,68(r3) |
|
|
178 stw r27,64(r3) |
|
|
179 stw r26,60(r3) |
|
|
180 stw r25,56(r3) |
|
|
181 stw r24,52(r3) |
|
|
182 stw r23,48(r3) |
|
|
183 stw r22,44(r3) |
|
|
184 stw r21,40(r3) |
|
|
185 stw r20,36(r3) |
|
|
186 stw r19,32(r3) |
|
|
187 stw r18,28(r3) |
|
|
188 stw r17,24(r3) |
|
|
189 stw r16,20(r3) |
|
|
190 stw r15,16(r3) |
|
|
191 stw r14,12(r3) |
|
|
192 stw r13,8(r3) |
|
|
193 stw r2,4(r3) # TOC, optimize out? |
|
|
194 stw sp,0(r3) |
|
|
195 li r3,0 # return 0 |
|
|
196 blr |
|
|
197 |
|
|
198 # hal_longjmp loads state from r3[arg0] and returns |
|
|
199 # and lr into buffer supplied in r3[arg0] |
|
|
200 |
|
|
201 FUNC_START(hal_longjmp) |
|
|
202 lwz r5,88(r3) |
|
|
203 mtcr r5 |
|
|
204 lwz r5,84(r3) |
|
|
205 mtlr r5 |
|
|
206 lwz r31,80(r3) |
|
|
207 lwz r30,76(r3) |
|
|
208 lwz r29,72(r3) |
|
|
209 lwz r28,68(r3) |
|
|
210 lwz r27,64(r3) |
|
|
211 lwz r26,60(r3) |
|
|
212 lwz r25,56(r3) |
|
|
213 lwz r24,52(r3) |
|
|
214 lwz r23,48(r3) |
|
|
215 lwz r22,44(r3) |
|
|
216 lwz r21,40(r3) |
|
|
217 lwz r20,36(r3) |
|
|
218 lwz r19,32(r3) |
|
|
219 lwz r18,28(r3) |
|
|
220 lwz r17,24(r3) |
|
|
221 lwz r16,20(r3) |
|
|
222 lwz r15,16(r3) |
|
|
223 lwz r14,12(r3) |
|
|
224 lwz r13,8(r3) |
|
|
225 lwz r2,4(r3) |
|
|
226 lwz sp,0(r3) |
|
|
227 mr r3,r4 # return r4[arg1] |
|
|
228 blr |
|
|
229 |
|
|
230 |
|
|
231 |
|
|
232 #------------------------------------------------------------------------------ |
|
|
233 # end of context.S |