root/arch/nds32/kernel/ex-scall.S

/* [<][>][^][v][top][bottom][index][help] */
   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)

/* [<][>][^][v][top][bottom][index][help] */