xref: /linux/arch/sh/kernel/cpu/sh2/entry.S (revision 47d11326)
1*47d11326SKuninori Morimoto/* SPDX-License-Identifier: GPL-2.0
2*47d11326SKuninori Morimoto *
3de398406SYoshinori Sato * arch/sh/kernel/cpu/sh2/entry.S
4de398406SYoshinori Sato *
5de398406SYoshinori Sato * The SH-2 exception entry
6de398406SYoshinori Sato *
76e80f5e8SYoshinori Sato * Copyright (C) 2005-2008 Yoshinori Sato
8de398406SYoshinori Sato * Copyright (C) 2005  AXE,Inc.
9de398406SYoshinori Sato */
10de398406SYoshinori Sato
11de398406SYoshinori Sato#include <linux/linkage.h>
12de398406SYoshinori Sato#include <asm/asm-offsets.h>
13de398406SYoshinori Sato#include <asm/thread_info.h>
14f15cbe6fSPaul Mundt#include <cpu/mmu_context.h>
15de398406SYoshinori Sato#include <asm/unistd.h>
16de398406SYoshinori Sato#include <asm/errno.h>
17de398406SYoshinori Sato#include <asm/page.h>
18de398406SYoshinori Sato
19de398406SYoshinori Sato/* Offsets to the stack */
20de398406SYoshinori SatoOFF_R0  =  0		/* Return value. New ABI also arg4 */
21de398406SYoshinori SatoOFF_R1  =  4     	/* New ABI: arg5 */
22de398406SYoshinori SatoOFF_R2  =  8     	/* New ABI: arg6 */
23de398406SYoshinori SatoOFF_R3  =  12     	/* New ABI: syscall_nr */
24de398406SYoshinori SatoOFF_R4  =  16     	/* New ABI: arg0 */
25de398406SYoshinori SatoOFF_R5  =  20     	/* New ABI: arg1 */
26de398406SYoshinori SatoOFF_R6  =  24     	/* New ABI: arg2 */
27de398406SYoshinori SatoOFF_R7  =  28     	/* New ABI: arg3 */
28de398406SYoshinori SatoOFF_SP	=  (15*4)
29de398406SYoshinori SatoOFF_PC  =  (16*4)
30de398406SYoshinori SatoOFF_SR	=  (16*4+2*4)
31de398406SYoshinori SatoOFF_TRA	=  (16*4+6*4)
32de398406SYoshinori Sato
33de398406SYoshinori Sato#include <asm/entry-macros.S>
34de398406SYoshinori Sato
35de398406SYoshinori SatoENTRY(exception_handler)
366e80f5e8SYoshinori Sato	! stack
376e80f5e8SYoshinori Sato	! r0 <- point sp
386e80f5e8SYoshinori Sato	! r1
396e80f5e8SYoshinori Sato	! pc
406e80f5e8SYoshinori Sato	! sr
416e80f5e8SYoshinori Sato	! r0 = temporary
426e80f5e8SYoshinori Sato	! r1 = vector (pseudo EXPEVT / INTEVT / TRA)
43de398406SYoshinori Sato	mov.l	r2,@-sp
44de398406SYoshinori Sato	mov.l	r3,@-sp
45de398406SYoshinori Sato	cli
46de398406SYoshinori Sato	mov.l	$cpu_mode,r2
474b6ef05bSRich Felker#ifdef CONFIG_SMP
484b6ef05bSRich Felker	mov.l	$cpuid,r3
494b6ef05bSRich Felker	mov.l	@r3,r3
504b6ef05bSRich Felker	mov.l	@r3,r3
514b6ef05bSRich Felker	shll2	r3
524b6ef05bSRich Felker	add	r3,r2
534b6ef05bSRich Felker#endif
54de398406SYoshinori Sato	mov.l	@r2,r0
55de398406SYoshinori Sato	mov.l	@(5*4,r15),r3	! previous SR
566e80f5e8SYoshinori Sato	or	r0,r3		! set MD
576e80f5e8SYoshinori Sato	tst	r0,r0
586e80f5e8SYoshinori Sato	bf/s	1f		! previous mode check
596e80f5e8SYoshinori Sato	 mov.l	r3,@(5*4,r15)	! update SR
60de398406SYoshinori Sato	! switch to kernel mode
616e80f5e8SYoshinori Sato	mov.l	__md_bit,r0
62de398406SYoshinori Sato	mov.l	r0,@r2		! enter kernel mode
63de398406SYoshinori Sato	mov.l	$current_thread_info,r2
644b6ef05bSRich Felker#ifdef CONFIG_SMP
654b6ef05bSRich Felker	mov.l	$cpuid,r0
664b6ef05bSRich Felker	mov.l	@r0,r0
674b6ef05bSRich Felker	mov.l	@r0,r0
684b6ef05bSRich Felker	shll2	r0
694b6ef05bSRich Felker	add	r0,r2
704b6ef05bSRich Felker#endif
71de398406SYoshinori Sato	mov.l	@r2,r2
726e80f5e8SYoshinori Sato	mov	#(THREAD_SIZE >> 8),r0
73de398406SYoshinori Sato	shll8	r0
74de398406SYoshinori Sato	add	r2,r0
75de398406SYoshinori Sato	mov	r15,r2		! r2 = user stack top
76de398406SYoshinori Sato	mov	r0,r15		! switch kernel stack
77de398406SYoshinori Sato	mov.l	r1,@-r15	! TRA
78de398406SYoshinori Sato	sts.l	macl, @-r15
79de398406SYoshinori Sato	sts.l	mach, @-r15
80de398406SYoshinori Sato	stc.l	gbr, @-r15
816e80f5e8SYoshinori Sato	mov.l	@(5*4,r2),r0
826e80f5e8SYoshinori Sato	mov.l	r0,@-r15	! original SR
83de398406SYoshinori Sato	sts.l	pr,@-r15
846e80f5e8SYoshinori Sato	mov.l	@(4*4,r2),r0
85de398406SYoshinori Sato	mov.l	r0,@-r15	! original PC
86de398406SYoshinori Sato	mov	r2,r3
87de398406SYoshinori Sato	add	#(4+2)*4,r3	! rewind r0 - r3 + exception frame
88de398406SYoshinori Sato	mov.l	r3,@-r15	! original SP
89de398406SYoshinori Sato	mov.l	r14,@-r15
90de398406SYoshinori Sato	mov.l	r13,@-r15
91de398406SYoshinori Sato	mov.l	r12,@-r15
92de398406SYoshinori Sato	mov.l	r11,@-r15
93de398406SYoshinori Sato	mov.l	r10,@-r15
94de398406SYoshinori Sato	mov.l	r9,@-r15
95de398406SYoshinori Sato	mov.l	r8,@-r15
96de398406SYoshinori Sato	mov.l	r7,@-r15
97de398406SYoshinori Sato	mov.l	r6,@-r15
98de398406SYoshinori Sato	mov.l	r5,@-r15
99de398406SYoshinori Sato	mov.l	r4,@-r15
1006e80f5e8SYoshinori Sato	mov	r1,r9		! save TRA
101de398406SYoshinori Sato	mov	r2,r8		! copy user -> kernel stack
1026e80f5e8SYoshinori Sato	mov.l	@(0,r8),r3
103de398406SYoshinori Sato	mov.l	r3,@-r15
1046e80f5e8SYoshinori Sato	mov.l	@(4,r8),r2
105de398406SYoshinori Sato	mov.l	r2,@-r15
1066e80f5e8SYoshinori Sato	mov.l	@(12,r8),r1
107de398406SYoshinori Sato	mov.l	r1,@-r15
1086e80f5e8SYoshinori Sato	mov.l	@(8,r8),r0
109de398406SYoshinori Sato	bra	2f
110de398406SYoshinori Sato	 mov.l	r0,@-r15
111de398406SYoshinori Sato1:
112de398406SYoshinori Sato	! in kernel exception
113de398406SYoshinori Sato	mov	#(22-4-4-1)*4+4,r0
114de398406SYoshinori Sato	mov	r15,r2
115de398406SYoshinori Sato	sub	r0,r15
116de398406SYoshinori Sato	mov.l	@r2+,r0		! old R3
117de398406SYoshinori Sato	mov.l	r0,@-r15
118de398406SYoshinori Sato	mov.l	@r2+,r0		! old R2
119de398406SYoshinori Sato	mov.l	r0,@-r15
1206e80f5e8SYoshinori Sato	mov.l	@(4,r2),r0	! old R1
121de398406SYoshinori Sato	mov.l	r0,@-r15
1226e80f5e8SYoshinori Sato	mov.l	@r2,r0		! old R0
123de398406SYoshinori Sato	mov.l	r0,@-r15
1246e80f5e8SYoshinori Sato	add	#8,r2
125de398406SYoshinori Sato	mov.l	@r2+,r3		! old PC
126de398406SYoshinori Sato	mov.l	@r2+,r0		! old SR
127de398406SYoshinori Sato	add	#-4,r2		! exception frame stub (sr)
128de398406SYoshinori Sato	mov.l	r1,@-r2		! TRA
129de398406SYoshinori Sato	sts.l	macl, @-r2
130de398406SYoshinori Sato	sts.l	mach, @-r2
131de398406SYoshinori Sato	stc.l	gbr, @-r2
132de398406SYoshinori Sato	mov.l	r0,@-r2		! save old SR
133de398406SYoshinori Sato	sts.l	pr,@-r2
134de398406SYoshinori Sato	mov.l	r3,@-r2		! save old PC
135de398406SYoshinori Sato	mov	r2,r0
136de398406SYoshinori Sato	add	#8*4,r0
137de398406SYoshinori Sato	mov.l	r0,@-r2		! save old SP
138de398406SYoshinori Sato	mov.l	r14,@-r2
139de398406SYoshinori Sato	mov.l	r13,@-r2
140de398406SYoshinori Sato	mov.l	r12,@-r2
141de398406SYoshinori Sato	mov.l	r11,@-r2
142de398406SYoshinori Sato	mov.l	r10,@-r2
143de398406SYoshinori Sato	mov.l	r9,@-r2
144de398406SYoshinori Sato	mov.l	r8,@-r2
145de398406SYoshinori Sato	mov.l	r7,@-r2
146de398406SYoshinori Sato	mov.l	r6,@-r2
147de398406SYoshinori Sato	mov.l	r5,@-r2
148de398406SYoshinori Sato	mov.l	r4,@-r2
1496e80f5e8SYoshinori Sato	mov	r1,r9
150de398406SYoshinori Sato	mov.l	@(OFF_R0,r15),r0
151de398406SYoshinori Sato	mov.l	@(OFF_R1,r15),r1
152de398406SYoshinori Sato	mov.l	@(OFF_R2,r15),r2
153de398406SYoshinori Sato	mov.l	@(OFF_R3,r15),r3
154de398406SYoshinori Sato2:
155de398406SYoshinori Sato	mov	#64,r8
156de398406SYoshinori Sato	cmp/hs	r8,r9
157de398406SYoshinori Sato	bt	interrupt_entry	! vec >= 64 is interrupt
1583623d138SRich Felker	mov	#31,r8
159de398406SYoshinori Sato	cmp/hs	r8,r9
1603623d138SRich Felker	bt	trap_entry	! 64 > vec >= 31  is trap
1615a846abaSRich Felker#ifdef CONFIG_CPU_J2
1625a846abaSRich Felker	mov	#16,r8
1635a846abaSRich Felker	cmp/hs	r8,r9
1645a846abaSRich Felker	bt	interrupt_entry	! 31 > vec >= 16 is interrupt
1655a846abaSRich Felker#endif
16674d99a5eSPaul Mundt
167de398406SYoshinori Sato	mov.l	4f,r8
168de398406SYoshinori Sato	mov	r9,r4
169de398406SYoshinori Sato	shll2	r9
170de398406SYoshinori Sato	add	r9,r8
1716e80f5e8SYoshinori Sato	mov.l	@r8,r8		! exception handler address
1726e80f5e8SYoshinori Sato	tst	r8,r8
173de398406SYoshinori Sato	bf	3f
174de398406SYoshinori Sato	mov.l	8f,r8		! unhandled exception
175de398406SYoshinori Sato3:
176de398406SYoshinori Sato	mov.l	5f,r10
177de398406SYoshinori Sato	jmp	@r8
178de398406SYoshinori Sato	 lds	r10,pr
179de398406SYoshinori Sato
180de398406SYoshinori Satointerrupt_entry:
181de398406SYoshinori Sato	mov	r9,r4
1823afb209aSPaul Mundt	mov	r15,r5
183de398406SYoshinori Sato	mov.l	6f,r9
184de398406SYoshinori Sato	mov.l	7f,r8
185de398406SYoshinori Sato	jmp	@r8
186de398406SYoshinori Sato	 lds	r9,pr
187de398406SYoshinori Sato
188de398406SYoshinori Sato	.align	2
189de398406SYoshinori Sato4:	.long	exception_handling_table
190de398406SYoshinori Sato5:	.long	ret_from_exception
191de398406SYoshinori Sato6:	.long	ret_from_irq
192de398406SYoshinori Sato7:	.long	do_IRQ
1936e80f5e8SYoshinori Sato8:	.long	exception_error
194de398406SYoshinori Sato
195de398406SYoshinori Satotrap_entry:
1964aa362bbSYoshinori Sato	mov	#0x30,r8
1973623d138SRich Felker	cmp/ge	r8,r9		! vector 0x1f-0x2f is systemcall
1984aa362bbSYoshinori Sato	bt	1f
1993623d138SRich Felker	mov     #0x1f,r9	! convert to unified SH2/3/4 trap number
200e9cfc147SYoshinori Sato1:
201de398406SYoshinori Sato	shll2	r9			! TRA
2026e80f5e8SYoshinori Sato	bra	system_call	! jump common systemcall entry
203de398406SYoshinori Sato	 mov	r9,r8
204de398406SYoshinori Sato
205de398406SYoshinori Sato#if defined(CONFIG_SH_STANDARD_BIOS)
206de398406SYoshinori Sato	/* Unwind the stack and jmp to the debug entry */
207f413d0d9SPaul MundtENTRY(sh_bios_handler)
208de398406SYoshinori Sato	mov	r15,r0
209de398406SYoshinori Sato	add	#(22-4)*4-4,r0
210de398406SYoshinori Sato	ldc.l	@r0+,gbr
211de398406SYoshinori Sato	lds.l	@r0+,mach
212de398406SYoshinori Sato	lds.l	@r0+,macl
213de398406SYoshinori Sato	mov	r15,r0
214de398406SYoshinori Sato	mov.l	@(OFF_SP,r0),r1
215de398406SYoshinori Sato	mov	#OFF_SR,r2
216de398406SYoshinori Sato	mov.l	@(r0,r2),r3
217de398406SYoshinori Sato	mov.l	r3,@-r1
218de398406SYoshinori Sato	mov	#OFF_SP,r2
219de398406SYoshinori Sato	mov.l	@(r0,r2),r3
220de398406SYoshinori Sato	mov.l	r3,@-r1
221de398406SYoshinori Sato	mov	r15,r0
222de398406SYoshinori Sato	add	#(22-4)*4-8,r0
223de398406SYoshinori Sato	mov.l	1f,r2
224de398406SYoshinori Sato	mov.l	@r2,r2
225de398406SYoshinori Sato	stc	sr,r3
226de398406SYoshinori Sato	mov.l	r2,@r0
2276e80f5e8SYoshinori Sato	mov.l	r3,@(4,r0)
228de398406SYoshinori Sato	mov.l	r1,@(8,r0)
229de398406SYoshinori Sato	mov.l	@r15+, r0
230de398406SYoshinori Sato	mov.l	@r15+, r1
231de398406SYoshinori Sato	mov.l	@r15+, r2
232de398406SYoshinori Sato	mov.l	@r15+, r3
233de398406SYoshinori Sato	mov.l	@r15+, r4
234de398406SYoshinori Sato	mov.l	@r15+, r5
235de398406SYoshinori Sato	mov.l	@r15+, r6
236de398406SYoshinori Sato	mov.l	@r15+, r7
237de398406SYoshinori Sato	mov.l	@r15+, r8
238de398406SYoshinori Sato	mov.l	@r15+, r9
239de398406SYoshinori Sato	mov.l	@r15+, r10
240de398406SYoshinori Sato	mov.l	@r15+, r11
241de398406SYoshinori Sato	mov.l	@r15+, r12
242de398406SYoshinori Sato	mov.l	@r15+, r13
243de398406SYoshinori Sato	mov.l	@r15+, r14
244de398406SYoshinori Sato	add	#8,r15
245de398406SYoshinori Sato	lds.l	@r15+, pr
246de398406SYoshinori Sato	mov.l	@r15+,r15
2477a90e00dSPaul Mundt	rte
2487a90e00dSPaul Mundt	 nop
249de398406SYoshinori Sato	.align	2
250de398406SYoshinori Sato1:	.long	gdb_vbr_vector
251de398406SYoshinori Sato#endif /* CONFIG_SH_STANDARD_BIOS */
252de398406SYoshinori Sato
2535a4f7c66SPaul MundtENTRY(address_error_trap_handler)
254de398406SYoshinori Sato	mov	r15,r4				! regs
255de398406SYoshinori Sato	mov	#OFF_PC,r0
256de398406SYoshinori Sato	mov.l	@(r0,r15),r6			! pc
257de398406SYoshinori Sato	mov.l	1f,r0
258de398406SYoshinori Sato	jmp	@r0
259de398406SYoshinori Sato	 mov	#0,r5				! writeaccess is unknown
260de398406SYoshinori Sato
2616e80f5e8SYoshinori Sato	.align	2
262de398406SYoshinori Sato1:	.long	do_address_error
263de398406SYoshinori Sato
264de398406SYoshinori Satorestore_all:
2656e80f5e8SYoshinori Sato	stc	sr,r0
2666e80f5e8SYoshinori Sato	or	#0xf0,r0
2676e80f5e8SYoshinori Sato	ldc	r0,sr				! all interrupt block (same BL = 1)
2686e80f5e8SYoshinori Sato	! restore special register
2696e80f5e8SYoshinori Sato	! overlap exception frame
2706e80f5e8SYoshinori Sato	mov	r15,r0
2716e80f5e8SYoshinori Sato	add	#17*4,r0
2726e80f5e8SYoshinori Sato	lds.l	@r0+,pr
2736e80f5e8SYoshinori Sato	add	#4,r0
2746e80f5e8SYoshinori Sato	ldc.l	@r0+,gbr
2756e80f5e8SYoshinori Sato	lds.l	@r0+,mach
2766e80f5e8SYoshinori Sato	lds.l	@r0+,macl
277de398406SYoshinori Sato	mov	r15,r0
278de398406SYoshinori Sato	mov.l	$cpu_mode,r2
2794b6ef05bSRich Felker#ifdef CONFIG_SMP
2804b6ef05bSRich Felker	mov.l	$cpuid,r3
2814b6ef05bSRich Felker	mov.l	@r3,r3
2824b6ef05bSRich Felker	mov.l	@r3,r3
2834b6ef05bSRich Felker	shll2	r3
2844b6ef05bSRich Felker	add	r3,r2
2854b6ef05bSRich Felker#endif
286de398406SYoshinori Sato	mov	#OFF_SR,r3
287de398406SYoshinori Sato	mov.l	@(r0,r3),r1
2886e80f5e8SYoshinori Sato	mov.l	__md_bit,r3
2896e80f5e8SYoshinori Sato	and	r1,r3				! copy MD bit
2906e80f5e8SYoshinori Sato	mov.l	r3,@r2
291de398406SYoshinori Sato	shll2	r1				! clear MD bit
292de398406SYoshinori Sato	shlr2	r1
293de398406SYoshinori Sato	mov.l	@(OFF_SP,r0),r2
294de398406SYoshinori Sato	add	#-8,r2
295de398406SYoshinori Sato	mov.l	r2,@(OFF_SP,r0)			! point exception frame top
296de398406SYoshinori Sato	mov.l	r1,@(4,r2)			! set sr
297de398406SYoshinori Sato	mov	#OFF_PC,r3
298de398406SYoshinori Sato	mov.l	@(r0,r3),r1
299de398406SYoshinori Sato	mov.l	r1,@r2				! set pc
300de398406SYoshinori Sato	get_current_thread_info r0, r1
301de398406SYoshinori Sato	mov.l	$current_thread_info,r1
3024b6ef05bSRich Felker#ifdef CONFIG_SMP
3034b6ef05bSRich Felker	mov.l	$cpuid,r3
3044b6ef05bSRich Felker	mov.l	@r3,r3
3054b6ef05bSRich Felker	mov.l	@r3,r3
3064b6ef05bSRich Felker	shll2	r3
3074b6ef05bSRich Felker	add	r3,r1
3084b6ef05bSRich Felker#endif
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
3306e80f5e8SYoshinori Sato__md_bit:
3316e80f5e8SYoshinori Sato	.long	0x40000000
332de398406SYoshinori Sato$current_thread_info:
333de398406SYoshinori Sato	.long	__current_thread_info
334de398406SYoshinori Sato$cpu_mode:
335de398406SYoshinori Sato	.long	__cpu_mode
3364b6ef05bSRich Felker#ifdef CONFIG_SMP
3374b6ef05bSRich Felker$cpuid:
3384b6ef05bSRich Felker	.long sh2_cpuid_addr
3394b6ef05bSRich Felker#endif
340de398406SYoshinori Sato
341de398406SYoshinori Sato! common exception handler
342de398406SYoshinori Sato#include "../../entry-common.S"
343de398406SYoshinori Sato
3444b6ef05bSRich Felker#ifdef CONFIG_NR_CPUS
3454b6ef05bSRich Felker#define NR_CPUS CONFIG_NR_CPUS
3464b6ef05bSRich Felker#else
3474b6ef05bSRich Felker#define NR_CPUS 1
3484b6ef05bSRich Felker#endif
3494b6ef05bSRich Felker
350de398406SYoshinori Sato	.data
351de398406SYoshinori Sato! cpu operation mode
352de398406SYoshinori Sato! bit30 = MD (compatible SH3/4)
353de398406SYoshinori Sato__cpu_mode:
3544b6ef05bSRich Felker	.rept	NR_CPUS
355de398406SYoshinori Sato	.long	0x40000000
3564b6ef05bSRich Felker	.endr
3574b6ef05bSRich Felker
3584b6ef05bSRich Felker#ifdef CONFIG_SMP
3594b6ef05bSRich Felker.global sh2_cpuid_addr
3604b6ef05bSRich Felkersh2_cpuid_addr:
3614b6ef05bSRich Felker	.long	dummy_cpuid
3624b6ef05bSRich Felkerdummy_cpuid:
3634b6ef05bSRich Felker	.long	0
3644b6ef05bSRich Felker#endif
365de398406SYoshinori Sato
366de398406SYoshinori Sato	.section	.bss
367de398406SYoshinori Sato__current_thread_info:
3684b6ef05bSRich Felker	.rept	NR_CPUS
369de398406SYoshinori Sato	.long	0
3704b6ef05bSRich Felker	.endr
371de398406SYoshinori Sato
372de398406SYoshinori SatoENTRY(exception_handling_table)
373de398406SYoshinori Sato	.space	4*32
374