1 |
27 |
unneback |
// #=============================================================================
|
2 |
|
|
// #
|
3 |
|
|
// # context.S
|
4 |
|
|
// #
|
5 |
|
|
// # NEC/V850 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: NEC/V850 context switch code
|
47 |
|
|
// # Description: This file contains implementations of the thread context
|
48 |
|
|
// # switch routines. It also contains the longjmp() and setjmp() routines.
|
49 |
|
|
// #
|
50 |
|
|
// #####DESCRIPTIONEND####
|
51 |
|
|
// #
|
52 |
|
|
// #=============================================================================
|
53 |
|
|
|
54 |
|
|
#include
|
55 |
|
|
|
56 |
|
|
#include
|
57 |
|
|
|
58 |
|
|
.text
|
59 |
|
|
|
60 |
|
|
// ------------------------------------------------------------------------------
|
61 |
|
|
// hal_thread_switch_context
|
62 |
|
|
// Switch thread contexts
|
63 |
|
|
// R6 = address of sp of next thread to execute
|
64 |
|
|
// R7 = address of sp save location of current thread
|
65 |
|
|
.globl __hal_thread_switch_context
|
66 |
|
|
__hal_thread_switch_context:
|
67 |
|
|
addi -CYGARC_EXCEPTION_FRAME_SIZE,sp,sp
|
68 |
|
|
st.w ep,CYGARC_REG_EP[sp]
|
69 |
|
|
mov sp,ep
|
70 |
|
|
sst.w r1,CYGARC_REG_R1[ep]
|
71 |
|
|
sst.w r2,CYGARC_REG_R2[ep]
|
72 |
|
|
addi CYGARC_EXCEPTION_FRAME_SIZE,ep,r1
|
73 |
|
|
sst.w r1,CYGARC_REG_SP[ep] // sp
|
74 |
|
|
sst.w r4,CYGARC_REG_R4[ep]
|
75 |
|
|
sst.w r5,CYGARC_REG_R5[ep]
|
76 |
|
|
sst.w r6,CYGARC_REG_R6[ep]
|
77 |
|
|
sst.w r7,CYGARC_REG_R7[ep]
|
78 |
|
|
sst.w r8,CYGARC_REG_R8[ep]
|
79 |
|
|
sst.w r9,CYGARC_REG_R9[ep]
|
80 |
|
|
sst.w r10,CYGARC_REG_R10[ep]
|
81 |
|
|
sst.w r11,CYGARC_REG_R11[ep]
|
82 |
|
|
sst.w r12,CYGARC_REG_R12[ep]
|
83 |
|
|
sst.w r13,CYGARC_REG_R13[ep]
|
84 |
|
|
sst.w r14,CYGARC_REG_R14[ep]
|
85 |
|
|
sst.w r15,CYGARC_REG_R15[ep]
|
86 |
|
|
sst.w r16,CYGARC_REG_R16[ep]
|
87 |
|
|
sst.w r17,CYGARC_REG_R17[ep]
|
88 |
|
|
sst.w r18,CYGARC_REG_R18[ep]
|
89 |
|
|
sst.w r19,CYGARC_REG_R19[ep]
|
90 |
|
|
sst.w r20,CYGARC_REG_R20[ep]
|
91 |
|
|
sst.w r21,CYGARC_REG_R21[ep]
|
92 |
|
|
sst.w r22,CYGARC_REG_R22[ep]
|
93 |
|
|
sst.w r23,CYGARC_REG_R23[ep]
|
94 |
|
|
sst.w r24,CYGARC_REG_R24[ep]
|
95 |
|
|
sst.w r25,CYGARC_REG_R25[ep]
|
96 |
|
|
sst.w r26,CYGARC_REG_R26[ep]
|
97 |
|
|
sst.w r27,CYGARC_REG_R27[ep]
|
98 |
|
|
sst.w r28,CYGARC_REG_R28[ep]
|
99 |
|
|
sst.w r29,CYGARC_REG_R29[ep]
|
100 |
|
|
sst.w lp,CYGARC_REG_LP[ep]
|
101 |
|
|
sst.w lp,CYGARC_REG_PC[ep]
|
102 |
|
|
stsr PSW,r1
|
103 |
|
|
st.w r1,CYGARC_REG_PSW[ep]
|
104 |
|
|
st.w sp,0[r7] // return new stack pointer
|
105 |
|
|
|
106 |
|
|
# Now load the destination thread by dropping through
|
107 |
|
|
# to hal_thread_load_context
|
108 |
|
|
// ------------------------------------------------------------------------------
|
109 |
|
|
// hal_thread_load_context
|
110 |
|
|
// Load thread context
|
111 |
|
|
// R6 = address of sp of next thread to execute
|
112 |
|
|
// Note that this function is also the second half of hal_thread_switch_context
|
113 |
|
|
// and is simply dropped into from it.
|
114 |
|
|
|
115 |
|
|
.globl __hal_thread_load_context
|
116 |
|
|
__hal_thread_load_context:
|
117 |
|
|
di // disable interrupts while updating state
|
118 |
|
|
ld.w 0[r6],ep // get pointer to saved state
|
119 |
|
|
ld.w CYGARC_REG_PSW[ep],r6
|
120 |
|
|
sld.w CYGARC_REG_LP[ep],r7
|
121 |
|
|
sld.w CYGARC_REG_R1[ep],r1 // restore volatile registers
|
122 |
|
|
sld.w CYGARC_REG_R2[ep],r2
|
123 |
|
|
ldsr r6,EIPSW // avoids pipline bubble
|
124 |
|
|
ldsr r7,EIPC
|
125 |
|
|
sld.w CYGARC_REG_R4[ep],r4
|
126 |
|
|
sld.w CYGARC_REG_R5[ep],r5
|
127 |
|
|
sld.w CYGARC_REG_R6[ep],r6
|
128 |
|
|
sld.w CYGARC_REG_R7[ep],r7
|
129 |
|
|
sld.w CYGARC_REG_R8[ep],r8
|
130 |
|
|
sld.w CYGARC_REG_R9[ep],r9
|
131 |
|
|
sld.w CYGARC_REG_R10[ep],r10
|
132 |
|
|
sld.w CYGARC_REG_R11[ep],r11
|
133 |
|
|
sld.w CYGARC_REG_R12[ep],r12
|
134 |
|
|
sld.w CYGARC_REG_R13[ep],r13
|
135 |
|
|
sld.w CYGARC_REG_R14[ep],r14
|
136 |
|
|
sld.w CYGARC_REG_R15[ep],r15
|
137 |
|
|
sld.w CYGARC_REG_R16[ep],r16
|
138 |
|
|
sld.w CYGARC_REG_R17[ep],r17
|
139 |
|
|
sld.w CYGARC_REG_R18[ep],r18
|
140 |
|
|
sld.w CYGARC_REG_R19[ep],r19
|
141 |
|
|
sld.w CYGARC_REG_R20[ep],r20
|
142 |
|
|
sld.w CYGARC_REG_R21[ep],r21
|
143 |
|
|
sld.w CYGARC_REG_R22[ep],r22
|
144 |
|
|
sld.w CYGARC_REG_R23[ep],r23
|
145 |
|
|
sld.w CYGARC_REG_R24[ep],r24
|
146 |
|
|
sld.w CYGARC_REG_R25[ep],r25
|
147 |
|
|
sld.w CYGARC_REG_R26[ep],r26
|
148 |
|
|
sld.w CYGARC_REG_R27[ep],r27
|
149 |
|
|
sld.w CYGARC_REG_R28[ep],r28
|
150 |
|
|
sld.w CYGARC_REG_R29[ep],r29
|
151 |
|
|
sld.w CYGARC_REG_LP[ep],lp
|
152 |
|
|
sld.w CYGARC_REG_SP[ep],sp
|
153 |
|
|
sld.w CYGARC_REG_EP[ep],ep
|
154 |
|
|
reti
|
155 |
|
|
|
156 |
|
|
// ------------------------------------------------------------------------------
|
157 |
|
|
// HAL longjmp, setjmp implementations
|
158 |
|
|
|
159 |
|
|
#define fp r29
|
160 |
|
|
|
161 |
|
|
.globl _hal_setjmp
|
162 |
|
|
_hal_setjmp:
|
163 |
|
|
st.w r1,CYGARC_JMPBUF_R1[r6]
|
164 |
|
|
st.w r2,CYGARC_JMPBUF_R2[r6]
|
165 |
|
|
st.w r4,CYGARC_JMPBUF_R4[r6]
|
166 |
|
|
st.w r5,CYGARC_JMPBUF_R5[r6]
|
167 |
|
|
st.w sp,CYGARC_JMPBUF_SP[r6]
|
168 |
|
|
st.w gp,CYGARC_JMPBUF_GP[r6]
|
169 |
|
|
st.w tp,CYGARC_JMPBUF_TP[r6]
|
170 |
|
|
st.w r20,CYGARC_JMPBUF_R20[r6]
|
171 |
|
|
st.w r21,CYGARC_JMPBUF_R21[r6]
|
172 |
|
|
st.w r22,CYGARC_JMPBUF_R22[r6]
|
173 |
|
|
st.w r23,CYGARC_JMPBUF_R23[r6]
|
174 |
|
|
st.w r24,CYGARC_JMPBUF_R24[r6]
|
175 |
|
|
st.w r25,CYGARC_JMPBUF_R25[r6]
|
176 |
|
|
st.w r26,CYGARC_JMPBUF_R26[r6]
|
177 |
|
|
st.w r27,CYGARC_JMPBUF_R27[r6]
|
178 |
|
|
st.w r28,CYGARC_JMPBUF_R28[r6]
|
179 |
|
|
st.w fp,CYGARC_JMPBUF_FP[r6]
|
180 |
|
|
st.w ep,CYGARC_JMPBUF_EP[r6]
|
181 |
|
|
st.w lp,CYGARC_JMPBUF_LP[r6]
|
182 |
|
|
mov r0,r10
|
183 |
|
|
jmp [lp]
|
184 |
|
|
|
185 |
|
|
// hal_longjmp loads state from [arg0] and returns arg1
|
186 |
|
|
|
187 |
|
|
.globl _hal_longjmp
|
188 |
|
|
_hal_longjmp:
|
189 |
|
|
ld.w CYGARC_JMPBUF_SP[r6],sp
|
190 |
|
|
ld.w CYGARC_JMPBUF_GP[r6],gp
|
191 |
|
|
ld.w CYGARC_JMPBUF_TP[r6],tp
|
192 |
|
|
ld.w CYGARC_JMPBUF_R1[r6],r1
|
193 |
|
|
ld.w CYGARC_JMPBUF_R2[r6],r2
|
194 |
|
|
ld.w CYGARC_JMPBUF_R4[r6],r4
|
195 |
|
|
ld.w CYGARC_JMPBUF_R5[r6],r5
|
196 |
|
|
ld.w CYGARC_JMPBUF_R20[r6],r20
|
197 |
|
|
ld.w CYGARC_JMPBUF_R21[r6],r21
|
198 |
|
|
ld.w CYGARC_JMPBUF_R22[r6],r22
|
199 |
|
|
ld.w CYGARC_JMPBUF_R23[r6],r23
|
200 |
|
|
ld.w CYGARC_JMPBUF_R24[r6],r24
|
201 |
|
|
ld.w CYGARC_JMPBUF_R25[r6],r25
|
202 |
|
|
ld.w CYGARC_JMPBUF_R26[r6],r26
|
203 |
|
|
ld.w CYGARC_JMPBUF_R27[r6],r27
|
204 |
|
|
ld.w CYGARC_JMPBUF_R28[r6],r28
|
205 |
|
|
ld.w CYGARC_JMPBUF_FP[r6],fp
|
206 |
|
|
ld.w CYGARC_JMPBUF_EP[r6],ep
|
207 |
|
|
ld.w CYGARC_JMPBUF_LP[r6],lp
|
208 |
|
|
mov r7,r10
|
209 |
|
|
jmp [lp]
|
210 |
|
|
|
211 |
|
|
// ------------------------------------------------------------------------------
|
212 |
|
|
// end of context.S
|
213 |
|
|
|
214 |
|
|
|