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