]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/openrisc/arch/v2_0/src/context.S
Initial revision
[karo-tx-redboot.git] / packages / hal / openrisc / arch / v2_0 / src / context.S
1 ##=============================================================================##
2 ##      context.S
3 ##
4 ##      OpenRISC context switch code
5 ##
6 ##=============================================================================
7 #####ECOSGPLCOPYRIGHTBEGIN####
8 ## -------------------------------------------
9 ## This file is part of eCos, the Embedded Configurable Operating System.
10 ## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
11 ##
12 ## eCos is free software; you can redistribute it and/or modify it under
13 ## the terms of the GNU General Public License as published by the Free
14 ## Software Foundation; either version 2 or (at your option) any later version.
15 ##
16 ## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
17 ## WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 ## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19 ## for more details.
20 ##
21 ## You should have received a copy of the GNU General Public License along
22 ## with eCos; if not, write to the Free Software Foundation, Inc.,
23 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24 ##
25 ## As a special exception, if other files instantiate templates or use macros
26 ## or inline functions from this file, or you compile this file and link it
27 ## with other works to produce a work based on this file, this file does not
28 ## by itself cause the resulting work to be covered by the GNU General Public
29 ## License. However the source code for this file must still be made available
30 ## in accordance with section (3) of the GNU General Public License.
31 ##
32 ## This exception does not invalidate any other reasons why a work based on
33 ## this file might be covered by the GNU General Public License.
34 ##
35 ## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
36 ## at http://sources.redhat.com/ecos/ecos-license/
37 ## -------------------------------------------
38 #####ECOSGPLCOPYRIGHTEND####
39 ##=============================================================================
40 #######DESCRIPTIONBEGIN####
41 ##
42 ## Author(s):   Scott Furman
43 ## Contributors:
44 ## Date:        2003-01-21
45 ## Purpose:     OpenRISC context switch code
46 ## Description: This file contains implementations of the thread context 
47 ##              switch routines. It also contains the longjmp() and setjmp()
48 ##              routines.
49 ##
50 ######DESCRIPTIONEND####
51 ##
52 ##=============================================================================
53
54 #include <pkgconf/hal.h>
55
56 #include <cyg/hal/arch.inc>
57 #include <cyg/hal/openrisc.inc>
58
59
60
61 #------------------------------------------------------------------------------
62 # hal_thread_switch_context()
63 # Switch thread contexts
64 # R3 = address of sp of next thread to execute
65 # R4 = address of sp save location of current thread
66
67 FUNC_START(hal_thread_switch_context)
68         l.addi  sp,sp,-SIZEOF_OR1KREGS  # space for registers
69
70         # Store General Purpose Registers (GPRs).
71         l.sw     2 * OR1K_GPRSIZE(sp), r2
72         l.sw     9 * OR1K_GPRSIZE(sp), r9
73         l.sw    10 * OR1K_GPRSIZE(sp), r10
74         l.sw    12 * OR1K_GPRSIZE(sp), r12
75         l.sw    14 * OR1K_GPRSIZE(sp), r14
76         l.sw    16 * OR1K_GPRSIZE(sp), r16
77         l.sw    18 * OR1K_GPRSIZE(sp), r18
78         l.sw    20 * OR1K_GPRSIZE(sp), r20
79         l.sw    22 * OR1K_GPRSIZE(sp), r22
80         l.sw    24 * OR1K_GPRSIZE(sp), r24
81         l.sw    26 * OR1K_GPRSIZE(sp), r26
82         l.sw    28 * OR1K_GPRSIZE(sp), r28
83         l.sw    30 * OR1K_GPRSIZE(sp), r30
84
85 #ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
86         
87         # R0 is not typically stored because it is always zero-valued,
88         # but we store it here for consistency when examining registers
89         # in the debugger.
90         l.sw     0 * OR1K_GPRSIZE(sp), r0
91
92         # Caller-saved regs don't need to be preserved across
93         # context switches, but we do so to make debugging easier.
94
95         l.sw     3 * OR1K_GPRSIZE(sp), r3
96         l.sw     4 * OR1K_GPRSIZE(sp), r4
97         l.sw     5 * OR1K_GPRSIZE(sp), r5
98         l.sw     6 * OR1K_GPRSIZE(sp), r6
99         l.sw     7 * OR1K_GPRSIZE(sp), r7
100         l.sw     8 * OR1K_GPRSIZE(sp), r8
101         l.sw    11 * OR1K_GPRSIZE(sp), r11
102         l.sw    13 * OR1K_GPRSIZE(sp), r13
103         l.sw    15 * OR1K_GPRSIZE(sp), r15
104         l.sw    17 * OR1K_GPRSIZE(sp), r17
105         l.sw    19 * OR1K_GPRSIZE(sp), r19
106         l.sw    21 * OR1K_GPRSIZE(sp), r21
107         l.sw    23 * OR1K_GPRSIZE(sp), r23
108         l.sw    25 * OR1K_GPRSIZE(sp), r25
109         l.sw    27 * OR1K_GPRSIZE(sp), r27
110         l.sw    29 * OR1K_GPRSIZE(sp), r29
111         l.sw    31 * OR1K_GPRSIZE(sp), r31
112
113         # save MAC LO and HI regs
114         l.mfspr r5,r0,SPR_MACLO
115         l.sw    OR1KREG_MACLO(sp),r5
116         l.mfspr r5,r0,SPR_MACHI
117         l.sw    OR1KREG_MACHI(sp),r5
118         
119 #endif
120
121 #ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
122         # Make the thread context look like an exception context if thread-
123         # aware debugging is required. This state does not need restoring.
124         l.sw    OR1KREG_PC(sp),r9
125 #endif
126
127         l.addi  r5,sp,SIZEOF_OR1KREGS           # save SP in reg dump
128         l.sw     1 * OR1K_GPRSIZE(sp), r5
129
130         l.mfspr  r5,r0,SPR_SR                   # save SR in reg dump
131         l.sw     OR1KREG_SR(sp), r5
132
133         # Return resulting new SP to caller via second argument
134         l.sw     0(r4), sp
135
136         # Now load the destination thread by dropping through
137         # to hal_thread_load_context...
138 FUNC_END(hal_thread_switch_context)
139
140                 
141 #------------------------------------------------------------------------------
142 # hal_thread_load_context()
143 # Load thread context
144 # R3 = address of sp of next thread to execute
145 # Note that this function is also the second half of hal_thread_switch_context()
146 # and is simply dropped into from it.
147         
148 FUNC_START(hal_thread_load_context)
149
150         # Copy R3 to SP         
151         l.lwz   sp, 0(r3)
152
153         # Restore General Purpose Registers (GPRs).
154         # R0 is not restored because it is always zero-valued.
155         l.lwz   r2,   2 * OR1K_GPRSIZE(sp)
156         l.lwz   r9,   9 * OR1K_GPRSIZE(sp)
157         l.lwz   r10, 10 * OR1K_GPRSIZE(sp)
158         l.lwz   r12, 12 * OR1K_GPRSIZE(sp)
159         l.lwz   r14, 14 * OR1K_GPRSIZE(sp)
160         l.lwz   r16, 16 * OR1K_GPRSIZE(sp)
161         l.lwz   r18, 18 * OR1K_GPRSIZE(sp)
162         l.lwz   r20, 20 * OR1K_GPRSIZE(sp)
163         l.lwz   r22, 22 * OR1K_GPRSIZE(sp)
164         l.lwz   r24, 24 * OR1K_GPRSIZE(sp)
165         l.lwz   r26, 26 * OR1K_GPRSIZE(sp)
166         l.lwz   r28, 28 * OR1K_GPRSIZE(sp)
167         l.lwz   r30, 30 * OR1K_GPRSIZE(sp)
168
169         # Merge interrupt-enable state of new thread into
170         # current SR
171         load32i r5,~(SPR_SR_TEE|SPR_SR_IEE)
172         l.mfspr r6, r0, SPR_SR
173         l.and   r6, r5, r6
174         l.lwz   r5,  OR1KREG_SR(sp)
175         l.andi  r5, r5, (SPR_SR_TEE|SPR_SR_IEE)
176         l.or    r5, r5, r6
177         l.mtspr r0, r5, SPR_SR
178
179 #ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
180
181         # Caller-saved regs don't need to be preserved across
182         # context switches, but we do so here to make debugging
183         # easier.
184
185         # Restore MAC LO and HI regs
186         l.lwz   r5, OR1KREG_MACLO(sp)
187         l.mtspr r0,r5,SPR_MACLO
188         l.lwz   r5, OR1KREG_MACHI(sp)
189         l.mtspr r0,r5,SPR_MACHI
190
191         l.lwz    r4,  4 * OR1K_GPRSIZE(sp)
192         l.lwz    r5,  5 * OR1K_GPRSIZE(sp)
193         l.lwz    r6,  6 * OR1K_GPRSIZE(sp)
194         l.lwz    r7,  7 * OR1K_GPRSIZE(sp)
195         l.lwz    r8,  8 * OR1K_GPRSIZE(sp)
196         l.lwz   r11, 11 * OR1K_GPRSIZE(sp)
197         l.lwz   r13, 13 * OR1K_GPRSIZE(sp)
198         l.lwz   r15, 15 * OR1K_GPRSIZE(sp)
199         l.lwz   r17, 17 * OR1K_GPRSIZE(sp)
200         l.lwz   r19, 19 * OR1K_GPRSIZE(sp)
201         l.lwz   r21, 21 * OR1K_GPRSIZE(sp)
202         l.lwz   r23, 23 * OR1K_GPRSIZE(sp)
203         l.lwz   r25, 25 * OR1K_GPRSIZE(sp)
204         l.lwz   r27, 27 * OR1K_GPRSIZE(sp)
205         l.lwz   r29, 29 * OR1K_GPRSIZE(sp)
206         l.lwz   r31, 31 * OR1K_GPRSIZE(sp)
207
208 #endif
209
210         # If this is the first time we're running a thread, R3
211         # contains the argument to the thread entry point function,
212         # So we always have to restore it even though it's a callee-saved
213         # register.
214         l.lwz    r3,  3 * OR1K_GPRSIZE(sp)
215
216         # Finally, restore target thread's true SP
217         l.lwz   sp,   1 * OR1K_GPRSIZE(sp)
218
219         l.jr    lr
220         l.nop                                   # delay slot - must be nop
221
222 FUNC_END(hal_thread_load_context)
223         
224 #------------------------------------------------------------------------------
225 # HAL longjmp, setjmp implementations
226 # hal_setjmp saves only callee-saved registers into buffer supplied in r3:
227 #       1,2,9,10,13,15,17,19,21,23,25,27,29,31
228 # Note: These definitions are repeated in hal_arch.h. If changes are required
229 # remember to update both sets.
230
231 #define CYGARC_JMP_BUF_R1        0
232 #define CYGARC_JMP_BUF_R2        1
233 #define CYGARC_JMP_BUF_R9        2
234 #define CYGARC_JMP_BUF_R10       3
235 #define CYGARC_JMP_BUF_R12       4
236 #define CYGARC_JMP_BUF_R14       5
237 #define CYGARC_JMP_BUF_R16       6
238 #define CYGARC_JMP_BUF_R18       7
239 #define CYGARC_JMP_BUF_R20       8
240 #define CYGARC_JMP_BUF_R22       9
241 #define CYGARC_JMP_BUF_R24      10
242 #define CYGARC_JMP_BUF_R26      11
243 #define CYGARC_JMP_BUF_R28      12
244 #define CYGARC_JMP_BUF_R30      13
245
246 #define CYGARC_JMP_BUF_SIZE     14
247
248 #define jmpbuf_regsize 4
249
250 FUNC_START(hal_setjmp)
251         # Store General Purpose Registers (GPRs).
252         # R0 is not stored because it is always zero-valued.
253         # Caller-saved registers are not stored
254         l.sw    CYGARC_JMP_BUF_R1  * OR1K_GPRSIZE(r3), r1
255         l.sw    CYGARC_JMP_BUF_R2  * OR1K_GPRSIZE(r3), r2
256         l.sw    CYGARC_JMP_BUF_R9  * OR1K_GPRSIZE(r3), r9
257         l.sw    CYGARC_JMP_BUF_R10 * OR1K_GPRSIZE(r3), r10
258         l.sw    CYGARC_JMP_BUF_R12 * OR1K_GPRSIZE(r3), r12
259         l.sw    CYGARC_JMP_BUF_R14 * OR1K_GPRSIZE(r3), r14
260         l.sw    CYGARC_JMP_BUF_R16 * OR1K_GPRSIZE(r3), r16
261         l.sw    CYGARC_JMP_BUF_R18 * OR1K_GPRSIZE(r3), r18
262         l.sw    CYGARC_JMP_BUF_R20 * OR1K_GPRSIZE(r3), r20
263         l.sw    CYGARC_JMP_BUF_R22 * OR1K_GPRSIZE(r3), r22
264         l.sw    CYGARC_JMP_BUF_R24 * OR1K_GPRSIZE(r3), r24
265         l.sw    CYGARC_JMP_BUF_R26 * OR1K_GPRSIZE(r3), r26
266         l.sw    CYGARC_JMP_BUF_R28 * OR1K_GPRSIZE(r3), r28
267         l.sw    CYGARC_JMP_BUF_R30 * OR1K_GPRSIZE(r3), r30
268         l.jr    lr
269         l.nop                   # delay slot
270 FUNC_END(hal_setjmp)
271
272
273 FUNC_START(hal_longjmp)
274         l.lwz    r1, CYGARC_JMP_BUF_R1  * OR1K_GPRSIZE(r3)
275         l.lwz    r2, CYGARC_JMP_BUF_R2  * OR1K_GPRSIZE(r3)
276         l.lwz    r9, CYGARC_JMP_BUF_R9  * OR1K_GPRSIZE(r3)
277         l.lwz   r10, CYGARC_JMP_BUF_R10 * OR1K_GPRSIZE(r3)
278         l.lwz   r12, CYGARC_JMP_BUF_R12 * OR1K_GPRSIZE(r3)
279         l.lwz   r14, CYGARC_JMP_BUF_R14 * OR1K_GPRSIZE(r3)
280         l.lwz   r16, CYGARC_JMP_BUF_R16 * OR1K_GPRSIZE(r3)
281         l.lwz   r18, CYGARC_JMP_BUF_R18 * OR1K_GPRSIZE(r3)
282         l.lwz   r20, CYGARC_JMP_BUF_R20 * OR1K_GPRSIZE(r3)
283         l.lwz   r22, CYGARC_JMP_BUF_R22 * OR1K_GPRSIZE(r3)
284         l.lwz   r24, CYGARC_JMP_BUF_R24 * OR1K_GPRSIZE(r3)
285         l.lwz   r26, CYGARC_JMP_BUF_R26 * OR1K_GPRSIZE(r3)
286         l.lwz   r28, CYGARC_JMP_BUF_R28 * OR1K_GPRSIZE(r3)
287         l.lwz   r30, CYGARC_JMP_BUF_R30 * OR1K_GPRSIZE(r3)
288
289         l.jr    lr
290         l.nop                   # delay slot
291 FUNC_END(hal_longjmp)
292         
293
294 #------------------------------------------------------------------------------
295 # end of context.S