linux/arch/nds32/kernel/ex-scall.S
<<
>>
Prefs
   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
  18ENTRY(__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
  48ENTRY(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
  60jmp_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
  97ENTRY(sys_rt_sigreturn_wrapper)
  98        addi    $r0, $sp, #0
  99        b       sys_rt_sigreturn
 100ENDPROC(sys_rt_sigreturn_wrapper)
 101