1 // #===========================================================================
5 // # ARM context switch code
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.
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.
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
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.
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.
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.
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####
43 // # Author(s): nickg, gthomas
44 // # Contributors: nickg, gthomas
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()
51 // #####DESCRIPTIONEND####
53 // #===========================================================================
55 #include <pkgconf/hal.h>
61 // ----------------------------------------------------------------------------
62 // function declaration macro (start body in ARM mode)
65 #define FUNC_START_ARM(_name_, _r_) \
70 ldr _r_,=_name_ ## _ARM ;\
77 #define FUNC_START_ARM(_name_, _r_) \
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
89 // Need to save/restore R4..R12, R13 (sp), R14 (lr)
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
94 FUNC_START_ARM(hal_thread_switch_context, r2)
95 sub ip,sp,#20 // skip svc_sp, svc_lr, vector, cpsr, and pc
98 stmfd sp!,{r0-r10,fp,ip}
100 str r2,[sp,#armreg_cpsr]
101 str sp,[r1] // return new stack pointer
103 b hal_thread_load_context_ARM // skip mode switch stuff
106 # Now load the destination thread by dropping through
107 # to hal_thread_load_context
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.
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
121 ldr r0,[fp,#armreg_cpsr]
123 ldmfd fp,{r0-r10,fp,ip,sp,lr}
125 mrs r1,spsr // r1 is scratch
126 // [r0 holds initial thread arg]
127 msr cpsr,r1 // hopefully no mode switch here!
130 movs pc,lr // also restores saved PSR
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]
138 FUNC_START_ARM(hal_setjmp, r2)
147 // hal_longjmp loads state from r0[arg0] and returns
149 FUNC_START_ARM(hal_longjmp, r2)
151 mov r0,r1; # return [arg1]
158 // ----------------------------------------------------------------------------