linux/arch/nds32/kernel/ex-scall.S
Vincent Chen e46bf83c18 nds32: nds32 FPU port
This patch set contains basic components for supporting the nds32 FPU,
such as exception handlers and context switch for FPU registers. By
default, the lazy FPU scheme is supported and the user can configure it via
CONFIG_LZAY_FPU.

Signed-off-by: Vincent Chen <vincentc@andestech.com>
Acked-by: Greentime Hu <greentime@andestech.com>
Signed-off-by: Greentime Hu <greentime@andestech.com>
2018-11-22 18:13:13 +08:00

101 lines
2.2 KiB
ArmAsm

// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2005-2017 Andes Technology Corporation
#include <linux/linkage.h>
#include <asm/unistd.h>
#include <asm/assembler.h>
#include <asm/nds32.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/current.h>
/*
* $r0 = previous task_struct,
* $r1 = next task_struct,
* previous and next are guaranteed not to be the same.
*/
ENTRY(__switch_to)
la $p0, __entry_task
sw $r1, [$p0]
addi $p1, $r0, #THREAD_CPU_CONTEXT
smw.bi $r6, [$p1], $r14, #0xb ! push r6~r14, fp, lp, sp
move $r25, $r1
#if defined(CONFIG_FPU)
call _switch_fpu
#endif
addi $r1, $r25, #THREAD_CPU_CONTEXT
lmw.bi $r6, [$r1], $r14, #0xb ! pop r6~r14, fp, lp, sp
ret
#define tbl $r8
/*
* $r7 will be writen as syscall nr
*/
.macro get_scno
lwi $r7, [$sp + R15_OFFSET]
swi $r7, [$sp + SYSCALLNO_OFFSET]
.endm
.macro updateipc
addi $r17, $r13, #4 ! $r13 is $IPC
swi $r17, [$sp + IPC_OFFSET]
.endm
ENTRY(eh_syscall)
updateipc
get_scno
gie_enable
lwi $p0, [tsk+#TSK_TI_FLAGS] ! check for syscall tracing
andi $p1, $p0, #_TIF_WORK_SYSCALL_ENTRY ! are we tracing syscalls?
bnez $p1, __sys_trace
la $lp, ret_fast_syscall ! return address
jmp_systbl:
addi $p1, $r7, #-__NR_syscalls ! syscall number of syscall instruction is guarded by addembler
bgez $p1, _SCNO_EXCEED ! call sys_* routine
la tbl, sys_call_table ! load syscall table pointer
slli $p1, $r7, #2
add $p1, tbl, $p1
lwi $p1, [$p1]
jr $p1 ! no return
_SCNO_EXCEED:
ori $r0, $r7, #0
ori $r1, $sp, #0
b bad_syscall
/*
* This is the really slow path. We're going to be doing
* context switches, and waiting for our parent to respond.
*/
__sys_trace:
move $r0, $sp
bal syscall_trace_enter
move $r7, $r0
la $lp, __sys_trace_return ! return address
addi $p1, $r7, #1
beqz $p1, ret_slow_syscall ! fatal signal is pending
addi $p1, $sp, #R0_OFFSET ! pointer to regs
lmw.bi $r0, [$p1], $r5 ! have to reload $r0 - $r5
b jmp_systbl
__sys_trace_return:
swi $r0, [$sp+#R0_OFFSET] ! T: save returned $r0
move $r0, $sp ! set pt_regs for syscall_trace_leave
bal syscall_trace_leave
b ret_slow_syscall
ENTRY(sys_rt_sigreturn_wrapper)
addi $r0, $sp, #0
b sys_rt_sigreturn
ENDPROC(sys_rt_sigreturn_wrapper)