blackfin architecture
[safe/jmp/linux-2.6] / include / asm-blackfin / mach-common / context.S
1 /*
2  * File:         arch/blackfin/kernel/context.S
3  * Based on:
4  * Author:
5  *
6  * Created:
7  * Description:
8  *
9  * Modified:
10  *               Copyright 2004-2007 Analog Devices Inc.
11  *
12  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, see the file COPYING, or write
26  * to the Free Software Foundation, Inc.,
27  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28  */
29
30 /*
31  * Code to save processor context.
32  *  We even save the register which are preserved by a function call
33  *       - r4, r5, r6, r7, p3, p4, p5
34  */
35 .macro save_context_with_interrupts
36         [--sp] = SYSCFG;
37
38         [--sp] = P0;    /*orig_p0*/
39         [--sp] = R0;    /*orig_r0*/
40
41         [--sp] = ( R7:0, P5:0 );
42         [--sp] = fp;
43         [--sp] = usp;
44
45         [--sp] = i0;
46         [--sp] = i1;
47         [--sp] = i2;
48         [--sp] = i3;
49
50         [--sp] = m0;
51         [--sp] = m1;
52         [--sp] = m2;
53         [--sp] = m3;
54
55         [--sp] = l0;
56         [--sp] = l1;
57         [--sp] = l2;
58         [--sp] = l3;
59
60         [--sp] = b0;
61         [--sp] = b1;
62         [--sp] = b2;
63         [--sp] = b3;
64         [--sp] = a0.x;
65         [--sp] = a0.w;
66         [--sp] = a1.x;
67         [--sp] = a1.w;
68
69         [--sp] = LC0;
70         [--sp] = LC1;
71         [--sp] = LT0;
72         [--sp] = LT1;
73         [--sp] = LB0;
74         [--sp] = LB1;
75
76         [--sp] = ASTAT;
77
78         [--sp] = r0;    /* Skip reserved */
79         [--sp] = RETS;
80         r0 = RETI;
81         [--sp] = r0;
82         [--sp] = RETX;
83         [--sp] = RETN;
84         [--sp] = RETE;
85         [--sp] = SEQSTAT;
86         [--sp] = r0;    /* Skip IPEND as well. */
87         /* Switch to other method of keeping interrupts disabled.  */
88 #ifdef CONFIG_DEBUG_HWERR
89         r0 = 0x3f;
90         sti r0;
91 #else
92         cli r0;
93 #endif
94         [--sp] = RETI;  /*orig_pc*/
95         /* Clear all L registers.  */
96         r0 = 0 (x);
97         l0 = r0;
98         l1 = r0;
99         l2 = r0;
100         l3 = r0;
101 .endm
102
103 .macro save_context_syscall
104         [--sp] = SYSCFG;
105
106         [--sp] = P0;    /*orig_p0*/
107         [--sp] = R0;    /*orig_r0*/
108         [--sp] = ( R7:0, P5:0 );
109         [--sp] = fp;
110         [--sp] = usp;
111
112         [--sp] = i0;
113         [--sp] = i1;
114         [--sp] = i2;
115         [--sp] = i3;
116
117         [--sp] = m0;
118         [--sp] = m1;
119         [--sp] = m2;
120         [--sp] = m3;
121
122         [--sp] = l0;
123         [--sp] = l1;
124         [--sp] = l2;
125         [--sp] = l3;
126
127         [--sp] = b0;
128         [--sp] = b1;
129         [--sp] = b2;
130         [--sp] = b3;
131         [--sp] = a0.x;
132         [--sp] = a0.w;
133         [--sp] = a1.x;
134         [--sp] = a1.w;
135
136         [--sp] = LC0;
137         [--sp] = LC1;
138         [--sp] = LT0;
139         [--sp] = LT1;
140         [--sp] = LB0;
141         [--sp] = LB1;
142
143         [--sp] = ASTAT;
144
145         [--sp] = r0;    /* Skip reserved */
146         [--sp] = RETS;
147         r0 = RETI;
148         [--sp] = r0;
149         [--sp] = RETX;
150         [--sp] = RETN;
151         [--sp] = RETE;
152         [--sp] = SEQSTAT;
153         [--sp] = r0;    /* Skip IPEND as well. */
154         [--sp] = RETI;  /*orig_pc*/
155         /* Clear all L registers.  */
156         r0 = 0 (x);
157         l0 = r0;
158         l1 = r0;
159         l2 = r0;
160         l3 = r0;
161 .endm
162
163 .macro save_context_no_interrupts
164         [--sp] = SYSCFG;
165         [--sp] = P0;    /* orig_p0 */
166         [--sp] = R0;    /* orig_r0 */
167         [--sp] = ( R7:0, P5:0 );
168         [--sp] = fp;
169         [--sp] = usp;
170
171         [--sp] = i0;
172         [--sp] = i1;
173         [--sp] = i2;
174         [--sp] = i3;
175
176         [--sp] = m0;
177         [--sp] = m1;
178         [--sp] = m2;
179         [--sp] = m3;
180
181         [--sp] = l0;
182         [--sp] = l1;
183         [--sp] = l2;
184         [--sp] = l3;
185
186         [--sp] = b0;
187         [--sp] = b1;
188         [--sp] = b2;
189         [--sp] = b3;
190         [--sp] = a0.x;
191         [--sp] = a0.w;
192         [--sp] = a1.x;
193         [--sp] = a1.w;
194
195         [--sp] = LC0;
196         [--sp] = LC1;
197         [--sp] = LT0;
198         [--sp] = LT1;
199         [--sp] = LB0;
200         [--sp] = LB1;
201
202         [--sp] = ASTAT;
203
204 #ifdef CONFIG_KGDB
205         fp     = 0(Z);
206         r1     = sp;
207         r1    += 60;
208         r1    += 60;
209         r1    += 60;
210         [--sp] = r1;
211 #else
212         [--sp] = r0;    /* Skip reserved */
213 #endif
214         [--sp] = RETS;
215         r0 = RETI;
216         [--sp] = r0;
217         [--sp] = RETX;
218         [--sp] = RETN;
219         [--sp] = RETE;
220         [--sp] = SEQSTAT;
221 #ifdef CONFIG_KGDB
222         r1.l = lo(IPEND);
223         r1.h = hi(IPEND);
224         [--sp] = r1;
225 #else
226         [--sp] = r0;    /* Skip IPEND as well. */
227 #endif
228         [--sp] = r0;  /*orig_pc*/
229         /* Clear all L registers.  */
230         r0 = 0 (x);
231         l0 = r0;
232         l1 = r0;
233         l2 = r0;
234         l3 = r0;
235 .endm
236
237 .macro restore_context_no_interrupts
238         sp += 4;        /* Skip orig_pc */
239         sp += 4;        /* Skip IPEND */
240         SEQSTAT = [sp++];
241         RETE = [sp++];
242         RETN = [sp++];
243         RETX = [sp++];
244         r0 = [sp++];
245         RETI = r0;      /* Restore RETI indirectly when in exception */
246         RETS = [sp++];
247
248         sp += 4;        /* Skip Reserved */
249
250         ASTAT = [sp++];
251
252         LB1 = [sp++];
253         LB0 = [sp++];
254         LT1 = [sp++];
255         LT0 = [sp++];
256         LC1 = [sp++];
257         LC0 = [sp++];
258
259         a1.w = [sp++];
260         a1.x = [sp++];
261         a0.w = [sp++];
262         a0.x = [sp++];
263         b3 = [sp++];
264         b2 = [sp++];
265         b1 = [sp++];
266         b0 = [sp++];
267
268         l3 = [sp++];
269         l2 = [sp++];
270         l1 = [sp++];
271         l0 = [sp++];
272
273         m3 = [sp++];
274         m2 = [sp++];
275         m1 = [sp++];
276         m0 = [sp++];
277
278         i3 = [sp++];
279         i2 = [sp++];
280         i1 = [sp++];
281         i0 = [sp++];
282
283         sp += 4;
284         fp = [sp++];
285
286         ( R7 : 0, P5 : 0) = [ SP ++ ];
287         sp += 8;        /* Skip orig_r0/orig_p0 */
288         SYSCFG = [sp++];
289 .endm
290
291 .macro restore_context_with_interrupts
292         sp += 4;        /* Skip orig_pc */
293         sp += 4;        /* Skip IPEND */
294         SEQSTAT = [sp++];
295         RETE = [sp++];
296         RETN = [sp++];
297         RETX = [sp++];
298         RETI = [sp++];
299         RETS = [sp++];
300
301         p0.h = _irq_flags;
302         p0.l = _irq_flags;
303         r0 = [p0];
304         sti r0;
305
306         sp += 4;        /* Skip Reserved */
307
308         ASTAT = [sp++];
309
310         LB1 = [sp++];
311         LB0 = [sp++];
312         LT1 = [sp++];
313         LT0 = [sp++];
314         LC1 = [sp++];
315         LC0 = [sp++];
316
317         a1.w = [sp++];
318         a1.x = [sp++];
319         a0.w = [sp++];
320         a0.x = [sp++];
321         b3 = [sp++];
322         b2 = [sp++];
323         b1 = [sp++];
324         b0 = [sp++];
325
326         l3 = [sp++];
327         l2 = [sp++];
328         l1 = [sp++];
329         l0 = [sp++];
330
331         m3 = [sp++];
332         m2 = [sp++];
333         m1 = [sp++];
334         m0 = [sp++];
335
336         i3 = [sp++];
337         i2 = [sp++];
338         i1 = [sp++];
339         i0 = [sp++];
340
341         sp += 4;
342         fp = [sp++];
343
344         ( R7 : 0, P5 : 0) = [ SP ++ ];
345         sp += 8;        /* Skip orig_r0/orig_p0 */
346         csync;
347         SYSCFG = [sp++];
348         csync;
349 .endm
350