• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/h8300/kernel/
1/* -*- mode: asm -*-
2 *
3 *  linux/arch/h8300/platform/h8300h/entry.S
4 *
5 *  Yoshinori Sato <ysato@users.sourceforge.jp>
6 *  David McCullough <davidm@snapgear.com>
7 *
8 */
9
10/*
11 *  entry.S
12 *  include exception/interrupt gateway
13 *          system call entry
14 */
15
16#include <linux/sys.h>
17#include <asm/unistd.h>
18#include <asm/setup.h>
19#include <asm/segment.h>
20#include <asm/linkage.h>
21#include <asm/asm-offsets.h>
22#include <asm/thread_info.h>
23#include <asm/errno.h>
24
25#if defined(CONFIG_CPU_H8300H)
26#define USERRET 8
27INTERRUPTS = 64
28	.h8300h
29	.macro	SHLL2 reg
30	shll.l	\reg
31	shll.l	\reg
32	.endm
33	.macro	SHLR2 reg
34	shlr.l	\reg
35	shlr.l	\reg
36	.endm
37	.macro	SAVEREGS
38	mov.l	er0,@-sp
39	mov.l	er1,@-sp
40	mov.l	er2,@-sp
41	mov.l	er3,@-sp
42	.endm
43	.macro	RESTOREREGS
44	mov.l	@sp+,er3
45	mov.l	@sp+,er2
46	.endm
47	.macro	SAVEEXR
48	.endm
49	.macro	RESTOREEXR
50	.endm
51#endif
52#if defined(CONFIG_CPU_H8S)
53#define USERRET 10
54#define USEREXR 8
55INTERRUPTS = 128
56	.h8300s
57	.macro	SHLL2 reg
58	shll.l	#2,\reg
59	.endm
60	.macro	SHLR2 reg
61	shlr.l	#2,\reg
62	.endm
63	.macro	SAVEREGS
64	stm.l	er0-er3,@-sp
65	.endm
66	.macro	RESTOREREGS
67	ldm.l	@sp+,er2-er3
68	.endm
69	.macro	SAVEEXR
70	mov.w	@(USEREXR:16,er0),r1
71	mov.w	r1,@(LEXR-LER3:16,sp)		/* copy EXR */
72	.endm
73	.macro	RESTOREEXR
74	mov.w	@(LEXR-LER1:16,sp),r1		/* restore EXR */
75	mov.b	r1l,r1h
76	mov.w	r1,@(USEREXR:16,er0)
77	.endm
78#endif
79
80
81/* CPU context save/restore macros. */
82
83	.macro	SAVE_ALL
84	mov.l	er0,@-sp
85	stc	ccr,r0l				/* check kernel mode */
86	btst	#4,r0l
87	bne	5f
88
89	/* user mode */
90	mov.l	sp,@SYMBOL_NAME(sw_usp)
91	mov.l	@sp,er0				/* restore saved er0 */
92	orc	#0x10,ccr			/* switch kernel stack */
93	mov.l	@SYMBOL_NAME(sw_ksp),sp
94	sub.l	#(LRET-LORIG),sp		/* allocate LORIG - LRET */
95	SAVEREGS
96	mov.l   @SYMBOL_NAME(sw_usp),er0
97	mov.l   @(USERRET:16,er0),er1           /* copy the RET addr */
98	mov.l   er1,@(LRET-LER3:16,sp)
99	SAVEEXR
100
101	mov.l	@(LORIG-LER3:16,sp),er0
102	mov.l	er0,@(LER0-LER3:16,sp)		/* copy ER0 */
103	mov.w	e1,r1				/* e1 highbyte = ccr */
104	and	#0xef,r1h			/* mask mode? flag */
105	bra	6f
1065:
107	/* kernel mode */
108	mov.l	@sp,er0				/* restore saved er0 */
109	subs	#2,sp				/* set dummy ccr */
110	SAVEREGS
111	mov.w	@(LRET-LER3:16,sp),r1		/* copy old ccr */
1126:
113	mov.b	r1h,r1l
114	mov.b	#0,r1h
115	mov.w	r1,@(LCCR-LER3:16,sp)		/* set ccr */
116	mov.l	er6,@-sp			/* syscall arg #6 */
117	mov.l	er5,@-sp			/* syscall arg #5 */
118	mov.l	er4,@-sp			/* syscall arg #4 */
119	.endm					/* r1 = ccr */
120
121	.macro	RESTORE_ALL
122	mov.l	@sp+,er4
123	mov.l	@sp+,er5
124	mov.l	@sp+,er6
125	RESTOREREGS
126	mov.w	@(LCCR-LER1:16,sp),r0		/* check kernel mode */
127	btst	#4,r0l
128	bne	7f
129
130	orc	#0x80,ccr
131	mov.l	@SYMBOL_NAME(sw_usp),er0
132	mov.l	@(LER0-LER1:16,sp),er1		/* restore ER0 */
133	mov.l	er1,@er0
134	RESTOREEXR
135	mov.w	@(LCCR-LER1:16,sp),r1		/* restore the RET addr */
136	mov.b	r1l,r1h
137	mov.b	@(LRET+1-LER1:16,sp),r1l
138	mov.w	r1,e1
139	mov.w	@(LRET+2-LER1:16,sp),r1
140	mov.l	er1,@(USERRET:16,er0)
141
142	mov.l	@sp+,er1
143	add.l	#(LRET-LER1),sp			/* remove LORIG - LRET */
144	mov.l	sp,@SYMBOL_NAME(sw_ksp)
145	andc	#0xef,ccr			/* switch to user mode */
146	mov.l	er0,sp
147	bra	8f
1487:
149	mov.l	@sp+,er1
150	adds	#4,sp
151	adds	#2,sp
1528:
153	mov.l	@sp+,er0
154	adds	#4,sp				/* remove the sw created LVEC */
155	rte
156	.endm
157
158.globl SYMBOL_NAME(system_call)
159.globl SYMBOL_NAME(ret_from_exception)
160.globl SYMBOL_NAME(ret_from_fork)
161.globl SYMBOL_NAME(ret_from_interrupt)
162.globl SYMBOL_NAME(interrupt_redirect_table)
163.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
164.globl SYMBOL_NAME(resume)
165.globl SYMBOL_NAME(interrupt_entry)
166.globl SYMBOL_NAME(trace_break)
167
168#if defined(CONFIG_ROMKERNEL)
169	.section .int_redirect,"ax"
170SYMBOL_NAME_LABEL(interrupt_redirect_table)
171#if defined(CONFIG_CPU_H8300H)
172	.rept	7
173	.long	0
174	.endr
175#endif
176#if defined(CONFIG_CPU_H8S)
177	.rept	5
178	.long	0
179	.endr
180	jmp	@SYMBOL_NAME(trace_break)
181	.long	0
182#endif
183
184	jsr	@SYMBOL_NAME(interrupt_entry)	/* NMI */
185	jmp	@SYMBOL_NAME(system_call)	/* TRAPA #0 (System call) */
186	.long	0
187	.long	0
188	jmp	@SYMBOL_NAME(trace_break)	/* TRAPA #3 (breakpoint) */
189	.rept	INTERRUPTS-12
190	jsr	@SYMBOL_NAME(interrupt_entry)
191	.endr
192#endif
193#if defined(CONFIG_RAMKERNEL)
194.globl SYMBOL_NAME(interrupt_redirect_table)
195	.section .bss
196SYMBOL_NAME_LABEL(interrupt_redirect_table)
197	.space	4
198#endif
199
200	.section .text
201	.align	2
202SYMBOL_NAME_LABEL(interrupt_entry)
203	SAVE_ALL
204	mov.l	sp,er0
205	add.l	#LVEC,er0
206	btst	#4,r1l
207	bne	1f
208	/* user LVEC */
209	mov.l	@SYMBOL_NAME(sw_usp),er0
210	adds	#4,er0
2111:
212	mov.l	@er0,er0			/* LVEC address */
213#if defined(CONFIG_ROMKERNEL)
214	sub.l	#SYMBOL_NAME(interrupt_redirect_table),er0
215#endif
216#if defined(CONFIG_RAMKERNEL)
217	mov.l	@SYMBOL_NAME(interrupt_redirect_table),er1
218	sub.l	er1,er0
219#endif
220	SHLR2	er0
221	dec.l	#1,er0
222	mov.l	sp,er1
223	subs	#4,er1				/* adjust ret_pc */
224	jsr	@SYMBOL_NAME(do_IRQ)
225	jmp	@SYMBOL_NAME(ret_from_interrupt)
226
227SYMBOL_NAME_LABEL(system_call)
228	subs	#4,sp				/* dummy LVEC */
229	SAVE_ALL
230	andc	#0x7f,ccr
231	mov.l	er0,er4
232
233	/* save top of frame */
234	mov.l	sp,er0
235	jsr	@SYMBOL_NAME(set_esp0)
236	mov.l	sp,er2
237	and.w	#0xe000,r2
238	mov.b	@((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
239	btst	#(TIF_SYSCALL_TRACE & 7),r2l
240	beq	1f
241	jsr	@SYMBOL_NAME(do_syscall_trace)
2421:
243	cmp.l	#NR_syscalls,er4
244	bcc	badsys
245	SHLL2	er4
246	mov.l	#SYMBOL_NAME(sys_call_table),er0
247	add.l	er4,er0
248	mov.l	@er0,er4
249	beq	SYMBOL_NAME(ret_from_exception):16
250	mov.l	@(LER1:16,sp),er0
251	mov.l	@(LER2:16,sp),er1
252	mov.l	@(LER3:16,sp),er2
253	jsr	@er4
254	mov.l	er0,@(LER0:16,sp)		/* save the return value */
255	mov.l	sp,er2
256	and.w	#0xe000,r2
257	mov.b	@((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
258	btst	#(TIF_SYSCALL_TRACE & 7),r2l
259	beq	2f
260	jsr	@SYMBOL_NAME(do_syscall_trace)
2612:
262#if defined(CONFIG_SYSCALL_PRINT)
263	jsr	@SYMBOL_NAME(syscall_print)
264#endif
265	orc	#0x80,ccr
266	bra	resume_userspace
267
268badsys:
269	mov.l	#-ENOSYS,er0
270	mov.l	er0,@(LER0:16,sp)
271	bra	resume_userspace
272
273#if !defined(CONFIG_PREEMPT)
274#define resume_kernel restore_all
275#endif
276
277SYMBOL_NAME_LABEL(ret_from_exception)
278#if defined(CONFIG_PREEMPT)
279	orc	#0x80,ccr
280#endif
281SYMBOL_NAME_LABEL(ret_from_interrupt)
282	mov.b	@(LCCR+1:16,sp),r0l
283	btst	#4,r0l
284	bne	resume_kernel:8		/* return from kernel */
285resume_userspace:
286	andc	#0x7f,ccr
287	mov.l	sp,er4
288	and.w	#0xe000,r4		/* er4 <- current thread info */
289	mov.l	@(TI_FLAGS:16,er4),er1
290	and.l	#_TIF_WORK_MASK,er1
291	beq	restore_all:8
292work_pending:
293	btst	#TIF_NEED_RESCHED,r1l
294	bne	work_resched:8
295	/* work notifysig */
296	mov.l	sp,er0
297	subs	#4,er0			/* er0: pt_regs */
298	jsr	@SYMBOL_NAME(do_notify_resume)
299	bra	restore_all:8
300work_resched:
301	mov.l	sp,er0
302	jsr	@SYMBOL_NAME(set_esp0)
303	jsr	@SYMBOL_NAME(schedule)
304	bra	resume_userspace:8
305restore_all:
306	RESTORE_ALL			/* Does RTE */
307
308#if defined(CONFIG_PREEMPT)
309resume_kernel:
310	mov.l	@(TI_PRE_COUNT:16,er4),er0
311	bne	restore_all:8
312need_resched:
313	mov.l	@(TI_FLAGS:16,er4),er0
314	btst	#TIF_NEED_RESCHED,r0l
315	beq	restore_all:8
316	mov.b	@(LCCR+1:16,sp),r0l	/* Interrupt Enabled? */
317	bmi	restore_all:8
318	mov.l	#PREEMPT_ACTIVE,er0
319	mov.l	er0,@(TI_PRE_COUNT:16,er4)
320	andc	#0x7f,ccr
321	mov.l	sp,er0
322	jsr	@SYMBOL_NAME(set_esp0)
323	jsr	@SYMBOL_NAME(schedule)
324	orc	#0x80,ccr
325	bra	need_resched:8
326#endif
327
328SYMBOL_NAME_LABEL(ret_from_fork)
329	mov.l	er2,er0
330	jsr	@SYMBOL_NAME(schedule_tail)
331	jmp	@SYMBOL_NAME(ret_from_exception)
332
333SYMBOL_NAME_LABEL(resume)
334	/*
335	 * Beware - when entering resume, offset of tss is in d1,
336	 * prev (the current task) is in a0, next (the new task)
337	 * is in a1 and d2.b is non-zero if the mm structure is
338	 * shared between the tasks, so don't change these
339	 * registers until their contents are no longer needed.
340	 */
341
342	/* save sr */
343	sub.w	r3,r3
344	stc	ccr,r3l
345	mov.w	r3,@(THREAD_CCR+2:16,er0)
346
347	/* disable interrupts */
348	orc	#0x80,ccr
349	mov.l	@SYMBOL_NAME(sw_usp),er3
350	mov.l	er3,@(THREAD_USP:16,er0)
351	mov.l	sp,@(THREAD_KSP:16,er0)
352
353	/* Skip address space switching if they are the same. */
354
355	mov.l	@(THREAD_USP:16,er1),er0
356	mov.l	er0,@SYMBOL_NAME(sw_usp)
357	mov.l	@(THREAD_KSP:16,er1),sp
358
359	/* restore status register */
360	mov.w	@(THREAD_CCR+2:16,er1),r3
361
362	ldc	r3l,ccr
363	rts
364
365SYMBOL_NAME_LABEL(trace_break)
366	subs	#4,sp
367	SAVE_ALL
368	sub.l	er1,er1
369	dec.l	#1,er1
370	mov.l	er1,@(LORIG,sp)
371	mov.l	sp,er0
372	jsr	@SYMBOL_NAME(set_esp0)
373	mov.l	@SYMBOL_NAME(sw_usp),er0
374	mov.l	@er0,er1
375	mov.w	@(-2:16,er1),r2
376	cmp.w	#0x5730,r2
377	beq	1f
378	subs	#2,er1
379	mov.l	er1,@er0
3801:
381	and.w	#0xff,e1
382	mov.l	er1,er0
383	jsr	@SYMBOL_NAME(trace_trap)
384	jmp	@SYMBOL_NAME(ret_from_exception)
385
386	.section	.bss
387SYMBOL_NAME_LABEL(sw_ksp)
388	.space	4
389SYMBOL_NAME_LABEL(sw_usp)
390	.space	4
391
392	.end
393