diff options
Diffstat (limited to 'arch/sh/kernel/entry-common.S')
| -rw-r--r-- | arch/sh/kernel/entry-common.S | 110 |
1 files changed, 61 insertions, 49 deletions
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index 9b6e4beeb296..91ab2607a1ff 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -1,11 +1,7 @@ -/* +/* SPDX-License-Identifier: GPL-2.0 + * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka * Copyright (C) 2003 - 2008 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * */ ! NOTE: @@ -45,7 +41,7 @@ */ #include <asm/dwarf.h> -#if defined(CONFIG_PREEMPT) +#if defined(CONFIG_PREEMPTION) # define preempt_stop() cli ; TRACE_IRQS_OFF #else # define preempt_stop() @@ -88,7 +84,7 @@ ENTRY(ret_from_irq) get_current_thread_info r8, r0 bt resume_kernel ! Yes, it's from kernel, go back soon -#ifdef CONFIG_PREEMPT +#ifdef CONFIG_PREEMPTION bra resume_userspace nop ENTRY(resume_kernel) @@ -108,7 +104,7 @@ need_resched: and #(0xf0>>1), r0 ! interrupts off (exception path)? cmp/eq #(0xf0>>1), r0 bt noresched - mov.l 3f, r0 + mov.l 1f, r0 jsr @r0 ! call preempt_schedule_irq nop bra need_resched @@ -119,9 +115,7 @@ noresched: nop .align 2 -1: .long PREEMPT_ACTIVE -2: .long schedule -3: .long preempt_schedule_irq +1: .long preempt_schedule_irq #endif ENTRY(resume_userspace) @@ -184,34 +178,6 @@ syscall_exit_work: bra resume_userspace nop - .align 2 -syscall_trace_entry: - ! Yes it is traced. - mov r15, r4 - mov.l 7f, r11 ! Call do_syscall_trace_enter which notifies - jsr @r11 ! superior (will chomp R[0-7]) - nop - mov.l r0, @(OFF_R0,r15) ! Save return value - ! Reload R0-R4 from kernel stack, where the - ! parent may have modified them using - ! ptrace(POKEUSR). (Note that R0-R2 are - ! used by the system call handler directly - ! from the kernel stack anyway, so don't need - ! to be reloaded here.) This allows the parent - ! to rewrite system calls and args on the fly. - mov.l @(OFF_R4,r15), r4 ! arg0 - mov.l @(OFF_R5,r15), r5 - mov.l @(OFF_R6,r15), r6 - mov.l @(OFF_R7,r15), r7 ! arg3 - mov.l @(OFF_R3,r15), r3 ! syscall_nr - ! - mov.l 2f, r10 ! Number of syscalls - cmp/hs r10, r3 - bf syscall_call - mov #-ENOSYS, r0 - bra syscall_exit - mov.l r0, @(OFF_R0,r15) ! Return value - __restore_all: mov #OFF_SR, r0 mov.l @(r0,r15), r0 ! get status register @@ -257,7 +223,7 @@ debug_trap: mov.l @r8, r8 jsr @r8 nop - bra __restore_all + bra ret_from_exception nop CFI_ENDPROC @@ -270,20 +236,29 @@ debug_trap: * Syscall #: R3 * Arguments #0 to #3: R4--R7 * Arguments #4 to #6: R0, R1, R2 - * TRA: (number of arguments + ABI revision) x 4 + * TRA: See following table. * - * This code also handles delegating other traps to the BIOS/gdb stub - * according to: - * - * Trap number * (TRA>>2) Purpose * -------- ------- * 0x00-0x0f original SH-3/4 syscall ABI (not in general use). * 0x10-0x1f general SH-3/4 syscall ABI. - * 0x20-0x2f syscall ABI for SH-2 parts. + * 0x1f unified SH-2/3/4 syscall ABI (preferred). + * 0x20-0x2f original SH-2 syscall ABI. * 0x30-0x3f debug traps used by the kernel. * 0x40-0xff Not supported by all parts, so left unhandled. * + * For making system calls, any trap number in the range for the + * given cpu model may be used, but the unified trap number 0x1f is + * preferred for compatibility with all models. + * + * The low bits of the trap number were once documented as matching + * the number of arguments, but they were never actually used as such + * by the kernel. SH-2 originally used its own separate trap range + * because several hardware exceptions fell in the range used for the + * SH-3/4 syscall ABI. + * + * This code also handles delegating other traps to the BIOS/gdb stub. + * * Note: When we're first called, the TRA value must be shifted * right 2 bits in order to get the value that was used as the "trapa" * argument. @@ -350,7 +325,7 @@ ENTRY(system_call) tst r9, r8 bf syscall_trace_entry ! - mov.l 2f, r8 ! Number of syscalls + mov.l 6f, r8 ! Number of syscalls cmp/hs r8, r3 bt syscall_badsys ! @@ -359,8 +334,15 @@ syscall_call: mov.l 3f, r8 ! Load the address of sys_call_table add r8, r3 mov.l @r3, r8 + mov.l @(OFF_R2,r15), r2 + mov.l @(OFF_R1,r15), r1 + mov.l @(OFF_R0,r15), r0 + mov.l r2, @-r15 + mov.l r1, @-r15 + mov.l r0, @-r15 jsr @r8 ! jump to specific syscall handler nop + add #12, r15 mov.l @(OFF_R0,r15), r12 ! save r0 mov.l r0, @(OFF_R0,r15) ! save the return value ! @@ -378,11 +360,41 @@ syscall_exit: bf syscall_exit_work bra __restore_all nop + + .align 2 +syscall_trace_entry: + ! Yes it is traced. + mov r15, r4 + mov.l 7f, r11 ! Call do_syscall_trace_enter which notifies + jsr @r11 ! superior (will chomp R[0-7]) + nop + cmp/eq #-1, r0 + bt syscall_exit + ! Reload R0-R4 from kernel stack, where the + ! parent may have modified them using + ! ptrace(POKEUSR). (Note that R0-R2 are + ! reloaded from the kernel stack by syscall_call + ! below, so don't need to be reloaded here.) + ! This allows the parent to rewrite system calls + ! and args on the fly. + mov.l @(OFF_R4,r15), r4 ! arg0 + mov.l @(OFF_R5,r15), r5 + mov.l @(OFF_R6,r15), r6 + mov.l @(OFF_R7,r15), r7 ! arg3 + mov.l @(OFF_R3,r15), r3 ! syscall_nr + ! + mov.l 6f, r10 ! Number of syscalls + cmp/hs r10, r3 + bf syscall_call + mov #-ENOSYS, r0 + bra syscall_exit + mov.l r0, @(OFF_R0,r15) ! Return value + .align 2 #if !defined(CONFIG_CPU_SH2) 1: .long TRA #endif -2: .long NR_syscalls +6: .long NR_syscalls 3: .long sys_call_table 7: .long do_syscall_trace_enter 8: .long do_syscall_trace_leave |
