• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_KGDB
227	r1.l = lo(IPEND);
228	r1.h = hi(IPEND);
229	[--sp] = r1;
230#else
231	[--sp] = r0;	/* Skip IPEND as well. */
232#endif
233	[--sp] = r0;  /*orig_pc*/
234	/* Clear all L registers.  */
235	r0 = 0 (x);
236	l0 = r0;
237	l1 = r0;
238	l2 = r0;
239	l3 = r0;
240.endm
241
242.macro restore_context_no_interrupts
243	sp += 4;	/* Skip orig_pc */
244	sp += 4;	/* Skip IPEND */
245	SEQSTAT = [sp++];
246	RETE = [sp++];
247	RETN = [sp++];
248	RETX = [sp++];
249	r0 = [sp++];
250	RETI = r0;	/* Restore RETI indirectly when in exception */
251	RETS = [sp++];
252
253	sp += 4;	/* Skip Reserved */
254
255	ASTAT = [sp++];
256
257	LB1 = [sp++];
258	LB0 = [sp++];
259	LT1 = [sp++];
260	LT0 = [sp++];
261	LC1 = [sp++];
262	LC0 = [sp++];
263
264	a1.w = [sp++];
265	a1.x = [sp++];
266	a0.w = [sp++];
267	a0.x = [sp++];
268	b3 = [sp++];
269	b2 = [sp++];
270	b1 = [sp++];
271	b0 = [sp++];
272
273	l3 = [sp++];
274	l2 = [sp++];
275	l1 = [sp++];
276	l0 = [sp++];
277
278	m3 = [sp++];
279	m2 = [sp++];
280	m1 = [sp++];
281	m0 = [sp++];
282
283	i3 = [sp++];
284	i2 = [sp++];
285	i1 = [sp++];
286	i0 = [sp++];
287
288	sp += 4;
289	fp = [sp++];
290
291	( R7 : 0, P5 : 0) = [ SP ++ ];
292	sp += 8;	/* Skip orig_r0/orig_p0 */
293	SYSCFG = [sp++];
294.endm
295
296.macro restore_context_with_interrupts
297	sp += 4;	/* Skip orig_pc */
298	sp += 4;	/* Skip IPEND */
299	SEQSTAT = [sp++];
300	RETE = [sp++];
301	RETN = [sp++];
302	RETX = [sp++];
303	RETI = [sp++];
304	RETS = [sp++];
305
306#ifdef CONFIG_SMP
307	GET_PDA(p0, r0);
308	r0 = [p0 + PDA_IRQFLAGS];
309#else
310	p0.h = _bfin_irq_flags;
311	p0.l = _bfin_irq_flags;
312	r0 = [p0];
313#endif
314	sti r0;
315
316	sp += 4;	/* Skip Reserved */
317
318	ASTAT = [sp++];
319
320	LB1 = [sp++];
321	LB0 = [sp++];
322	LT1 = [sp++];
323	LT0 = [sp++];
324	LC1 = [sp++];
325	LC0 = [sp++];
326
327	a1.w = [sp++];
328	a1.x = [sp++];
329	a0.w = [sp++];
330	a0.x = [sp++];
331	b3 = [sp++];
332	b2 = [sp++];
333	b1 = [sp++];
334	b0 = [sp++];
335
336	l3 = [sp++];
337	l2 = [sp++];
338	l1 = [sp++];
339	l0 = [sp++];
340
341	m3 = [sp++];
342	m2 = [sp++];
343	m1 = [sp++];
344	m0 = [sp++];
345
346	i3 = [sp++];
347	i2 = [sp++];
348	i1 = [sp++];
349	i0 = [sp++];
350
351	sp += 4;
352	fp = [sp++];
353
354	( R7 : 0, P5 : 0) = [ SP ++ ];
355	sp += 8;	/* Skip orig_r0/orig_p0 */
356	csync;
357	SYSCFG = [sp++];
358	csync;
359.endm
360
361.macro save_context_cplb
362	[--sp] = (R7:0, P5:0);
363	[--sp] = fp;
364
365	[--sp] = a0.x;
366	[--sp] = a0.w;
367	[--sp] = a1.x;
368	[--sp] = a1.w;
369
370	[--sp] = LC0;
371	[--sp] = LC1;
372	[--sp] = LT0;
373	[--sp] = LT1;
374	[--sp] = LB0;
375	[--sp] = LB1;
376
377	[--sp] = RETS;
378.endm
379
380.macro restore_context_cplb
381	RETS = [sp++];
382
383	LB1 = [sp++];
384	LB0 = [sp++];
385	LT1 = [sp++];
386	LT0 = [sp++];
387	LC1 = [sp++];
388	LC0 = [sp++];
389
390	a1.w = [sp++];
391	a1.x = [sp++];
392	a0.w = [sp++];
393	a0.x = [sp++];
394
395	fp = [sp++];
396
397	(R7:0, P5:0) = [SP++];
398.endm
399