ex-scall.S 2.2 KB

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