1 /* 2 * This file is subject to the terms and condi 3 * License. See the file "COPYING" in the mai 4 * for more details. 5 * 6 * Copyright (C) 1995 - 2000, 2001 by Ralf Bae 7 * Copyright (C) 1999, 2000 Silicon Graphics, 8 * Copyright (C) 2001 MIPS Technologies, Inc. 9 * Copyright (C) 2004 Thiemo Seufer 10 * 11 * Hairy, the userspace application uses a dif 12 * convention than the kernel, so we have to t 13 * to ABI64 calling convention. 64-bit syscal 14 * here for now. 15 */ 16 #include <linux/errno.h> 17 #include <asm/asm.h> 18 #include <asm/asmmacro.h> 19 #include <asm/irqflags.h> 20 #include <asm/mipsregs.h> 21 #include <asm/regdef.h> 22 #include <asm/stackframe.h> 23 #include <asm/thread_info.h> 24 #include <asm/unistd.h> 25 #include <asm/sysmips.h> 26 27 .align 5 28 NESTED(handle_sys, PT_SIZE, sp) 29 .set noat 30 SAVE_SOME 31 TRACE_IRQS_ON_RELOAD 32 STI 33 .set at 34 ld t1, PT_EPC(sp) # skip 35 36 dsubu t0, v0, __NR_O32_Linux # chec 37 sltiu t0, t0, __NR_O32_Linux_syscall 38 daddiu t1, 4 # skip 39 sd t1, PT_EPC(sp) 40 beqz t0, not_o32_scall 41 #if 0 42 SAVE_ALL 43 move a1, v0 44 ASM_PRINT("Scall %ld\n") 45 RESTORE_ALL 46 #endif 47 48 /* We don't want to stumble over broke 49 userland. O32 does never use the up 50 sll a0, a0, 0 51 sll a1, a1, 0 52 sll a2, a2, 0 53 sll a3, a3, 0 54 55 sd a3, PT_R26(sp) # save 56 57 /* 58 * More than four arguments. Try to d 59 * stack arguments from the user stack 60 * This Sucks (TM). 61 * 62 * We intentionally keep the kernel st 63 * userspace so we don't have to do a 64 */ 65 ld t0, PT_R29(sp) # get 66 daddu t1, t0, 32 67 bltz t1, bad_stack 68 69 load_a4: lw a4, 16(t0) # argu 70 load_a5: lw a5, 20(t0) # argu 71 load_a6: lw a6, 24(t0) # argu 72 load_a7: lw a7, 28(t0) # argu 73 loads_done: 74 75 .section __ex_table,"a" 76 PTR_WD load_a4, bad_stack_a4 77 PTR_WD load_a5, bad_stack_a5 78 PTR_WD load_a6, bad_stack_a6 79 PTR_WD load_a7, bad_stack_a7 80 .previous 81 82 /* 83 * absolute syscall number is in v0 un 84 * where the real syscall number is in 85 * note: NR_syscall is the first O32 s 86 * only defined when compiling with -m 87 * therefore __NR_O32_Linux is used (4 88 */ 89 90 subu t2, v0, __NR_O32_Linux 91 bnez t2, 1f /* __NR_syscall at offs 92 LONG_S a0, TI_SYSCALL($28) # Save 93 b 2f 94 1: 95 LONG_S v0, TI_SYSCALL($28) # Save 96 2: 97 98 li t1, _TIF_WORK_SYSCALL_ENTRY 99 LONG_L t0, TI_FLAGS($28) # sysc 100 and t0, t1, t0 101 bnez t0, trace_a_syscall 102 103 syscall_common: 104 dsll t0, v0, 3 # offs 105 ld t2, (sys32_call_table - (__NR_ 106 107 jalr t2 # Do T 108 109 li t0, -EMAXERRNO - 1 # erro 110 sltu t0, t0, v0 111 sd t0, PT_R7(sp) # set 112 beqz t0, 1f 113 114 ld t1, PT_R2(sp) # sysc 115 dnegu v0 # erro 116 sd t1, PT_R0(sp) # save 117 1: sd v0, PT_R2(sp) # resu 118 119 o32_syscall_exit: 120 j syscall_exit_partial 121 122 /* ------------------------------------------- 123 124 trace_a_syscall: 125 SAVE_STATIC 126 sd a4, PT_R8(sp) # Save 127 sd a5, PT_R9(sp) 128 sd a6, PT_R10(sp) 129 sd a7, PT_R11(sp) # For 130 131 move a0, sp 132 jal syscall_trace_enter 133 134 bltz v0, 1f # secc 135 136 RESTORE_STATIC 137 ld v0, PT_R2(sp) # Rest 138 ld a0, PT_R4(sp) # Rest 139 ld a1, PT_R5(sp) 140 ld a2, PT_R6(sp) 141 ld a3, PT_R7(sp) 142 ld a4, PT_R8(sp) 143 ld a5, PT_R9(sp) 144 ld a6, PT_R10(sp) 145 ld a7, PT_R11(sp) # For 146 147 dsubu t0, v0, __NR_O32_Linux # chec 148 sltiu t0, t0, __NR_O32_Linux_syscall 149 beqz t0, not_o32_scall 150 151 j syscall_common 152 153 1: j syscall_exit 154 155 /* ------------------------------------------- 156 157 /* 158 * The stackpointer for a call with mo 159 */ 160 bad_stack: 161 li v0, EFAULT 162 sd v0, PT_R2(sp) 163 li t0, 1 # set 164 sd t0, PT_R7(sp) 165 j o32_syscall_exit 166 167 bad_stack_a4: 168 li a4, 0 169 b load_a5 170 171 bad_stack_a5: 172 li a5, 0 173 b load_a6 174 175 bad_stack_a6: 176 li a6, 0 177 b load_a7 178 179 bad_stack_a7: 180 li a7, 0 181 b loads_done 182 183 not_o32_scall: 184 /* 185 * This is not an o32 compatibility sy 186 * to the 64-bit syscall handlers. 187 */ 188 #ifdef CONFIG_MIPS32_N32 189 j handle_sysn32 190 #else 191 j handle_sys64 192 #endif 193 END(handle_sys) 194 195 LEAF(sys32_syscall) 196 subu t0, a0, __NR_O32_Linux # chec 197 sltiu v0, t0, __NR_O32_Linux_syscall 198 beqz t0, einval # do n 199 dsll t1, t0, 3 200 beqz v0, einval 201 ld t2, sys32_call_table(t1) 202 203 move a0, a1 # shif 204 move a1, a2 205 move a2, a3 206 move a3, a4 207 move a4, a5 208 move a5, a6 209 move a6, a7 210 jr t2 211 /* Unreached */ 212 213 einval: li v0, -ENOSYS 214 jr ra 215 END(sys32_syscall) 216 217 #define __SYSCALL_WITH_COMPAT(nr, native, comp 218 #define __SYSCALL(nr, entry) PTR_WD entry 219 .align 3 220 .type sys32_call_table,@object 221 EXPORT(sys32_call_table) 222 #include <asm/syscall_table_o32.h>
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.