]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/arch/v2_0/src/context.S
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / arch / v2_0 / src / context.S
1 // #===========================================================================
2 // #
3 // #    context.S
4 // #
5 // #    ARM context switch code
6 // #
7 // #===========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 // #===========================================================================
41 // ######DESCRIPTIONBEGIN####
42 // #
43 // # Author(s):    nickg, gthomas
44 // # Contributors: nickg, gthomas
45 // # Date:         1998-09-15
46 // # Purpose:      ARM context switch code
47 // # Description:  This file contains implementations of the thread context 
48 // #               switch routines. It also contains the longjmp() and setjmp()
49 // #               routines.
50 // #
51 // #####DESCRIPTIONEND####
52 // #
53 // #===========================================================================
54
55 #include <pkgconf/hal.h>
56
57 #include "arm.inc"
58
59         .text
60
61 // ----------------------------------------------------------------------------
62 //  function declaration macro (start body in ARM mode)
63                 
64 #ifdef __thumb__
65 #define FUNC_START_ARM(_name_, _r_)              \
66         .code   16                              ;\
67         .thumb_func                             ;\
68         .globl _name_                           ;\
69 _name_:                                         ;\
70         ldr     _r_,=_name_ ## _ARM             ;\
71         bx      _r_                             ;\
72         .code   32                              ;\
73 _name_ ## _ARM:
74
75 #else
76
77 #define FUNC_START_ARM(_name_, _r_) \
78         .globl _name_; \
79 _name_: 
80         
81 #endif
82         
83 // ----------------------------------------------------------------------------
84 //  hal_thread_switch_context
85 //  Switch thread contexts
86 //  R0 = address of sp of next thread to execute
87 //  R1 = address of sp save location of current thread
88
89 // Need to save/restore R4..R12, R13 (sp), R14 (lr)
90
91 // Note: this is a little wasteful since r0..r3 don't need to be saved.
92 // They are saved here though so that the information can match the HAL_SavedRegisters
93         
94 FUNC_START_ARM(hal_thread_switch_context, r2)
95         sub     ip,sp,#20               // skip svc_sp, svc_lr, vector, cpsr, and pc
96         stmfd   ip!,{sp,lr}
97         mov     sp,ip
98         stmfd   sp!,{r0-r10,fp,ip}
99         mrs     r2,cpsr
100         str     r2,[sp,#armreg_cpsr]
101         str     sp,[r1]                 // return new stack pointer
102 #ifdef __thumb__
103         b       hal_thread_load_context_ARM // skip mode switch stuff
104 #endif
105
106         # Now load the destination thread by dropping through
107         # to hal_thread_load_context
108         
109 // ----------------------------------------------------------------------------
110 //  hal_thread_load_context
111 //  Load thread context
112 //  R0 = address of sp of next thread to execute
113 //  Note that this function is also the second half of
114 //  hal_thread_switch_context and is simply dropped into from it.
115         
116 FUNC_START_ARM(hal_thread_load_context, r2)
117         ldr     fp,[r0]                 // get context to restore
118         mrs     r0,cpsr                 // disable IRQ's
119         orr     r0,r0,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE
120         msr     cpsr,r0
121         ldr     r0,[fp,#armreg_cpsr]
122         msr     spsr,r0
123         ldmfd   fp,{r0-r10,fp,ip,sp,lr}
124 #ifdef __thumb__
125         mrs     r1,spsr                 // r1 is scratch 
126                                         // [r0 holds initial thread arg]
127         msr     cpsr,r1                 // hopefully no mode switch here!
128         bx      lr
129 #else
130         movs    pc,lr                   // also restores saved PSR
131 #endif
132
133 // ----------------------------------------------------------------------------
134 //  HAL longjmp, setjmp implementations
135 //  hal_setjmp saves only to callee save registers 4-14
136 //  and lr into buffer supplied in r0[arg0]
137
138 FUNC_START_ARM(hal_setjmp, r2)
139         stmea   r0,{r4-r14}
140         mov     r0,#0
141 #ifdef __thumb__
142         bx      lr
143 #else
144         mov     pc,lr;          # return
145 #endif
146
147 //  hal_longjmp loads state from r0[arg0] and returns
148         
149 FUNC_START_ARM(hal_longjmp, r2)
150         ldmfd   r0,{r4-r14}
151         mov     r0,r1;          # return [arg1]
152 #ifdef __thumb__
153         bx      lr
154 #else
155         mov     pc,lr
156 #endif
157
158 // ----------------------------------------------------------------------------
159 //  end of context.S