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
95 FUNC_START_ARM(hal_thread_switch_context, r2)
97 sub sp,sp,#(ARMREG_SIZE - armreg_lr - 4) // skip svc_sp, svc_lr, vector, cpsr, and pc
99 stmfd sp!,{r0-r10,fp,ip}
101 str r2,[sp,#armreg_cpsr]
102 str sp,[r1] // return new stack pointer
104 b hal_thread_load_context_ARM // skip mode switch stuff
107 # Now load the destination thread by dropping through
108 # to hal_thread_load_context
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.
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
122 ldr r0,[fp,#armreg_cpsr]
124 ldmfd fp,{r0-r10,fp,ip,sp,lr}
126 mrs r1,spsr // r1 is scratch
127 // [r0 holds initial thread arg]
128 msr cpsr,r1 // hopefully no mode switch here!
131 movs pc,lr // also restores saved PSR
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]
139 FUNC_START_ARM(hal_setjmp, r2)
148 // hal_longjmp loads state from r0[arg0] and returns
150 FUNC_START_ARM(hal_longjmp, r2)
152 mov r0,r1; # return [arg1]
159 // ----------------------------------------------------------------------------