1 /* SPDX-License-Identifier: GPL-2.0
3 * arch/sh/kernel/cpu/sh2/entry.S
5 * The SH-2 exception entry
7 * Copyright (C) 2005-2008 Yoshinori Sato
8 * Copyright (C) 2005 AXE,Inc.
11 #include <linux/linkage.h>
12 #include <asm/asm-offsets.h>
13 #include <asm/thread_info.h>
14 #include <cpu/mmu_context.h>
15 #include <asm/unistd.h>
16 #include <asm/errno.h>
19 /* Offsets to the stack */
20 OFF_R0 = 0 /* Return value. New ABI also arg4 */
21 OFF_R1 = 4 /* New ABI: arg5 */
22 OFF_R2 = 8 /* New ABI: arg6 */
23 OFF_R3 = 12 /* New ABI: syscall_nr */
24 OFF_R4 = 16 /* New ABI: arg0 */
25 OFF_R5 = 20 /* New ABI: arg1 */
26 OFF_R6 = 24 /* New ABI: arg2 */
27 OFF_R7 = 28 /* New ABI: arg3 */
33 #include <asm/entry-macros.S>
35 ENTRY(exception_handler)
42 ! r1 = vector (pseudo EXPEVT / INTEVT / TRA)
55 mov.l @(5*4,r15),r3 ! previous SR
58 bf/s 1f ! previous mode check
59 mov.l r3,@(5*4,r15) ! update SR
60 ! switch to kernel mode
62 mov.l r0,@r2 ! enter kernel mode
63 mov.l $current_thread_info,r2
72 mov #(THREAD_SIZE >> 8),r0
75 mov r15,r2 ! r2 = user stack top
76 mov r0,r15 ! switch kernel stack
82 mov.l r0,@-r15 ! original SR
85 mov.l r0,@-r15 ! original PC
87 add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame
88 mov.l r3,@-r15 ! original SP
101 mov r2,r8 ! copy user -> kernel stack
112 ! in kernel exception
113 mov #(22-4-4-1)*4+4,r0
116 mov.l @r2+,r0 ! old R3
118 mov.l @r2+,r0 ! old R2
120 mov.l @(4,r2),r0 ! old R1
122 mov.l @r2,r0 ! old R0
125 mov.l @r2+,r3 ! old PC
126 mov.l @r2+,r0 ! old SR
127 add #-4,r2 ! exception frame stub (sr)
132 mov.l r0,@-r2 ! save old SR
134 mov.l r3,@-r2 ! save old PC
137 mov.l r0,@-r2 ! save old SP
150 mov.l @(OFF_R0,r15),r0
151 mov.l @(OFF_R1,r15),r1
152 mov.l @(OFF_R2,r15),r2
153 mov.l @(OFF_R3,r15),r3
157 bt interrupt_entry ! vec >= 64 is interrupt
160 bt trap_entry ! 64 > vec >= 31 is trap
164 bt interrupt_entry ! 31 > vec >= 16 is interrupt
171 mov.l @r8,r8 ! exception handler address
174 mov.l 8f,r8 ! unhandled exception
189 4: .long exception_handling_table
190 5: .long ret_from_exception
191 6: .long ret_from_irq
193 8: .long exception_error
197 cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall
199 mov #0x1f,r9 ! convert to unified SH2/3/4 trap number
202 bra system_call ! jump common systemcall entry
205 #if defined(CONFIG_SH_STANDARD_BIOS)
206 /* Unwind the stack and jmp to the debug entry */
207 ENTRY(sh_bios_handler)
214 mov.l @(OFF_SP,r0),r1
250 1: .long gdb_vbr_vector
251 #endif /* CONFIG_SH_STANDARD_BIOS */
253 ENTRY(address_error_trap_handler)
256 mov.l @(r0,r15),r6 ! pc
259 mov #0,r5 ! writeaccess is unknown
262 1: .long do_address_error
267 ldc r0,sr ! all interrupt block (same BL = 1)
268 ! restore special register
269 ! overlap exception frame
289 and r1,r3 ! copy MD bit
291 shll2 r1 ! clear MD bit
293 mov.l @(OFF_SP,r0),r2
295 mov.l r2,@(OFF_SP,r0) ! point exception frame top
296 mov.l r1,@(4,r2) ! set sr
299 mov.l r1,@r2 ! set pc
300 get_current_thread_info r0, r1
301 mov.l $current_thread_info,r1
332 $current_thread_info:
333 .long __current_thread_info
341 ! common exception handler
342 #include "../../entry-common.S"
344 #ifdef CONFIG_NR_CPUS
345 #define NR_CPUS CONFIG_NR_CPUS
352 ! bit30 = MD (compatible SH3/4)
359 .global sh2_cpuid_addr
367 __current_thread_info:
372 ENTRY(exception_handling_table)