Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / arch / nds32 / kernel / ex-scall.S
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2005-2017 Andes Technology Corporation
3
4 #include <linux/linkage.h>
5 #include <asm/unistd.h>
6 #include <asm/assembler.h>
7 #include <asm/nds32.h>
8 #include <asm/asm-offsets.h>
9 #include <asm/thread_info.h>
10 #include <asm/current.h>
11
12 /*
13  * $r0 = previous task_struct,
14  * $r1 = next task_struct,
15  * previous and next are guaranteed not to be the same.
16  */
17
18 ENTRY(__switch_to)
19
20         la      $p0, __entry_task
21         sw      $r1, [$p0]
22         addi    $p1, $r0, #THREAD_CPU_CONTEXT
23         smw.bi  $r6, [$p1], $r14, #0xb          ! push r6~r14, fp, lp, sp
24         move    $r25, $r1
25 #if defined(CONFIG_FPU)
26         call    _switch_fpu
27 #endif
28         addi    $r1, $r25, #THREAD_CPU_CONTEXT
29         lmw.bi  $r6, [$r1], $r14, #0xb          ! pop r6~r14, fp, lp, sp
30         ret
31
32
33 #define tbl $r8
34
35 /*
36  * $r7 will be writen as syscall nr
37  */
38         .macro  get_scno
39         lwi     $r7, [$sp + R15_OFFSET]
40         swi     $r7, [$sp + SYSCALLNO_OFFSET]
41         .endm
42
43         .macro  updateipc
44         addi    $r17, $r13, #4                          ! $r13 is $IPC
45         swi     $r17, [$sp + IPC_OFFSET]
46         .endm
47
48 ENTRY(eh_syscall)
49         updateipc
50
51         get_scno
52         gie_enable
53
54         lwi     $p0, [tsk+#TSK_TI_FLAGS]                ! check for syscall tracing
55
56         andi    $p1, $p0, #_TIF_WORK_SYSCALL_ENTRY      ! are we tracing syscalls?
57         bnez    $p1, __sys_trace
58
59         la      $lp, ret_fast_syscall           ! return address
60 jmp_systbl:
61         addi    $p1, $r7, #-__NR_syscalls       ! syscall number of syscall instruction is guarded by addembler
62         bgez    $p1, _SCNO_EXCEED               ! call sys_* routine
63         la      tbl, sys_call_table             ! load syscall table pointer
64         slli    $p1, $r7, #2
65         add     $p1, tbl, $p1
66         lwi     $p1, [$p1]
67         jr      $p1                             ! no return
68
69 _SCNO_EXCEED:
70         ori     $r0, $r7, #0
71         ori     $r1, $sp, #0
72         b       bad_syscall
73
74 /*
75  * This is the really slow path.  We're going to be doing
76  * context switches, and waiting for our parent to respond.
77  */
78 __sys_trace:
79         move    $r0, $sp
80         bal     syscall_trace_enter
81         move    $r7, $r0
82         la      $lp, __sys_trace_return         ! return address
83
84         addi    $p1, $r7, #1
85         beqz    $p1, ret_slow_syscall           ! fatal signal is pending
86
87         addi    $p1, $sp, #R0_OFFSET            ! pointer to regs
88         lmw.bi  $r0, [$p1], $r5                 ! have to reload $r0 - $r5
89         b       jmp_systbl
90
91 __sys_trace_return:
92         swi     $r0, [$sp+#R0_OFFSET]           ! T: save returned $r0
93         move    $r0, $sp                        ! set pt_regs for syscall_trace_leave
94         bal     syscall_trace_leave
95         b       ret_slow_syscall
96
97 ENTRY(sys_rt_sigreturn_wrapper)
98         addi    $r0, $sp, #0
99         b       sys_rt_sigreturn
100 ENDPROC(sys_rt_sigreturn_wrapper)