Merge branch 'master' into percpu
[pandora-kernel.git] / arch / blackfin / include / asm / context.S
1 /*
2  * Copyright 2007-2009 Analog Devices Inc.
3  *
4  * Licensed under the GPL-2 or later.
5  */
6
7 /*
8  * NOTE!  The single-stepping code assumes that all interrupt handlers
9  * start by saving SYSCFG on the stack with their first instruction.
10  */
11
12 /*
13  * Code to save processor context.
14  *  We even save the register which are preserved by a function call
15  *       - r4, r5, r6, r7, p3, p4, p5
16  */
17 .macro save_context_with_interrupts
18         [--sp] = SYSCFG;
19
20         [--sp] = P0;    /*orig_p0*/
21         [--sp] = R0;    /*orig_r0*/
22
23         [--sp] = ( R7:0, P5:0 );
24         [--sp] = fp;
25         [--sp] = usp;
26
27         [--sp] = i0;
28         [--sp] = i1;
29         [--sp] = i2;
30         [--sp] = i3;
31
32         [--sp] = m0;
33         [--sp] = m1;
34         [--sp] = m2;
35         [--sp] = m3;
36
37         [--sp] = l0;
38         [--sp] = l1;
39         [--sp] = l2;
40         [--sp] = l3;
41
42         [--sp] = b0;
43         [--sp] = b1;
44         [--sp] = b2;
45         [--sp] = b3;
46         [--sp] = a0.x;
47         [--sp] = a0.w;
48         [--sp] = a1.x;
49         [--sp] = a1.w;
50
51         [--sp] = LC0;
52         [--sp] = LC1;
53         [--sp] = LT0;
54         [--sp] = LT1;
55         [--sp] = LB0;
56         [--sp] = LB1;
57
58         [--sp] = ASTAT;
59
60         [--sp] = r0;    /* Skip reserved */
61         [--sp] = RETS;
62         r0 = RETI;
63         [--sp] = r0;
64         [--sp] = RETX;
65         [--sp] = RETN;
66         [--sp] = RETE;
67         [--sp] = SEQSTAT;
68         [--sp] = r0;    /* Skip IPEND as well. */
69         /* Switch to other method of keeping interrupts disabled.  */
70 #ifdef CONFIG_DEBUG_HWERR
71         r0 = 0x3f;
72         sti r0;
73 #else
74         cli r0;
75 #endif
76         [--sp] = RETI;  /*orig_pc*/
77         /* Clear all L registers.  */
78         r0 = 0 (x);
79         l0 = r0;
80         l1 = r0;
81         l2 = r0;
82         l3 = r0;
83 .endm
84
85 .macro save_context_syscall
86         [--sp] = SYSCFG;
87
88         [--sp] = P0;    /*orig_p0*/
89         [--sp] = R0;    /*orig_r0*/
90         [--sp] = ( R7:0, P5:0 );
91         [--sp] = fp;
92         [--sp] = usp;
93
94         [--sp] = i0;
95         [--sp] = i1;
96         [--sp] = i2;
97         [--sp] = i3;
98
99         [--sp] = m0;
100         [--sp] = m1;
101         [--sp] = m2;
102         [--sp] = m3;
103
104         [--sp] = l0;
105         [--sp] = l1;
106         [--sp] = l2;
107         [--sp] = l3;
108
109         [--sp] = b0;
110         [--sp] = b1;
111         [--sp] = b2;
112         [--sp] = b3;
113         [--sp] = a0.x;
114         [--sp] = a0.w;
115         [--sp] = a1.x;
116         [--sp] = a1.w;
117
118         [--sp] = LC0;
119         [--sp] = LC1;
120         [--sp] = LT0;
121         [--sp] = LT1;
122         [--sp] = LB0;
123         [--sp] = LB1;
124
125         [--sp] = ASTAT;
126
127         [--sp] = r0;    /* Skip reserved */
128         [--sp] = RETS;
129         r0 = RETI;
130         [--sp] = r0;
131         [--sp] = RETX;
132         [--sp] = RETN;
133         [--sp] = RETE;
134         [--sp] = SEQSTAT;
135         [--sp] = r0;    /* Skip IPEND as well. */
136         [--sp] = RETI;  /*orig_pc*/
137         /* Clear all L registers.  */
138         r0 = 0 (x);
139         l0 = r0;
140         l1 = r0;
141         l2 = r0;
142         l3 = r0;
143 .endm
144
145 .macro save_context_no_interrupts
146         [--sp] = SYSCFG;
147         [--sp] = P0;    /* orig_p0 */
148         [--sp] = R0;    /* orig_r0 */
149         [--sp] = ( R7:0, P5:0 );
150         [--sp] = fp;
151         [--sp] = usp;
152
153         [--sp] = i0;
154         [--sp] = i1;
155         [--sp] = i2;
156         [--sp] = i3;
157
158         [--sp] = m0;
159         [--sp] = m1;
160         [--sp] = m2;
161         [--sp] = m3;
162
163         [--sp] = l0;
164         [--sp] = l1;
165         [--sp] = l2;
166         [--sp] = l3;
167
168         [--sp] = b0;
169         [--sp] = b1;
170         [--sp] = b2;
171         [--sp] = b3;
172         [--sp] = a0.x;
173         [--sp] = a0.w;
174         [--sp] = a1.x;
175         [--sp] = a1.w;
176
177         [--sp] = LC0;
178         [--sp] = LC1;
179         [--sp] = LT0;
180         [--sp] = LT1;
181         [--sp] = LB0;
182         [--sp] = LB1;
183
184         [--sp] = ASTAT;
185
186 #ifdef CONFIG_KGDB
187         fp     = 0(Z);
188         r1     = sp;
189         r1    += 60;
190         r1    += 60;
191         r1    += 60;
192         [--sp] = r1;
193 #else
194         [--sp] = r0;    /* Skip reserved */
195 #endif
196         [--sp] = RETS;
197         r0 = RETI;
198         [--sp] = r0;
199         [--sp] = RETX;
200         [--sp] = RETN;
201         [--sp] = RETE;
202         [--sp] = SEQSTAT;
203 #ifdef CONFIG_DEBUG_KERNEL
204         p1.l = lo(IPEND);
205         p1.h = hi(IPEND);
206         r1 = [p1];
207         [--sp] = r1;
208 #else
209         [--sp] = r0;    /* Skip IPEND as well. */
210 #endif
211         [--sp] = r0;  /*orig_pc*/
212         /* Clear all L registers.  */
213         r0 = 0 (x);
214         l0 = r0;
215         l1 = r0;
216         l2 = r0;
217         l3 = r0;
218 .endm
219
220 .macro restore_context_no_interrupts
221         sp += 4;        /* Skip orig_pc */
222         sp += 4;        /* Skip IPEND */
223         SEQSTAT = [sp++];
224         RETE = [sp++];
225         RETN = [sp++];
226         RETX = [sp++];
227         r0 = [sp++];
228         RETI = r0;      /* Restore RETI indirectly when in exception */
229         RETS = [sp++];
230
231         sp += 4;        /* Skip Reserved */
232
233         ASTAT = [sp++];
234
235         LB1 = [sp++];
236         LB0 = [sp++];
237         LT1 = [sp++];
238         LT0 = [sp++];
239         LC1 = [sp++];
240         LC0 = [sp++];
241
242         a1.w = [sp++];
243         a1.x = [sp++];
244         a0.w = [sp++];
245         a0.x = [sp++];
246         b3 = [sp++];
247         b2 = [sp++];
248         b1 = [sp++];
249         b0 = [sp++];
250
251         l3 = [sp++];
252         l2 = [sp++];
253         l1 = [sp++];
254         l0 = [sp++];
255
256         m3 = [sp++];
257         m2 = [sp++];
258         m1 = [sp++];
259         m0 = [sp++];
260
261         i3 = [sp++];
262         i2 = [sp++];
263         i1 = [sp++];
264         i0 = [sp++];
265
266         sp += 4;
267         fp = [sp++];
268
269         ( R7 : 0, P5 : 0) = [ SP ++ ];
270         sp += 8;        /* Skip orig_r0/orig_p0 */
271         SYSCFG = [sp++];
272 .endm
273
274 .macro restore_context_with_interrupts
275         sp += 4;        /* Skip orig_pc */
276         sp += 4;        /* Skip IPEND */
277         SEQSTAT = [sp++];
278         RETE = [sp++];
279         RETN = [sp++];
280         RETX = [sp++];
281         RETI = [sp++];
282         RETS = [sp++];
283
284 #ifdef CONFIG_SMP
285         GET_PDA(p0, r0);
286         r0 = [p0 + PDA_IRQFLAGS];
287 #else
288         p0.h = _bfin_irq_flags;
289         p0.l = _bfin_irq_flags;
290         r0 = [p0];
291 #endif
292         sti r0;
293
294         sp += 4;        /* Skip Reserved */
295
296         ASTAT = [sp++];
297
298         LB1 = [sp++];
299         LB0 = [sp++];
300         LT1 = [sp++];
301         LT0 = [sp++];
302         LC1 = [sp++];
303         LC0 = [sp++];
304
305         a1.w = [sp++];
306         a1.x = [sp++];
307         a0.w = [sp++];
308         a0.x = [sp++];
309         b3 = [sp++];
310         b2 = [sp++];
311         b1 = [sp++];
312         b0 = [sp++];
313
314         l3 = [sp++];
315         l2 = [sp++];
316         l1 = [sp++];
317         l0 = [sp++];
318
319         m3 = [sp++];
320         m2 = [sp++];
321         m1 = [sp++];
322         m0 = [sp++];
323
324         i3 = [sp++];
325         i2 = [sp++];
326         i1 = [sp++];
327         i0 = [sp++];
328
329         sp += 4;
330         fp = [sp++];
331
332         ( R7 : 0, P5 : 0) = [ SP ++ ];
333         sp += 8;        /* Skip orig_r0/orig_p0 */
334         csync;
335         SYSCFG = [sp++];
336         csync;
337 .endm
338
339 .macro save_context_cplb
340         [--sp] = (R7:0, P5:0);
341         [--sp] = fp;
342
343         [--sp] = a0.x;
344         [--sp] = a0.w;
345         [--sp] = a1.x;
346         [--sp] = a1.w;
347
348         [--sp] = LC0;
349         [--sp] = LC1;
350         [--sp] = LT0;
351         [--sp] = LT1;
352         [--sp] = LB0;
353         [--sp] = LB1;
354
355         [--sp] = RETS;
356 .endm
357
358 .macro restore_context_cplb
359         RETS = [sp++];
360
361         LB1 = [sp++];
362         LB0 = [sp++];
363         LT1 = [sp++];
364         LT0 = [sp++];
365         LC1 = [sp++];
366         LC0 = [sp++];
367
368         a1.w = [sp++];
369         a1.x = [sp++];
370         a0.w = [sp++];
371         a0.x = [sp++];
372
373         fp = [sp++];
374
375         (R7:0, P5:0) = [SP++];
376 .endm