]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/arch/v2_0/src/context.S
unified MX27, MX25, MX37 trees
[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
93 // HAL_SavedRegisters
94         
95 FUNC_START_ARM(hal_thread_switch_context, r2)
96         mov     ip,sp
97         sub     sp,sp,#(ARMREG_SIZE - armreg_lr - 4) // skip svc_sp, svc_lr, vector, cpsr, and pc
98         stmfd   sp!,{ip,lr}
99         stmfd   sp!,{r0-r10,fp,ip}
100         mrs     r2,cpsr
101         str     r2,[sp,#armreg_cpsr]
102         str     sp,[r1]                 // return new stack pointer
103 #ifdef __thumb__
104         b       hal_thread_load_context_ARM // skip mode switch stuff
105 #endif
106
107         # Now load the destination thread by dropping through
108         # to hal_thread_load_context
109         
110 // ----------------------------------------------------------------------------
111 //  hal_thread_load_context
112 //  Load thread context
113 //  R0 = address of sp of next thread to execute
114 //  Note that this function is also the second half of
115 //  hal_thread_switch_context and is simply dropped into from it.
116         
117 FUNC_START_ARM(hal_thread_load_context, r2)
118         ldr     fp,[r0]                 // get context to restore
119         mrs     r0,cpsr                 // disable IRQ's
120         orr     r0,r0,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE
121         msr     cpsr,r0
122         ldr     r0,[fp,#armreg_cpsr]
123         msr     spsr,r0
124         ldmfd   fp,{r0-r10,fp,ip,sp,lr}
125 #ifdef __thumb__
126         mrs     r1,spsr                 // r1 is scratch 
127                                         // [r0 holds initial thread arg]
128         msr     cpsr,r1                 // hopefully no mode switch here!
129         bx      lr
130 #else
131         movs    pc,lr                   // also restores saved PSR
132 #endif
133
134 // ----------------------------------------------------------------------------
135 //  HAL longjmp, setjmp implementations
136 //  hal_setjmp saves only to callee save registers 4-14
137 //  and lr into buffer supplied in r0[arg0]
138
139 FUNC_START_ARM(hal_setjmp, r2)
140         stmea   r0,{r4-r14}
141         mov     r0,#0
142 #ifdef __thumb__
143         bx      lr
144 #else
145         mov     pc,lr;          # return
146 #endif
147
148 //  hal_longjmp loads state from r0[arg0] and returns
149         
150 FUNC_START_ARM(hal_longjmp, r2)
151         ldmfd   r0,{r4-r14}
152         mov     r0,r1;          # return [arg1]
153 #ifdef __thumb__
154         bx      lr
155 #else
156         mov     pc,lr
157 #endif
158
159 // ----------------------------------------------------------------------------
160 //  end of context.S