xref: /openbmc/linux/arch/sh/kernel/cpu/sh2/entry.S (revision 74d99a5e)
1de398406SYoshinori Sato/*
2de398406SYoshinori Sato * arch/sh/kernel/cpu/sh2/entry.S
3de398406SYoshinori Sato *
4de398406SYoshinori Sato * The SH-2 exception entry
5de398406SYoshinori Sato *
6de398406SYoshinori Sato * Copyright (C) 2005,2006 Yoshinori Sato
7de398406SYoshinori Sato * Copyright (C) 2005  AXE,Inc.
8de398406SYoshinori Sato *
9de398406SYoshinori Sato * This file is subject to the terms and conditions of the GNU General Public
10de398406SYoshinori Sato * License.  See the file "COPYING" in the main directory of this archive
11de398406SYoshinori Sato * for more details.
12de398406SYoshinori Sato */
13de398406SYoshinori Sato
14de398406SYoshinori Sato#include <linux/linkage.h>
15de398406SYoshinori Sato#include <asm/asm-offsets.h>
16de398406SYoshinori Sato#include <asm/thread_info.h>
17de398406SYoshinori Sato#include <asm/cpu/mmu_context.h>
18de398406SYoshinori Sato#include <asm/unistd.h>
19de398406SYoshinori Sato#include <asm/errno.h>
20de398406SYoshinori Sato#include <asm/page.h>
21de398406SYoshinori Sato
22de398406SYoshinori Sato/* Offsets to the stack */
23de398406SYoshinori SatoOFF_R0  =  0		/* Return value. New ABI also arg4 */
24de398406SYoshinori SatoOFF_R1  =  4     	/* New ABI: arg5 */
25de398406SYoshinori SatoOFF_R2  =  8     	/* New ABI: arg6 */
26de398406SYoshinori SatoOFF_R3  =  12     	/* New ABI: syscall_nr */
27de398406SYoshinori SatoOFF_R4  =  16     	/* New ABI: arg0 */
28de398406SYoshinori SatoOFF_R5  =  20     	/* New ABI: arg1 */
29de398406SYoshinori SatoOFF_R6  =  24     	/* New ABI: arg2 */
30de398406SYoshinori SatoOFF_R7  =  28     	/* New ABI: arg3 */
31de398406SYoshinori SatoOFF_SP	=  (15*4)
32de398406SYoshinori SatoOFF_PC  =  (16*4)
33de398406SYoshinori SatoOFF_SR	=  (16*4+2*4)
34de398406SYoshinori SatoOFF_TRA	=  (16*4+6*4)
35de398406SYoshinori Sato
36de398406SYoshinori Sato#include <asm/entry-macros.S>
37de398406SYoshinori Sato
38de398406SYoshinori SatoENTRY(exception_handler)
39de398406SYoshinori Sato	! already saved r0/r1
40de398406SYoshinori Sato	mov.l	r2,@-sp
41de398406SYoshinori Sato	mov.l	r3,@-sp
42de398406SYoshinori Sato	mov	r0,r1
43de398406SYoshinori Sato	cli
44de398406SYoshinori Sato	mov.l	$cpu_mode,r2
45de398406SYoshinori Sato	mov.l	@r2,r0
46de398406SYoshinori Sato	mov.l	@(5*4,r15),r3	! previous SR
47de398406SYoshinori Sato	shll2	r3		! set "S" flag
48de398406SYoshinori Sato	rotl	r0		! T <- "S" flag
49de398406SYoshinori Sato	rotl	r0		! "S" flag is LSB
50de398406SYoshinori Sato	rotcr	r3		! T -> r3:b30
51de398406SYoshinori Sato	shlr	r3
52de398406SYoshinori Sato	shlr	r0
53de398406SYoshinori Sato	bt/s	1f
54de398406SYoshinori Sato	 mov.l	r3,@(5*4,r15)	! copy cpu mode to SR
55de398406SYoshinori Sato	! switch to kernel mode
56de398406SYoshinori Sato	mov	#1,r0
57de398406SYoshinori Sato	rotr	r0
58de398406SYoshinori Sato	rotr	r0
59de398406SYoshinori Sato	mov.l	r0,@r2		! enter kernel mode
60de398406SYoshinori Sato	mov.l	$current_thread_info,r2
61de398406SYoshinori Sato	mov.l	@r2,r2
62de398406SYoshinori Sato	mov	#0x20,r0
63de398406SYoshinori Sato	shll8	r0
64de398406SYoshinori Sato	add	r2,r0
65de398406SYoshinori Sato	mov	r15,r2		! r2 = user stack top
66de398406SYoshinori Sato	mov	r0,r15		! switch kernel stack
67de398406SYoshinori Sato	add	#-4,r15		! dummy
68de398406SYoshinori Sato	mov.l	r1,@-r15	! TRA
69de398406SYoshinori Sato	sts.l	macl, @-r15
70de398406SYoshinori Sato	sts.l	mach, @-r15
71de398406SYoshinori Sato	stc.l	gbr, @-r15
72de398406SYoshinori Sato	mov.l	@(4*4,r2),r0
73de398406SYoshinori Sato	mov.l	@(5*4,r2),r1
74de398406SYoshinori Sato	mov.l	r1,@-r15	! original SR
75de398406SYoshinori Sato	sts.l	pr,@-r15
76de398406SYoshinori Sato	mov.l	r0,@-r15	! original PC
77de398406SYoshinori Sato	mov	r2,r3
78de398406SYoshinori Sato	add	#(4+2)*4,r3	! rewind r0 - r3 + exception frame
79de398406SYoshinori Sato	mov.l	r3,@-r15	! original SP
80de398406SYoshinori Sato	mov.l	r14,@-r15
81de398406SYoshinori Sato	mov.l	r13,@-r15
82de398406SYoshinori Sato	mov.l	r12,@-r15
83de398406SYoshinori Sato	mov.l	r11,@-r15
84de398406SYoshinori Sato	mov.l	r10,@-r15
85de398406SYoshinori Sato	mov.l	r9,@-r15
86de398406SYoshinori Sato	mov.l	r8,@-r15
87de398406SYoshinori Sato	mov.l	r7,@-r15
88de398406SYoshinori Sato	mov.l	r6,@-r15
89de398406SYoshinori Sato	mov.l	r5,@-r15
90de398406SYoshinori Sato	mov.l	r4,@-r15
91de398406SYoshinori Sato	mov	r2,r8		! copy user -> kernel stack
92de398406SYoshinori Sato	mov.l	@r8+,r3
93de398406SYoshinori Sato	mov.l	r3,@-r15
94de398406SYoshinori Sato	mov.l	@r8+,r2
95de398406SYoshinori Sato	mov.l	r2,@-r15
96de398406SYoshinori Sato	mov.l	@r8+,r1
97de398406SYoshinori Sato	mov.l	r1,@-r15
98de398406SYoshinori Sato	mov.l	@r8+,r0
99de398406SYoshinori Sato	bra	2f
100de398406SYoshinori Sato	 mov.l	r0,@-r15
101de398406SYoshinori Sato1:
102de398406SYoshinori Sato	! in kernel exception
103de398406SYoshinori Sato	mov	#(22-4-4-1)*4+4,r0
104de398406SYoshinori Sato	mov	r15,r2
105de398406SYoshinori Sato	sub	r0,r15
106de398406SYoshinori Sato	mov.l	@r2+,r0		! old R3
107de398406SYoshinori Sato	mov.l	r0,@-r15
108de398406SYoshinori Sato	mov.l	@r2+,r0		! old R2
109de398406SYoshinori Sato	mov.l	r0,@-r15
110de398406SYoshinori Sato	mov.l	@r2+,r0		! old R1
111de398406SYoshinori Sato	mov.l	r0,@-r15
112de398406SYoshinori Sato	mov.l	@r2+,r0		! old R0
113de398406SYoshinori Sato	mov.l	r0,@-r15
114de398406SYoshinori Sato	mov.l	@r2+,r3		! old PC
115de398406SYoshinori Sato	mov.l	@r2+,r0		! old SR
116de398406SYoshinori Sato	add	#-4,r2		! exception frame stub (sr)
117de398406SYoshinori Sato	mov.l	r1,@-r2		! TRA
118de398406SYoshinori Sato	sts.l	macl, @-r2
119de398406SYoshinori Sato	sts.l	mach, @-r2
120de398406SYoshinori Sato	stc.l	gbr, @-r2
121de398406SYoshinori Sato	mov.l	r0,@-r2		! save old SR
122de398406SYoshinori Sato	sts.l	pr,@-r2
123de398406SYoshinori Sato	mov.l	r3,@-r2		! save old PC
124de398406SYoshinori Sato	mov	r2,r0
125de398406SYoshinori Sato	add	#8*4,r0
126de398406SYoshinori Sato	mov.l	r0,@-r2		! save old SP
127de398406SYoshinori Sato	mov.l	r14,@-r2
128de398406SYoshinori Sato	mov.l	r13,@-r2
129de398406SYoshinori Sato	mov.l	r12,@-r2
130de398406SYoshinori Sato	mov.l	r11,@-r2
131de398406SYoshinori Sato	mov.l	r10,@-r2
132de398406SYoshinori Sato	mov.l	r9,@-r2
133de398406SYoshinori Sato	mov.l	r8,@-r2
134de398406SYoshinori Sato	mov.l	r7,@-r2
135de398406SYoshinori Sato	mov.l	r6,@-r2
136de398406SYoshinori Sato	mov.l	r5,@-r2
137de398406SYoshinori Sato	mov.l	r4,@-r2
138de398406SYoshinori Sato	mov.l	@(OFF_R0,r15),r0
139de398406SYoshinori Sato	mov.l	@(OFF_R1,r15),r1
140de398406SYoshinori Sato	mov.l	@(OFF_R2,r15),r2
141de398406SYoshinori Sato	mov.l	@(OFF_R3,r15),r3
142de398406SYoshinori Sato2:
143de398406SYoshinori Sato	mov	#OFF_TRA,r8
144de398406SYoshinori Sato	add	r15,r8
145de398406SYoshinori Sato	mov.l	@r8,r9
146de398406SYoshinori Sato	mov	#64,r8
147de398406SYoshinori Sato	cmp/hs	r8,r9
148de398406SYoshinori Sato	bt	interrupt_entry	! vec >= 64 is interrupt
149de398406SYoshinori Sato	mov	#32,r8
150de398406SYoshinori Sato	cmp/hs	r8,r9
151de398406SYoshinori Sato	bt	trap_entry	! 64 > vec >= 32  is trap
15274d99a5eSPaul Mundt
15374d99a5eSPaul Mundt#if defined(CONFIG_SH_FPU)
15474d99a5eSPaul Mundt	mov     #13,r8
15574d99a5eSPaul Mundt	cmp/eq  r8,r9
15674d99a5eSPaul Mundt	bt      10f             ! fpu
15774d99a5eSPaul Mundt	nop
15874d99a5eSPaul Mundt#endif
15974d99a5eSPaul Mundt
160de398406SYoshinori Sato	mov.l	4f,r8
161de398406SYoshinori Sato	mov	r9,r4
162de398406SYoshinori Sato	shll2	r9
163de398406SYoshinori Sato	add	r9,r8
164de398406SYoshinori Sato	mov.l	@r8,r8
165de398406SYoshinori Sato	mov	#0,r9
166de398406SYoshinori Sato	cmp/eq	r9,r8
167de398406SYoshinori Sato	bf	3f
168de398406SYoshinori Sato	mov.l	8f,r8		! unhandled exception
16974d99a5eSPaul Mundt#if defined(CONFIG_SH_FPU)
17074d99a5eSPaul Mundt10:
17174d99a5eSPaul Mundt	mov.l	9f, r8		! unhandled exception
17274d99a5eSPaul Mundt#endif
173de398406SYoshinori Sato3:
174de398406SYoshinori Sato	mov.l	5f,r10
175de398406SYoshinori Sato	jmp	@r8
176de398406SYoshinori Sato	 lds	r10,pr
177de398406SYoshinori Sato
178de398406SYoshinori Satointerrupt_entry:
179de398406SYoshinori Sato	mov	r9,r4
1803afb209aSPaul Mundt	mov	r15,r5
181de398406SYoshinori Sato	mov.l	6f,r9
182de398406SYoshinori Sato	mov.l	7f,r8
183de398406SYoshinori Sato	jmp	@r8
184de398406SYoshinori Sato	 lds	r9,pr
185de398406SYoshinori Sato
186de398406SYoshinori Sato	.align	2
187de398406SYoshinori Sato4:	.long	exception_handling_table
188de398406SYoshinori Sato5:	.long	ret_from_exception
189de398406SYoshinori Sato6:	.long	ret_from_irq
190de398406SYoshinori Sato7:	.long	do_IRQ
191de398406SYoshinori Sato8:	.long	do_exception_error
19274d99a5eSPaul Mundt#ifdef CONFIG_SH_FPU
19374d99a5eSPaul Mundt9:	.long	fpu_error_trap_handler
19474d99a5eSPaul Mundt#endif
195de398406SYoshinori Sato
196de398406SYoshinori Satotrap_entry:
1974aa362bbSYoshinori Sato	mov	#0x30,r8
1984aa362bbSYoshinori Sato	cmp/ge	r8,r9		! vector 0x20-0x2f is systemcall
1994aa362bbSYoshinori Sato	bt	1f
2004aa362bbSYoshinori Sato	add	#-0x10,r9	! convert SH2 to SH3/4 ABI
201e9cfc147SYoshinori Sato1:
202de398406SYoshinori Sato	shll2	r9			! TRA
203de398406SYoshinori Sato	mov	#OFF_TRA,r8
204de398406SYoshinori Sato	add	r15,r8
205de398406SYoshinori Sato	mov.l	r9,@r8
206de398406SYoshinori Sato	mov	r9,r8
207afbfb52eSPaul Mundt#ifdef CONFIG_TRACE_IRQFLAGS
208e9cfc147SYoshinori Sato	mov.l	2f, r9
209afbfb52eSPaul Mundt	jsr	@r9
210afbfb52eSPaul Mundt	 nop
211afbfb52eSPaul Mundt#endif
212de398406SYoshinori Sato	sti
213de398406SYoshinori Sato	bra	system_call
214de398406SYoshinori Sato	 nop
215de398406SYoshinori Sato
216de398406SYoshinori Sato	.align	2
217afbfb52eSPaul Mundt#ifdef CONFIG_TRACE_IRQFLAGS
218e9cfc147SYoshinori Sato2:	.long	trace_hardirqs_on
219afbfb52eSPaul Mundt#endif
220de398406SYoshinori Sato
221de398406SYoshinori Sato#if defined(CONFIG_SH_STANDARD_BIOS)
222de398406SYoshinori Sato	/* Unwind the stack and jmp to the debug entry */
223f413d0d9SPaul MundtENTRY(sh_bios_handler)
224de398406SYoshinori Sato	mov	r15,r0
225de398406SYoshinori Sato	add	#(22-4)*4-4,r0
226de398406SYoshinori Sato	ldc.l	@r0+,gbr
227de398406SYoshinori Sato	lds.l	@r0+,mach
228de398406SYoshinori Sato	lds.l	@r0+,macl
229de398406SYoshinori Sato	mov	r15,r0
230de398406SYoshinori Sato	mov.l	@(OFF_SP,r0),r1
231de398406SYoshinori Sato	mov	#OFF_SR,r2
232de398406SYoshinori Sato	mov.l	@(r0,r2),r3
233de398406SYoshinori Sato	mov.l	r3,@-r1
234de398406SYoshinori Sato	mov	#OFF_SP,r2
235de398406SYoshinori Sato	mov.l	@(r0,r2),r3
236de398406SYoshinori Sato	mov.l	r3,@-r1
237de398406SYoshinori Sato	mov	r15,r0
238de398406SYoshinori Sato	add	#(22-4)*4-8,r0
239de398406SYoshinori Sato	mov.l	1f,r2
240de398406SYoshinori Sato	mov.l	@r2,r2
241de398406SYoshinori Sato	stc	sr,r3
242de398406SYoshinori Sato	mov.l	r2,@r0
243de398406SYoshinori Sato	mov.l	r3,@r0
244de398406SYoshinori Sato	mov.l	r1,@(8,r0)
245de398406SYoshinori Sato	mov.l	@r15+, r0
246de398406SYoshinori Sato	mov.l	@r15+, r1
247de398406SYoshinori Sato	mov.l	@r15+, r2
248de398406SYoshinori Sato	mov.l	@r15+, r3
249de398406SYoshinori Sato	mov.l	@r15+, r4
250de398406SYoshinori Sato	mov.l	@r15+, r5
251de398406SYoshinori Sato	mov.l	@r15+, r6
252de398406SYoshinori Sato	mov.l	@r15+, r7
253de398406SYoshinori Sato	mov.l	@r15+, r8
254de398406SYoshinori Sato	mov.l	@r15+, r9
255de398406SYoshinori Sato	mov.l	@r15+, r10
256de398406SYoshinori Sato	mov.l	@r15+, r11
257de398406SYoshinori Sato	mov.l	@r15+, r12
258de398406SYoshinori Sato	mov.l	@r15+, r13
259de398406SYoshinori Sato	mov.l	@r15+, r14
260de398406SYoshinori Sato	add	#8,r15
261de398406SYoshinori Sato	lds.l	@r15+, pr
262de398406SYoshinori Sato	rte
263de398406SYoshinori Sato	 mov.l	@r15+,r15
264de398406SYoshinori Sato	.align	2
265de398406SYoshinori Sato1:	.long	gdb_vbr_vector
266de398406SYoshinori Sato#endif /* CONFIG_SH_STANDARD_BIOS */
267de398406SYoshinori Sato
2685a4f7c66SPaul MundtENTRY(address_error_trap_handler)
269de398406SYoshinori Sato	mov	r15,r4				! regs
270de398406SYoshinori Sato	add	#4,r4
271de398406SYoshinori Sato	mov	#OFF_PC,r0
272de398406SYoshinori Sato	mov.l	@(r0,r15),r6			! pc
273de398406SYoshinori Sato	mov.l	1f,r0
274de398406SYoshinori Sato	jmp	@r0
275de398406SYoshinori Sato	 mov	#0,r5				! writeaccess is unknown
276de398406SYoshinori Sato	.align	2
277de398406SYoshinori Sato
278de398406SYoshinori Sato1:	.long	do_address_error
279de398406SYoshinori Sato
280de398406SYoshinori Satorestore_all:
281de398406SYoshinori Sato	cli
282afbfb52eSPaul Mundt#ifdef CONFIG_TRACE_IRQFLAGS
283e9cfc147SYoshinori Sato	mov.l	1f, r0
284afbfb52eSPaul Mundt	jsr	@r0
285afbfb52eSPaul Mundt	 nop
286afbfb52eSPaul Mundt#endif
287de398406SYoshinori Sato	mov	r15,r0
288de398406SYoshinori Sato	mov.l	$cpu_mode,r2
289de398406SYoshinori Sato	mov	#OFF_SR,r3
290de398406SYoshinori Sato	mov.l	@(r0,r3),r1
291de398406SYoshinori Sato	mov.l	r1,@r2
292de398406SYoshinori Sato	shll2	r1				! clear MD bit
293de398406SYoshinori Sato	shlr2	r1
294de398406SYoshinori Sato	mov.l	@(OFF_SP,r0),r2
295de398406SYoshinori Sato	add	#-8,r2
296de398406SYoshinori Sato	mov.l	r2,@(OFF_SP,r0)			! point exception frame top
297de398406SYoshinori Sato	mov.l	r1,@(4,r2)			! set sr
298de398406SYoshinori Sato	mov	#OFF_PC,r3
299de398406SYoshinori Sato	mov.l	@(r0,r3),r1
300de398406SYoshinori Sato	mov.l	r1,@r2				! set pc
301de398406SYoshinori Sato	add	#4*16+4,r0
302de398406SYoshinori Sato	lds.l	@r0+,pr
303de398406SYoshinori Sato	add	#4,r0				! skip sr
304de398406SYoshinori Sato	ldc.l	@r0+,gbr
305de398406SYoshinori Sato	lds.l	@r0+,mach
306de398406SYoshinori Sato	lds.l	@r0+,macl
307de398406SYoshinori Sato	get_current_thread_info r0, r1
308de398406SYoshinori Sato	mov.l	$current_thread_info,r1
309de398406SYoshinori Sato	mov.l	r0,@r1
310de398406SYoshinori Sato	mov.l	@r15+,r0
311de398406SYoshinori Sato	mov.l	@r15+,r1
312de398406SYoshinori Sato	mov.l	@r15+,r2
313de398406SYoshinori Sato	mov.l	@r15+,r3
314de398406SYoshinori Sato	mov.l	@r15+,r4
315de398406SYoshinori Sato	mov.l	@r15+,r5
316de398406SYoshinori Sato	mov.l	@r15+,r6
317de398406SYoshinori Sato	mov.l	@r15+,r7
318de398406SYoshinori Sato	mov.l	@r15+,r8
319de398406SYoshinori Sato	mov.l	@r15+,r9
320de398406SYoshinori Sato	mov.l	@r15+,r10
321de398406SYoshinori Sato	mov.l	@r15+,r11
322de398406SYoshinori Sato	mov.l	@r15+,r12
323de398406SYoshinori Sato	mov.l	@r15+,r13
324de398406SYoshinori Sato	mov.l	@r15+,r14
325de398406SYoshinori Sato	mov.l	@r15,r15
326de398406SYoshinori Sato	rte
327de398406SYoshinori Sato	 nop
328de398406SYoshinori Sato
3299f9a5de4SPaul Mundt	.align 2
330e9cfc147SYoshinori Sato#ifdef CONFIG_TRACE_IRQFLAGS
331e9cfc147SYoshinori Sato1:     .long   trace_hardirqs_off
332e9cfc147SYoshinori Sato#endif
333de398406SYoshinori Sato$current_thread_info:
334de398406SYoshinori Sato	.long	__current_thread_info
335de398406SYoshinori Sato$cpu_mode:
336de398406SYoshinori Sato	.long	__cpu_mode
337de398406SYoshinori Sato
338de398406SYoshinori Sato! common exception handler
339de398406SYoshinori Sato#include "../../entry-common.S"
340de398406SYoshinori Sato
341de398406SYoshinori Sato	.data
342de398406SYoshinori Sato! cpu operation mode
343de398406SYoshinori Sato! bit30 = MD (compatible SH3/4)
344de398406SYoshinori Sato__cpu_mode:
345de398406SYoshinori Sato	.long	0x40000000
346de398406SYoshinori Sato
347de398406SYoshinori Sato	.section	.bss
348de398406SYoshinori Sato__current_thread_info:
349de398406SYoshinori Sato	.long	0
350de398406SYoshinori Sato
351de398406SYoshinori SatoENTRY(exception_handling_table)
352de398406SYoshinori Sato	.space	4*32
353