|
0
|
1 ##=============================================================================## |
|
|
2 ## context.S |
|
|
3 ## |
|
|
4 ## MIPS context switch code |
|
|
5 ## |
|
|
6 ##============================================================================= |
|
|
7 #####COPYRIGHTBEGIN#### |
|
|
8 # |
|
|
9 # ------------------------------------------- |
|
|
10 # The contents of this file are subject to the Cygnus eCos Public License |
|
|
11 # Version 1.0 (the "License"); you may not use this file except in |
|
|
12 # compliance with the License. You may obtain a copy of the License at |
|
|
13 # http://sourceware.cygnus.com/ecos |
|
|
14 # |
|
|
15 # Software distributed under the License is distributed on an "AS IS" |
|
|
16 # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
|
17 # License for the specific language governing rights and limitations under |
|
|
18 # the License. |
|
|
19 # |
|
|
20 # The Original Code is eCos - Embedded Cygnus Operating System, released |
|
|
21 # September 30, 1998. |
|
|
22 # |
|
|
23 # The Initial Developer of the Original Code is Cygnus. Portions created |
|
|
24 # by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. |
|
|
25 # ------------------------------------------- |
|
|
26 # |
|
|
27 #####COPYRIGHTEND#### |
|
|
28 ##============================================================================= |
|
|
29 #######DESCRIPTIONBEGIN#### |
|
|
30 ## |
|
|
31 ## Author(s): nickg |
|
|
32 ## Contributors: nickg |
|
|
33 ## Date: 1998-04-27 |
|
|
34 ## Purpose: MIPS context switch code |
|
|
35 ## Description: This file contains implementations of the thread context |
|
|
36 ## switch routines. It also contains the longjmp() and setjmp() |
|
|
37 ## routines. |
|
|
38 ## |
|
|
39 ######DESCRIPTIONEND#### |
|
|
40 ## |
|
|
41 ##============================================================================= |
|
|
42 |
|
|
43 #include <pkgconf/hal.h> |
|
|
44 |
|
|
45 #include <cyg/hal/mips.inc> |
|
|
46 |
|
|
47 .set noat |
|
|
48 |
|
|
49 #------------------------------------------------------------------------------ |
|
|
50 # hal_thread_switch_context |
|
|
51 # Switch thread contexts |
|
|
52 # A0 = address of sp of next thread to execute |
|
|
53 # A1 = address of sp save location of current thread |
|
|
54 |
|
|
55 .global hal_thread_switch_context |
|
|
56 hal_thread_switch_context: |
|
|
57 |
|
|
58 addi sp,sp,-mipsreg_size # space for registers |
|
|
59 |
|
|
60 # store GPRs |
|
|
61 #ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM |
|
|
62 sw $0,(mipsreg_regs+0*4)(sp) |
|
|
63 sw $1,(mipsreg_regs+1*4)(sp) |
|
|
64 sw $2,(mipsreg_regs+2*4)(sp) |
|
|
65 sw $3,(mipsreg_regs+3*4)(sp) |
|
|
66 sw $4,(mipsreg_regs+4*4)(sp) |
|
|
67 sw $5,(mipsreg_regs+5*4)(sp) |
|
|
68 sw $6,(mipsreg_regs+6*4)(sp) |
|
|
69 sw $7,(mipsreg_regs+7*4)(sp) |
|
|
70 sw $8,(mipsreg_regs+8*4)(sp) |
|
|
71 sw $9,(mipsreg_regs+9*4)(sp) |
|
|
72 sw $10,(mipsreg_regs+10*4)(sp) |
|
|
73 sw $11,(mipsreg_regs+11*4)(sp) |
|
|
74 sw $12,(mipsreg_regs+12*4)(sp) |
|
|
75 sw $13,(mipsreg_regs+13*4)(sp) |
|
|
76 sw $14,(mipsreg_regs+14*4)(sp) |
|
|
77 sw $15,(mipsreg_regs+15*4)(sp) |
|
|
78 sw $24,(mipsreg_regs+24*4)(sp) |
|
|
79 sw $25,(mipsreg_regs+25*4)(sp) |
|
|
80 sw $28,(mipsreg_regs+28*4)(sp) # == GP |
|
|
81 #endif |
|
|
82 sw $16,(mipsreg_regs+16*4)(sp) |
|
|
83 sw $17,(mipsreg_regs+17*4)(sp) |
|
|
84 sw $18,(mipsreg_regs+18*4)(sp) |
|
|
85 sw $19,(mipsreg_regs+19*4)(sp) |
|
|
86 sw $20,(mipsreg_regs+20*4)(sp) |
|
|
87 sw $21,(mipsreg_regs+21*4)(sp) |
|
|
88 sw $22,(mipsreg_regs+22*4)(sp) |
|
|
89 sw $23,(mipsreg_regs+23*4)(sp) |
|
|
90 # sw $26,(mipsreg_regs+26*4)(sp) # == K0 |
|
|
91 # sw $27,(mipsreg_regs+27*4)(sp) # == K1 |
|
|
92 # sw $29,(mipsreg_regs+29*4)(sp) # == SP |
|
|
93 sw $30,(mipsreg_regs+30*4)(sp) # == FP |
|
|
94 sw $31,(mipsreg_regs+31*4)(sp) # == RA |
|
|
95 sw $31,(mipsreg_pc)(sp) # == PC (to help with debugging) |
|
|
96 |
|
|
97 #ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM |
|
|
98 |
|
|
99 mflo t0 # save LO and HI regs |
|
|
100 mfhi t1 |
|
|
101 sw t0,mipsreg_lo(sp) |
|
|
102 sw t1,mipsreg_hi(sp) |
|
|
103 |
|
|
104 #endif |
|
|
105 |
|
|
106 addi t0,sp,mipsreg_size # save SP in reg dump |
|
|
107 sw t0,(mipsreg_regs+29*4)(sp) |
|
|
108 |
|
|
109 sw sp,0(a1) # save sp in save loc |
|
|
110 |
|
|
111 # Now load the destination thread by dropping through |
|
|
112 # to hal_thread_load_context |
|
|
113 |
|
|
114 #------------------------------------------------------------------------------ |
|
|
115 # hal_thread_load_context |
|
|
116 # Load thread context |
|
|
117 # A0 = address of sp of next thread to execute |
|
|
118 # Note that this function is also the second half of hal_thread_switch_context |
|
|
119 # and is simply dropped into from it. |
|
|
120 |
|
|
121 .global hal_thread_load_context |
|
|
122 hal_thread_load_context: |
|
|
123 |
|
|
124 lw sp,0(a0) # load new SP directly |
|
|
125 |
|
|
126 #ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM |
|
|
127 |
|
|
128 lw t0,mipsreg_hi(sp) # load HI and LO regs |
|
|
129 lw t1,mipsreg_lo(sp) |
|
|
130 mthi t0 |
|
|
131 mtlo t1 |
|
|
132 |
|
|
133 #endif |
|
|
134 |
|
|
135 # load GPRs |
|
|
136 # lw $0,(mipsreg_regs+0*4)(sp) |
|
|
137 lw $4,(mipsreg_regs+4*4)(sp) # A0, must load for thread startup |
|
|
138 #ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM |
|
|
139 lw $1,(mipsreg_regs+1*4)(sp) |
|
|
140 lw $2,(mipsreg_regs+2*4)(sp) |
|
|
141 lw $3,(mipsreg_regs+3*4)(sp) |
|
|
142 lw $5,(mipsreg_regs+5*4)(sp) |
|
|
143 lw $6,(mipsreg_regs+6*4)(sp) |
|
|
144 lw $7,(mipsreg_regs+7*4)(sp) |
|
|
145 lw $8,(mipsreg_regs+8*4)(sp) |
|
|
146 lw $9,(mipsreg_regs+9*4)(sp) |
|
|
147 lw $10,(mipsreg_regs+10*4)(sp) |
|
|
148 lw $11,(mipsreg_regs+11*4)(sp) |
|
|
149 lw $12,(mipsreg_regs+12*4)(sp) |
|
|
150 lw $13,(mipsreg_regs+13*4)(sp) |
|
|
151 lw $14,(mipsreg_regs+14*4)(sp) |
|
|
152 lw $15,(mipsreg_regs+15*4)(sp) |
|
|
153 lw $24,(mipsreg_regs+24*4)(sp) |
|
|
154 lw $25,(mipsreg_regs+25*4)(sp) |
|
|
155 #endif |
|
|
156 lw $16,(mipsreg_regs+16*4)(sp) |
|
|
157 lw $17,(mipsreg_regs+17*4)(sp) |
|
|
158 lw $18,(mipsreg_regs+18*4)(sp) |
|
|
159 lw $19,(mipsreg_regs+19*4)(sp) |
|
|
160 lw $20,(mipsreg_regs+20*4)(sp) |
|
|
161 lw $21,(mipsreg_regs+21*4)(sp) |
|
|
162 lw $22,(mipsreg_regs+22*4)(sp) |
|
|
163 lw $23,(mipsreg_regs+23*4)(sp) |
|
|
164 # lw $26,(mipsreg_regs+26*4)(sp) # == K0 |
|
|
165 # lw $27,(mipsreg_regs+27*4)(sp) # == K1 |
|
|
166 # lw $28,(mipsreg_regs+28*4)(sp) # == GP |
|
|
167 # lw $29,(mipsreg_regs+29*4)(sp) # == SP |
|
|
168 lw $30,(mipsreg_regs+30*4)(sp) # == FP |
|
|
169 lw $31,(mipsreg_regs+31*4)(sp) # == RA |
|
|
170 |
|
|
171 # Note that the following lw must go here and not |
|
|
172 # in the jr delay slot, since it has a delay slot |
|
|
173 # of its own. |
|
|
174 lw sp,(mipsreg_regs+29*4)(sp) # load SP |
|
|
175 jr ra # return via ra |
|
|
176 nop # delay slot - must be nop |
|
|
177 |
|
|
178 #------------------------------------------------------------------------------ |
|
|
179 # HAL longjmp, setjmp implementations |
|
|
180 # hal_setjmp saves only to callee save registers 13-31, r1[sp],r2 |
|
|
181 # and lr into buffer supplied in r3[arg0] |
|
|
182 |
|
|
183 .globl hal_setjmp |
|
|
184 .ent hal_setjmp |
|
|
185 hal_setjmp: |
|
|
186 sw $31,44(a0) # ra (link) |
|
|
187 sw $30,40(a0) |
|
|
188 sw $28,36(a0) # gp, optimize out? |
|
|
189 sw $23,32(a0) |
|
|
190 sw $22,28(a0) |
|
|
191 sw $21,24(a0) |
|
|
192 sw $20,20(a0) |
|
|
193 sw $19,16(a0) |
|
|
194 sw $18,12(a0) |
|
|
195 sw $17,8(a0) |
|
|
196 sw $16,4(a0) |
|
|
197 sw sp,0(a0) # $29 |
|
|
198 li v0,0 |
|
|
199 jr ra |
|
|
200 nop # delay slot |
|
|
201 .end hal_setjmp |
|
|
202 |
|
|
203 .globl hal_longjmp |
|
|
204 .ent hal_longjmp |
|
|
205 hal_longjmp: |
|
|
206 lw $31,44(a0) # ra (link) |
|
|
207 lw $30,40(a0) |
|
|
208 lw $28,36(a0) # gp, optimize out? |
|
|
209 lw $23,32(a0) |
|
|
210 lw $22,28(a0) |
|
|
211 lw $21,24(a0) |
|
|
212 lw $20,20(a0) |
|
|
213 lw $19,16(a0) |
|
|
214 lw $18,12(a0) |
|
|
215 lw $17,8(a0) |
|
|
216 lw $16,4(a0) |
|
|
217 lw sp,0(a0) # $29 |
|
|
218 move v0,a1 |
|
|
219 jr ra |
|
|
220 nop # delay slot |
|
|
221 .end hal_longjmp |
|
|
222 |
|
|
223 |
|
|
224 #------------------------------------------------------------------------------ |
|
|
225 # end of context.S |
|
|
226 |
|
|
227 |