1 /* 1 /* 2 * linux/arch/nios2/kernel/entry.S !! 2 * arch/alpha/kernel/entry.S 3 * 3 * 4 * Copyright (C) 2013-2014 Altera Corporation !! 4 * Kernel entry-points. 5 * Copyright (C) 2009, Wind River Systems Inc << 6 * << 7 * Implemented by fredrik.markstrom@gmail.com << 8 * << 9 * Copyright (C) 1999-2002, Greg Ungerer (ger << 10 * Copyright (C) 1998 D. Jeff Dionne <jeff@li << 11 * Kenneth Albanowski <kja << 12 * Copyright (C) 2000 Lineo Inc. (www.lineo. << 13 * Copyright (C) 2004 Microtronix Datacom Lt << 14 * << 15 * This file is subject to the terms and condi << 16 * License. See the file "COPYING" in the mai << 17 * for more details. << 18 * << 19 * Linux/m68k support by Hamish Macdonald << 20 * << 21 * 68060 fixes by Jesper Skov << 22 * ColdFire support by Greg Ungerer (gerg@snap << 23 * 5307 fixes by David W. Miller << 24 * linux 2.4 support David McCullough <davidm@s << 25 */ 5 */ 26 6 27 #include <linux/sys.h> << 28 #include <linux/linkage.h> << 29 #include <asm/asm-offsets.h> 7 #include <asm/asm-offsets.h> 30 #include <asm/asm-macros.h> << 31 #include <asm/thread_info.h> 8 #include <asm/thread_info.h> >> 9 #include <asm/pal.h> 32 #include <asm/errno.h> 10 #include <asm/errno.h> 33 #include <asm/setup.h> << 34 #include <asm/entry.h> << 35 #include <asm/unistd.h> 11 #include <asm/unistd.h> 36 #include <asm/processor.h> << 37 12 38 .macro GET_THREAD_INFO reg !! 13 .text 39 .if THREAD_SIZE & 0xffff0000 !! 14 .set noat 40 andhi \reg, sp, %hi(~(THREAD_SIZE-1) << 41 .else << 42 addi \reg, r0, %lo(~(THREAD_SIZE-1) << 43 and \reg, \reg, sp << 44 .endif << 45 .endm << 46 15 47 .macro kuser_cmpxchg_check !! 16 /* Stack offsets. */ 48 /* !! 17 #define SP_OFF 184 49 * Make sure our user space atomic hel !! 18 #define SWITCH_STACK_SIZE 320 50 * interrupted in a critical region. << 51 * ea-4 = address of interrupted insn << 52 * sp = saved regs. << 53 * cmpxchg_ldw = first critical insn, << 54 * If ea <= cmpxchg_stw and ea > cmpxc << 55 * cmpxchg_ldw + 4. << 56 */ << 57 /* et = cmpxchg_stw + 4 */ << 58 movui et, (KUSER_BASE + 4 + (cmpxchg << 59 bgtu ea, et, 1f << 60 << 61 subi et, et, (cmpxchg_stw - cmpxchg << 62 bltu ea, et, 1f << 63 stw et, PT_EA(sp) /* fix up EA * << 64 mov ea, et << 65 1: << 66 .endm << 67 << 68 .section .rodata << 69 .align 4 << 70 exception_table: << 71 .word unhandled_exception /* 0 - << 72 .word unhandled_exception /* 1 - << 73 .word external_interrupt /* 2 - << 74 .word handle_trap /* 3 - << 75 << 76 .word instruction_trap /* 4 - << 77 .word handle_illegal /* 5 - << 78 .word handle_unaligned /* 6 - << 79 .word handle_unaligned /* 7 - << 80 << 81 .word handle_diverror /* 8 - << 82 .word protection_exception_ba /* 9 - << 83 .word protection_exception_instr /* 10 << 84 .word protection_exception_ba /* 11 << 85 << 86 .word unhandled_exception /* 12 << 87 .word protection_exception_pte /* 13 << 88 .word protection_exception_pte /* 14 << 89 .word protection_exception_pte /* 15 << 90 << 91 .word unhandled_exception /* 16 << 92 << 93 trap_table: << 94 .word handle_system_call /* 0 << 95 .word handle_trap_1 /* 1 << 96 .word handle_trap_2 /* 2 << 97 .word handle_trap_3 /* 3 << 98 .word handle_trap_reserved /* 4 << 99 .word handle_trap_reserved /* 5 << 100 .word handle_trap_reserved /* 6 << 101 .word handle_trap_reserved /* 7 << 102 .word handle_trap_reserved /* 8 << 103 .word handle_trap_reserved /* 9 << 104 .word handle_trap_reserved /* 10 << 105 .word handle_trap_reserved /* 11 << 106 .word handle_trap_reserved /* 12 << 107 .word handle_trap_reserved /* 13 << 108 .word handle_trap_reserved /* 14 << 109 .word handle_trap_reserved /* 15 << 110 .word handle_trap_reserved /* 16 << 111 .word handle_trap_reserved /* 17 << 112 .word handle_trap_reserved /* 18 << 113 .word handle_trap_reserved /* 19 << 114 .word handle_trap_reserved /* 20 << 115 .word handle_trap_reserved /* 21 << 116 .word handle_trap_reserved /* 22 << 117 .word handle_trap_reserved /* 23 << 118 .word handle_trap_reserved /* 24 << 119 .word handle_trap_reserved /* 25 << 120 .word handle_trap_reserved /* 26 << 121 .word handle_trap_reserved /* 27 << 122 .word handle_trap_reserved /* 28 << 123 .word handle_trap_reserved /* 29 << 124 #ifdef CONFIG_KGDB << 125 .word handle_kgdb_breakpoint /* 30 << 126 #else << 127 .word instruction_trap << 128 #endif << 129 .word handle_breakpoint /* 31 << 130 19 131 .text !! 20 /* 132 .set noat !! 21 * This defines the normal kernel pt-regs layout. 133 .set nobreak !! 22 * >> 23 * regs 9-15 preserved by C code >> 24 * regs 16-18 saved by PAL-code >> 25 * regs 29-30 saved and set up by PAL-code >> 26 * JRP - Save regs 16-18 in a special area of the stack, so that >> 27 * the palcode-provided values are available to the signal handler. >> 28 */ 134 29 135 ENTRY(inthandler) !! 30 #define SAVE_ALL \ 136 SAVE_ALL !! 31 subq $sp, SP_OFF, $sp; \ >> 32 stq $0, 0($sp); \ >> 33 stq $1, 8($sp); \ >> 34 stq $2, 16($sp); \ >> 35 stq $3, 24($sp); \ >> 36 stq $4, 32($sp); \ >> 37 stq $28, 144($sp); \ >> 38 lda $2, alpha_mv; \ >> 39 stq $5, 40($sp); \ >> 40 stq $6, 48($sp); \ >> 41 stq $7, 56($sp); \ >> 42 stq $8, 64($sp); \ >> 43 stq $19, 72($sp); \ >> 44 stq $20, 80($sp); \ >> 45 stq $21, 88($sp); \ >> 46 ldq $2, HAE_CACHE($2); \ >> 47 stq $22, 96($sp); \ >> 48 stq $23, 104($sp); \ >> 49 stq $24, 112($sp); \ >> 50 stq $25, 120($sp); \ >> 51 stq $26, 128($sp); \ >> 52 stq $27, 136($sp); \ >> 53 stq $2, 152($sp); \ >> 54 stq $16, 160($sp); \ >> 55 stq $17, 168($sp); \ >> 56 stq $18, 176($sp) >> 57 >> 58 #define RESTORE_ALL \ >> 59 lda $19, alpha_mv; \ >> 60 ldq $0, 0($sp); \ >> 61 ldq $1, 8($sp); \ >> 62 ldq $2, 16($sp); \ >> 63 ldq $3, 24($sp); \ >> 64 ldq $21, 152($sp); \ >> 65 ldq $20, HAE_CACHE($19); \ >> 66 ldq $4, 32($sp); \ >> 67 ldq $5, 40($sp); \ >> 68 ldq $6, 48($sp); \ >> 69 ldq $7, 56($sp); \ >> 70 subq $20, $21, $20; \ >> 71 ldq $8, 64($sp); \ >> 72 beq $20, 99f; \ >> 73 ldq $20, HAE_REG($19); \ >> 74 stq $21, HAE_CACHE($19); \ >> 75 stq $21, 0($20); \ >> 76 ldq $0, 0($sp); \ >> 77 ldq $1, 8($sp); \ >> 78 99:; \ >> 79 ldq $19, 72($sp); \ >> 80 ldq $20, 80($sp); \ >> 81 ldq $21, 88($sp); \ >> 82 ldq $22, 96($sp); \ >> 83 ldq $23, 104($sp); \ >> 84 ldq $24, 112($sp); \ >> 85 ldq $25, 120($sp); \ >> 86 ldq $26, 128($sp); \ >> 87 ldq $27, 136($sp); \ >> 88 ldq $28, 144($sp); \ >> 89 addq $sp, SP_OFF, $sp 137 90 138 kuser_cmpxchg_check !! 91 /* >> 92 * Non-syscall kernel entry points. >> 93 */ 139 94 140 /* Clear EH bit before we get a new ex !! 95 .align 4 141 * and after we have saved it to the e !! 96 .globl entInt 142 * whether it's trap, tlb-miss or inte !! 97 .ent entInt 143 * estatus is not updated the next exc !! 98 entInt: 144 */ !! 99 SAVE_ALL 145 rdctl r24, status !! 100 lda $8, 0x3fff 146 movi r9, %lo(~STATUS_EH) !! 101 lda $26, ret_from_sys_call 147 and r24, r24, r9 !! 102 bic $sp, $8, $8 148 wrctl status, r24 !! 103 mov $sp, $19 149 !! 104 jsr $31, do_entInt 150 /* Read cause and vector and branch to !! 105 .end entInt 151 mov r4, sp !! 106 152 rdctl r5, exception !! 107 .align 4 153 movia r9, exception_table !! 108 .globl entArith 154 add r24, r9, r5 !! 109 .ent entArith 155 ldw r24, 0(r24) !! 110 entArith: 156 jmp r24 !! 111 SAVE_ALL 157 !! 112 lda $8, 0x3fff 158 !! 113 lda $26, ret_from_sys_call 159 /********************************************* !! 114 bic $sp, $8, $8 160 * Handle traps !! 115 mov $sp, $18 161 ********************************************* !! 116 jsr $31, do_entArith 162 */ !! 117 .end entArith 163 ENTRY(handle_trap) !! 118 164 ldwio r24, -4(ea) /* instruction !! 119 .align 4 165 srli r24, r24, 4 !! 120 .globl entMM 166 andi r24, r24, 0x7c !! 121 .ent entMM 167 movia r9,trap_table !! 122 entMM: 168 add r24, r24, r9 !! 123 SAVE_ALL 169 ldw r24, 0(r24) !! 124 /* save $9 - $15 so the inline exception code can manipulate them. */ 170 jmp r24 !! 125 subq $sp, 56, $sp 171 !! 126 stq $9, 0($sp) 172 !! 127 stq $10, 8($sp) 173 /********************************************* !! 128 stq $11, 16($sp) 174 * Handle system calls !! 129 stq $12, 24($sp) 175 ********************************************* !! 130 stq $13, 32($sp) 176 */ !! 131 stq $14, 40($sp) 177 ENTRY(handle_system_call) !! 132 stq $15, 48($sp) 178 /* Enable interrupts */ !! 133 addq $sp, 56, $19 179 rdctl r10, status !! 134 /* handle the fault */ 180 ori r10, r10, STATUS_PIE !! 135 lda $8, 0x3fff 181 wrctl status, r10 !! 136 bic $sp, $8, $8 182 !! 137 jsr $26, do_page_fault 183 /* Reload registers destroyed by commo !! 138 /* reload the registers after the exception code played. */ 184 ldw r4, PT_R4(sp) !! 139 ldq $9, 0($sp) 185 ldw r5, PT_R5(sp) !! 140 ldq $10, 8($sp) 186 !! 141 ldq $11, 16($sp) 187 local_restart: !! 142 ldq $12, 24($sp) 188 stw r2, PT_ORIG_R2(sp) !! 143 ldq $13, 32($sp) 189 /* Check that the requested system cal !! 144 ldq $14, 40($sp) 190 movui r1, __NR_syscalls !! 145 ldq $15, 48($sp) 191 bgeu r2, r1, ret_invsyscall !! 146 addq $sp, 56, $sp 192 slli r1, r2, 2 !! 147 /* finish up the syscall as normal. */ 193 movhi r11, %hiadj(sys_call_table) !! 148 br ret_from_sys_call 194 add r1, r1, r11 !! 149 .end entMM 195 ldw r1, %lo(sys_call_table)(r1) !! 150 196 !! 151 .align 4 197 /* Check if we are being traced */ !! 152 .globl entIF 198 GET_THREAD_INFO r11 !! 153 .ent entIF 199 ldw r11,TI_FLAGS(r11) !! 154 entIF: 200 BTBNZ r11,r11,TIF_SYSCALL_TRACE,trac !! 155 SAVE_ALL 201 !! 156 lda $8, 0x3fff 202 /* Execute the system call */ !! 157 lda $26, ret_from_sys_call 203 callr r1 !! 158 bic $sp, $8, $8 204 !! 159 mov $sp, $17 205 /* If the syscall returns a negative r !! 160 jsr $31, do_entIF 206 * Set r7 to 1 to indicate error, !! 161 .end entIF 207 * Negate r2 to get a positive error !! 162 208 * If the syscall returns zero or a po !! 163 .align 4 209 * Set r7 to 0. !! 164 .globl entUna 210 * The sigreturn system calls will ski !! 165 .ent entUna 211 * adding to register ra. To avoid des !! 166 entUna: 212 */ !! 167 lda $sp, -256($sp) 213 translate_rc_and_ret: !! 168 stq $0, 0($sp) 214 movi r1, 0 !! 169 ldq $0, 256($sp) /* get PS */ 215 bge r2, zero, 3f !! 170 stq $1, 8($sp) 216 ldw r1, PT_ORIG_R2(sp) !! 171 stq $2, 16($sp) 217 addi r1, r1, 1 !! 172 stq $3, 24($sp) 218 beq r1, zero, 3f !! 173 and $0, 8, $0 /* user mode? */ 219 sub r2, zero, r2 !! 174 stq $4, 32($sp) 220 movi r1, 1 !! 175 bne $0, entUnaUser /* yup -> do user-level unaligned fault */ 221 3: !! 176 stq $5, 40($sp) 222 stw r2, PT_R2(sp) !! 177 stq $6, 48($sp) 223 stw r1, PT_R7(sp) !! 178 stq $7, 56($sp) 224 end_translate_rc_and_ret: !! 179 stq $8, 64($sp) 225 !! 180 stq $9, 72($sp) 226 ret_from_exception: !! 181 stq $10, 80($sp) 227 ldw r1, PT_ESTATUS(sp) !! 182 stq $11, 88($sp) 228 /* if so, skip resched, signals */ !! 183 stq $12, 96($sp) 229 TSTBNZ r1, r1, ESTATUS_EU, Luser_retu !! 184 stq $13, 104($sp) >> 185 stq $14, 112($sp) >> 186 stq $15, 120($sp) >> 187 /* 16-18 PAL-saved */ >> 188 stq $19, 152($sp) >> 189 stq $20, 160($sp) >> 190 stq $21, 168($sp) >> 191 stq $22, 176($sp) >> 192 stq $23, 184($sp) >> 193 stq $24, 192($sp) >> 194 stq $25, 200($sp) >> 195 stq $26, 208($sp) >> 196 stq $27, 216($sp) >> 197 stq $28, 224($sp) >> 198 mov $sp, $19 >> 199 stq $gp, 232($sp) >> 200 lda $8, 0x3fff >> 201 stq $31, 248($sp) >> 202 bic $sp, $8, $8 >> 203 jsr $26, do_entUna >> 204 ldq $0, 0($sp) >> 205 ldq $1, 8($sp) >> 206 ldq $2, 16($sp) >> 207 ldq $3, 24($sp) >> 208 ldq $4, 32($sp) >> 209 ldq $5, 40($sp) >> 210 ldq $6, 48($sp) >> 211 ldq $7, 56($sp) >> 212 ldq $8, 64($sp) >> 213 ldq $9, 72($sp) >> 214 ldq $10, 80($sp) >> 215 ldq $11, 88($sp) >> 216 ldq $12, 96($sp) >> 217 ldq $13, 104($sp) >> 218 ldq $14, 112($sp) >> 219 ldq $15, 120($sp) >> 220 /* 16-18 PAL-saved */ >> 221 ldq $19, 152($sp) >> 222 ldq $20, 160($sp) >> 223 ldq $21, 168($sp) >> 224 ldq $22, 176($sp) >> 225 ldq $23, 184($sp) >> 226 ldq $24, 192($sp) >> 227 ldq $25, 200($sp) >> 228 ldq $26, 208($sp) >> 229 ldq $27, 216($sp) >> 230 ldq $28, 224($sp) >> 231 ldq $gp, 232($sp) >> 232 lda $sp, 256($sp) >> 233 call_pal PAL_rti >> 234 .end entUna >> 235 >> 236 .align 4 >> 237 .ent entUnaUser >> 238 entUnaUser: >> 239 ldq $0, 0($sp) /* restore original $0 */ >> 240 lda $sp, 256($sp) /* pop entUna's stack frame */ >> 241 SAVE_ALL /* setup normal kernel stack */ >> 242 lda $sp, -56($sp) >> 243 stq $9, 0($sp) >> 244 stq $10, 8($sp) >> 245 stq $11, 16($sp) >> 246 stq $12, 24($sp) >> 247 stq $13, 32($sp) >> 248 stq $14, 40($sp) >> 249 stq $15, 48($sp) >> 250 lda $8, 0x3fff >> 251 addq $sp, 56, $19 >> 252 bic $sp, $8, $8 >> 253 jsr $26, do_entUnaUser >> 254 ldq $9, 0($sp) >> 255 ldq $10, 8($sp) >> 256 ldq $11, 16($sp) >> 257 ldq $12, 24($sp) >> 258 ldq $13, 32($sp) >> 259 ldq $14, 40($sp) >> 260 ldq $15, 48($sp) >> 261 lda $sp, 56($sp) >> 262 br ret_from_sys_call >> 263 .end entUnaUser >> 264 >> 265 .align 4 >> 266 .globl entDbg >> 267 .ent entDbg >> 268 entDbg: >> 269 SAVE_ALL >> 270 lda $8, 0x3fff >> 271 lda $26, ret_from_sys_call >> 272 bic $sp, $8, $8 >> 273 mov $sp, $16 >> 274 jsr $31, do_entDbg >> 275 .end entDbg >> 276 >> 277 /* >> 278 * The system call entry point is special. Most importantly, it looks >> 279 * like a function call to userspace as far as clobbered registers. We >> 280 * do preserve the argument registers (for syscall restarts) and $26 >> 281 * (for leaf syscall functions). >> 282 * >> 283 * So much for theory. We don't take advantage of this yet. >> 284 * >> 285 * Note that a0-a2 are not saved by PALcode as with the other entry points. >> 286 */ 230 287 >> 288 .align 4 >> 289 .globl entSys >> 290 .globl ret_from_sys_call >> 291 .ent entSys >> 292 entSys: >> 293 SAVE_ALL >> 294 lda $8, 0x3fff >> 295 bic $sp, $8, $8 >> 296 lda $4, NR_SYSCALLS($31) >> 297 stq $16, SP_OFF+24($sp) >> 298 lda $5, sys_call_table >> 299 lda $27, sys_ni_syscall >> 300 cmpult $0, $4, $4 >> 301 ldl $3, TI_FLAGS($8) >> 302 stq $17, SP_OFF+32($sp) >> 303 s8addq $0, $5, $5 >> 304 stq $18, SP_OFF+40($sp) >> 305 blbs $3, strace >> 306 beq $4, 1f >> 307 ldq $27, 0($5) >> 308 1: jsr $26, ($27), alpha_ni_syscall >> 309 ldgp $gp, 0($26) >> 310 blt $0, $syscall_error /* the call failed */ >> 311 stq $0, 0($sp) >> 312 stq $31, 72($sp) /* a3=0 => no error */ >> 313 >> 314 .align 4 >> 315 ret_from_sys_call: >> 316 cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ >> 317 ldq $0, SP_OFF($sp) >> 318 and $0, 8, $0 >> 319 beq $0, restore_all >> 320 ret_from_reschedule: >> 321 /* Make sure need_resched and sigpending don't change between >> 322 sampling and the rti. */ >> 323 lda $16, 7 >> 324 call_pal PAL_swpipl >> 325 ldl $5, TI_FLAGS($8) >> 326 and $5, _TIF_WORK_MASK, $2 >> 327 bne $5, work_pending 231 restore_all: 328 restore_all: 232 rdctl r10, status << 233 andi r10, r10, %lo(~STATUS_PIE) << 234 wrctl status, r10 << 235 RESTORE_ALL 329 RESTORE_ALL 236 eret !! 330 call_pal PAL_rti 237 << 238 /* If the syscall number was invalid r << 239 ret_invsyscall: << 240 movi r2, -ENOSYS << 241 br translate_rc_and_ret << 242 << 243 /* This implements the same as above, << 244 * do_syscall_trace_enter and do_sysca << 245 * syscall in order for utilities like << 246 */ << 247 traced_system_call: << 248 SAVE_SWITCH_STACK << 249 call do_syscall_trace_enter << 250 RESTORE_SWITCH_STACK << 251 << 252 /* Create system call register argumen << 253 arguments on stack are already in p << 254 of pt_regs. */ << 255 ldw r2, PT_R2(sp) << 256 ldw r4, PT_R4(sp) << 257 ldw r5, PT_R5(sp) << 258 ldw r6, PT_R6(sp) << 259 ldw r7, PT_R7(sp) << 260 << 261 /* Fetch the syscall function. */ << 262 movui r1, __NR_syscalls << 263 bgeu r2, r1, traced_invsyscall << 264 slli r1, r2, 2 << 265 movhi r11,%hiadj(sys_call_table) << 266 add r1, r1, r11 << 267 ldw r1, %lo(sys_call_table)(r1) << 268 << 269 callr r1 << 270 << 271 /* If the syscall returns a negative r << 272 * Set r7 to 1 to indicate error, << 273 * Negate r2 to get a positive error << 274 * If the syscall returns zero or a po << 275 * Set r7 to 0. << 276 * The sigreturn system calls will ski << 277 * adding to register ra. To avoid des << 278 */ << 279 translate_rc_and_ret2: << 280 movi r1, 0 << 281 bge r2, zero, 4f << 282 ldw r1, PT_ORIG_R2(sp) << 283 addi r1, r1, 1 << 284 beq r1, zero, 4f << 285 sub r2, zero, r2 << 286 movi r1, 1 << 287 4: << 288 stw r2, PT_R2(sp) << 289 stw r1, PT_R7(sp) << 290 end_translate_rc_and_ret2: << 291 SAVE_SWITCH_STACK << 292 call do_syscall_trace_exit << 293 RESTORE_SWITCH_STACK << 294 br ret_from_exception << 295 << 296 /* If the syscall number was invalid r << 297 traced_invsyscall: << 298 movi r2, -ENOSYS << 299 br translate_rc_and_ret2 << 300 << 301 Luser_return: << 302 GET_THREAD_INFO r11 << 303 ldw r10, TI_FLAGS(r11) << 304 ANDI32 r11, r10, _TIF_WORK_MASK << 305 beq r11, r0, restore_all << 306 BTBZ r1, r10, TIF_NEED_RESCHED, Lsi << 307 << 308 /* Reschedule work */ << 309 call schedule << 310 br ret_from_exception << 311 << 312 Lsignal_return: << 313 ANDI32 r1, r10, _TIF_SIGPENDING | _TI << 314 beq r1, r0, restore_all << 315 mov r4, sp /* pt_ << 316 SAVE_SWITCH_STACK << 317 call do_notify_resume << 318 beq r2, r0, no_work_pending << 319 RESTORE_SWITCH_STACK << 320 /* prepare restart syscall here withou << 321 ldw r2, PT_R2(sp) /* reload sysc << 322 ldw r4, PT_R4(sp) /* reload sysc << 323 ldw r5, PT_R5(sp) << 324 ldw r6, PT_R6(sp) << 325 ldw r7, PT_R7(sp) << 326 ldw r8, PT_R8(sp) << 327 ldw r9, PT_R9(sp) << 328 br local_restart /* restart sys << 329 << 330 no_work_pending: << 331 RESTORE_SWITCH_STACK << 332 br ret_from_exception << 333 << 334 /********************************************* << 335 * Handle external interrupts. << 336 ********************************************* << 337 */ << 338 /* << 339 * This is the generic interrupt handler (for << 340 * sources). It figures out the vector number << 341 * interrupt service routine directly. << 342 */ << 343 external_interrupt: << 344 rdctl r12, ipending << 345 rdctl r9, ienable << 346 and r12, r12, r9 << 347 /* skip if no interrupt is pending */ << 348 beq r12, r0, ret_from_interrupt << 349 331 >> 332 .align 3 >> 333 $syscall_error: 350 /* 334 /* 351 * Process an external hardware interr !! 335 * Some system calls (e.g., ptrace) can return arbitrary >> 336 * values which might normally be mistaken as error numbers. >> 337 * Those functions must zero $0 (v0) directly in the stack >> 338 * frame to indicate that a negative return value wasn't an >> 339 * error number.. 352 */ 340 */ >> 341 ldq $19, 0($sp) /* old syscall nr (zero if success) */ >> 342 beq $19, $ret_success 353 343 354 addi ea, ea, -4 /* re-issue th !! 344 ldq $20, 72($sp) /* .. and this a3 */ 355 stw ea, PT_EA(sp) !! 345 subq $31, $0, $0 /* with error in v0 */ 356 2: movi r4, %lo(-1) /* Start from !! 346 addq $31, 1, $1 /* set a3 for errno return */ 357 highes !! 347 stq $0, 0($sp) 358 /* This is the !! 348 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ 359 1: andi r10, r12, 1 /* Isolate bit !! 349 stq $1, 72($sp) /* a3 for return */ 360 srli r12, r12, 1 /* shift count !! 350 br ret_from_sys_call 361 multip !! 351 362 addi r4, r4, 1 !! 352 $ret_success: 363 beq r10, r0, 1b !! 353 stq $0, 0($sp) 364 mov r5, sp /* Setup pt_re !! 354 stq $31, 72($sp) /* a3=0 => no error */ 365 call do_IRQ !! 355 br ret_from_sys_call 366 rdctl r12, ipending /* check again !! 356 .end entSys 367 rdctl r9, ienable /* Isolate pos !! 357 368 and r12, r12, r9 !! 358 /* 369 bne r12, r0, 2b !! 359 * Do all cleanup when returning from all interrupts and system calls. 370 /* br ret_from_interrupt */ /* fall !! 360 * 371 !! 361 * Arguments: 372 ENTRY(ret_from_interrupt) !! 362 * $5: TI_FLAGS. 373 ldw r1, PT_ESTATUS(sp) /* che !! 363 * $8: current. 374 TSTBNZ r1, r1, ESTATUS_EU, Luser_retu !! 364 * $19: The old syscall number, or zero if this is not a return 375 !! 365 * from a syscall that errored and is possibly restartable. 376 #ifdef CONFIG_PREEMPTION !! 366 * $20: Error indication. 377 GET_THREAD_INFO r1 !! 367 */ 378 ldw r4, TI_PREEMPT_COUNT(r1) !! 368 379 bne r4, r0, restore_all !! 369 .align 4 380 ldw r4, TI_FLAGS(r1) !! 370 .ent work_pending 381 BTBZ r10, r4, TIF_NEED_RESCHED, res !! 371 work_pending: 382 ldw r4, PT_ESTATUS(sp) /* ? I !! 372 and $5, _TIF_NEED_RESCHED, $2 383 andi r10, r4, ESTATUS_EPIE !! 373 beq $2, $work_notifysig 384 beq r10, r0, restore_all !! 374 385 call preempt_schedule_irq !! 375 $work_resched: 386 #endif !! 376 subq $sp, 16, $sp >> 377 stq $19, 0($sp) /* save syscall nr */ >> 378 stq $20, 8($sp) /* and error indication (a3) */ >> 379 jsr $26, schedule >> 380 ldq $19, 0($sp) >> 381 ldq $20, 8($sp) >> 382 addq $sp, 16, $sp >> 383 /* Make sure need_resched and sigpending don't change between >> 384 sampling and the rti. */ >> 385 lda $16, 7 >> 386 call_pal PAL_swpipl >> 387 ldl $5, TI_FLAGS($8) >> 388 and $5, _TIF_WORK_MASK, $2 >> 389 beq $2, restore_all >> 390 and $5, _TIF_NEED_RESCHED, $2 >> 391 bne $2, $work_resched >> 392 >> 393 $work_notifysig: >> 394 mov $sp, $16 >> 395 br $1, do_switch_stack >> 396 mov $sp, $17 >> 397 mov $5, $18 >> 398 jsr $26, do_notify_resume >> 399 bsr $1, undo_switch_stack 387 br restore_all 400 br restore_all >> 401 .end work_pending 388 402 389 /********************************************* !! 403 /* 390 * A few syscall wrappers !! 404 * PTRACE syscall handler 391 ********************************************* !! 405 */ 392 */ << 393 /* << 394 * int clone(unsigned long clone_flags, unsign << 395 * int __user * parent_tidptr, in << 396 * int tls_val) << 397 */ << 398 ENTRY(sys_clone) << 399 SAVE_SWITCH_STACK << 400 subi sp, sp, 4 /* make space for tl << 401 stw r8, 0(sp) /* pass tls pointer << 402 call nios2_clone << 403 addi sp, sp, 4 << 404 RESTORE_SWITCH_STACK << 405 ret << 406 << 407 ENTRY(sys_rt_sigreturn) << 408 SAVE_SWITCH_STACK << 409 mov r4, sp << 410 call do_rt_sigreturn << 411 RESTORE_SWITCH_STACK << 412 addi ra, ra, (end_translate_rc_and_ << 413 ret << 414 << 415 /********************************************* << 416 * A few other wrappers and stubs << 417 ********************************************* << 418 */ << 419 protection_exception_pte: << 420 rdctl r6, pteaddr << 421 slli r6, r6, 10 << 422 call do_page_fault << 423 br ret_from_exception << 424 << 425 protection_exception_ba: << 426 rdctl r6, badaddr << 427 call do_page_fault << 428 br ret_from_exception << 429 << 430 protection_exception_instr: << 431 call handle_supervisor_instr << 432 br ret_from_exception << 433 << 434 handle_breakpoint: << 435 call breakpoint_c << 436 br ret_from_exception << 437 << 438 #ifdef CONFIG_NIOS2_ALIGNMENT_TRAP << 439 handle_unaligned: << 440 SAVE_SWITCH_STACK << 441 call handle_unaligned_c << 442 RESTORE_SWITCH_STACK << 443 br ret_from_exception << 444 #else << 445 handle_unaligned: << 446 call handle_unaligned_c << 447 br ret_from_exception << 448 #endif << 449 406 450 handle_illegal: !! 407 .align 4 451 call handle_illegal_c !! 408 .ent strace 452 br ret_from_exception !! 409 strace: 453 !! 410 /* set up signal stack, call syscall_trace */ 454 handle_diverror: !! 411 bsr $1, do_switch_stack 455 call handle_diverror_c !! 412 jsr $26, syscall_trace 456 br ret_from_exception !! 413 bsr $1, undo_switch_stack 457 !! 414 458 #ifdef CONFIG_KGDB !! 415 /* get the system call number and the arguments back.. */ 459 handle_kgdb_breakpoint: !! 416 ldq $0, 0($sp) 460 call kgdb_breakpoint_c !! 417 ldq $16, SP_OFF+24($sp) 461 br ret_from_exception !! 418 ldq $17, SP_OFF+32($sp) 462 #endif !! 419 ldq $18, SP_OFF+40($sp) >> 420 ldq $19, 72($sp) >> 421 ldq $20, 80($sp) >> 422 ldq $21, 88($sp) >> 423 >> 424 /* get the system call pointer.. */ >> 425 lda $1, NR_SYSCALLS($31) >> 426 lda $2, sys_call_table >> 427 lda $27, alpha_ni_syscall >> 428 cmpult $0, $1, $1 >> 429 s8addq $0, $2, $2 >> 430 beq $1, 1f >> 431 ldq $27, 0($2) >> 432 1: jsr $26, ($27), sys_gettimeofday >> 433 ldgp $gp, 0($26) >> 434 >> 435 /* check return.. */ >> 436 blt $0, $strace_error /* the call failed */ >> 437 stq $31, 72($sp) /* a3=0 => no error */ >> 438 $strace_success: >> 439 stq $0, 0($sp) /* save return value */ >> 440 >> 441 bsr $1, do_switch_stack >> 442 jsr $26, syscall_trace >> 443 bsr $1, undo_switch_stack >> 444 br $31, ret_from_sys_call >> 445 >> 446 .align 3 >> 447 $strace_error: >> 448 ldq $19, 0($sp) /* old syscall nr (zero if success) */ >> 449 beq $19, $strace_success >> 450 ldq $20, 72($sp) /* .. and this a3 */ >> 451 >> 452 subq $31, $0, $0 /* with error in v0 */ >> 453 addq $31, 1, $1 /* set a3 for errno return */ >> 454 stq $0, 0($sp) >> 455 stq $1, 72($sp) /* a3 for return */ >> 456 >> 457 bsr $1, do_switch_stack >> 458 mov $19, $9 /* save old syscall number */ >> 459 mov $20, $10 /* save old a3 */ >> 460 jsr $26, syscall_trace >> 461 mov $9, $19 >> 462 mov $10, $20 >> 463 bsr $1, undo_switch_stack >> 464 >> 465 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ >> 466 br ret_from_sys_call >> 467 .end strace >> 468 >> 469 /* >> 470 * Save and restore the switch stack -- aka the balance of the user context. >> 471 */ 463 472 464 handle_trap_1: !! 473 .align 4 465 call handle_trap_1_c !! 474 .ent do_switch_stack 466 br ret_from_exception !! 475 do_switch_stack: >> 476 lda $sp, -SWITCH_STACK_SIZE($sp) >> 477 stq $9, 0($sp) >> 478 stq $10, 8($sp) >> 479 stq $11, 16($sp) >> 480 stq $12, 24($sp) >> 481 stq $13, 32($sp) >> 482 stq $14, 40($sp) >> 483 stq $15, 48($sp) >> 484 stq $26, 56($sp) >> 485 stt $f0, 64($sp) >> 486 stt $f1, 72($sp) >> 487 stt $f2, 80($sp) >> 488 stt $f3, 88($sp) >> 489 stt $f4, 96($sp) >> 490 stt $f5, 104($sp) >> 491 stt $f6, 112($sp) >> 492 stt $f7, 120($sp) >> 493 stt $f8, 128($sp) >> 494 stt $f9, 136($sp) >> 495 stt $f10, 144($sp) >> 496 stt $f11, 152($sp) >> 497 stt $f12, 160($sp) >> 498 stt $f13, 168($sp) >> 499 stt $f14, 176($sp) >> 500 stt $f15, 184($sp) >> 501 stt $f16, 192($sp) >> 502 stt $f17, 200($sp) >> 503 stt $f18, 208($sp) >> 504 stt $f19, 216($sp) >> 505 stt $f20, 224($sp) >> 506 stt $f21, 232($sp) >> 507 stt $f22, 240($sp) >> 508 stt $f23, 248($sp) >> 509 stt $f24, 256($sp) >> 510 stt $f25, 264($sp) >> 511 stt $f26, 272($sp) >> 512 stt $f27, 280($sp) >> 513 mf_fpcr $f0 # get fpcr >> 514 stt $f28, 288($sp) >> 515 stt $f29, 296($sp) >> 516 stt $f30, 304($sp) >> 517 stt $f0, 312($sp) # save fpcr in slot of $f31 >> 518 ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state. >> 519 ret $31, ($1), 1 >> 520 .end do_switch_stack >> 521 >> 522 .align 4 >> 523 .ent undo_switch_stack >> 524 undo_switch_stack: >> 525 ldq $9, 0($sp) >> 526 ldq $10, 8($sp) >> 527 ldq $11, 16($sp) >> 528 ldq $12, 24($sp) >> 529 ldq $13, 32($sp) >> 530 ldq $14, 40($sp) >> 531 ldq $15, 48($sp) >> 532 ldq $26, 56($sp) >> 533 ldt $f30, 312($sp) # get saved fpcr >> 534 ldt $f0, 64($sp) >> 535 ldt $f1, 72($sp) >> 536 ldt $f2, 80($sp) >> 537 ldt $f3, 88($sp) >> 538 mt_fpcr $f30 # install saved fpcr >> 539 ldt $f4, 96($sp) >> 540 ldt $f5, 104($sp) >> 541 ldt $f6, 112($sp) >> 542 ldt $f7, 120($sp) >> 543 ldt $f8, 128($sp) >> 544 ldt $f9, 136($sp) >> 545 ldt $f10, 144($sp) >> 546 ldt $f11, 152($sp) >> 547 ldt $f12, 160($sp) >> 548 ldt $f13, 168($sp) >> 549 ldt $f14, 176($sp) >> 550 ldt $f15, 184($sp) >> 551 ldt $f16, 192($sp) >> 552 ldt $f17, 200($sp) >> 553 ldt $f18, 208($sp) >> 554 ldt $f19, 216($sp) >> 555 ldt $f20, 224($sp) >> 556 ldt $f21, 232($sp) >> 557 ldt $f22, 240($sp) >> 558 ldt $f23, 248($sp) >> 559 ldt $f24, 256($sp) >> 560 ldt $f25, 264($sp) >> 561 ldt $f26, 272($sp) >> 562 ldt $f27, 280($sp) >> 563 ldt $f28, 288($sp) >> 564 ldt $f29, 296($sp) >> 565 ldt $f30, 304($sp) >> 566 lda $sp, SWITCH_STACK_SIZE($sp) >> 567 ret $31, ($1), 1 >> 568 .end undo_switch_stack >> 569 >> 570 /* >> 571 * The meat of the context switch code. >> 572 */ >> 573 >> 574 .align 4 >> 575 .globl alpha_switch_to >> 576 .ent alpha_switch_to >> 577 alpha_switch_to: >> 578 .prologue 0 >> 579 bsr $1, do_switch_stack >> 580 call_pal PAL_swpctx >> 581 lda $8, 0x3fff >> 582 bsr $1, undo_switch_stack >> 583 bic $sp, $8, $8 >> 584 mov $17, $0 >> 585 ret >> 586 .end alpha_switch_to 467 587 468 handle_trap_2: !! 588 /* 469 call handle_trap_2_c !! 589 * New processes begin life here. 470 br ret_from_exception !! 590 */ 471 591 472 handle_trap_3: !! 592 .globl ret_from_fork 473 handle_trap_reserved: !! 593 .align 4 474 call handle_trap_3_c !! 594 .ent ret_from_fork 475 br ret_from_exception !! 595 ret_from_fork: >> 596 lda $26, ret_from_sys_call >> 597 mov $17, $16 >> 598 jmp $31, schedule_tail >> 599 .end ret_from_fork 476 600 477 /* 601 /* 478 * Beware - when entering resume, prev (the cu !! 602 * kernel_thread(fn, arg, clone_flags) 479 * in r4, next (the new task) is in r5, don't << 480 * registers. << 481 */ 603 */ 482 ENTRY(resume) !! 604 .align 4 >> 605 .globl kernel_thread >> 606 .ent kernel_thread >> 607 kernel_thread: >> 608 /* We can be called from a module. */ >> 609 ldgp $gp, 0($27) >> 610 .prologue 1 >> 611 subq $sp, SP_OFF+6*8, $sp >> 612 br $1, 2f /* load start address */ >> 613 >> 614 /* We've now "returned" from a fake system call. */ >> 615 unop >> 616 blt $0, 1f /* error? */ >> 617 ldi $1, 0x3fff >> 618 beq $20, 1f /* parent or child? */ >> 619 >> 620 bic $sp, $1, $8 /* in child. */ >> 621 jsr $26, ($27) >> 622 ldgp $gp, 0($26) >> 623 mov $0, $16 >> 624 mov $31, $26 >> 625 jmp $31, sys_exit >> 626 >> 627 1: ret /* in parent. */ >> 628 >> 629 .align 4 >> 630 2: /* Fake a system call stack frame, as we can't do system calls >> 631 from kernel space. Note that we store FN and ARG as they >> 632 need to be set up in the child for the call. Also store $8 >> 633 and $26 for use in the parent. */ >> 634 stq $31, SP_OFF($sp) /* ps */ >> 635 stq $1, SP_OFF+8($sp) /* pc */ >> 636 stq $gp, SP_OFF+16($sp) /* gp */ >> 637 stq $16, 136($sp) /* $27; FN for child */ >> 638 stq $17, SP_OFF+24($sp) /* $16; ARG for child */ >> 639 stq $8, 64($sp) /* $8 */ >> 640 stq $26, 128($sp) /* $26 */ >> 641 /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */ >> 642 ldq $2, alpha_mv+HAE_CACHE >> 643 stq $2, 152($sp) /* HAE */ >> 644 >> 645 /* Shuffle FLAGS to the front; add CLONE_VM. */ >> 646 ldi $1, CLONE_VM|CLONE_UNTRACED >> 647 or $18, $1, $16 >> 648 bsr $26, sys_clone >> 649 >> 650 /* We don't actually care for a3 success widgetry in the kernel. >> 651 Not for positive errno values. */ >> 652 stq $0, 0($sp) /* $0 */ >> 653 br restore_all >> 654 .end kernel_thread 483 655 484 rdctl r7, status !! 656 /* 485 stw r7, TASK_THREAD + THREAD_KPSR( !! 657 * kernel_execve(path, argv, envp) >> 658 */ >> 659 .align 4 >> 660 .globl kernel_execve >> 661 .ent kernel_execve >> 662 kernel_execve: >> 663 /* We can be called from a module. */ >> 664 ldgp $gp, 0($27) >> 665 lda $sp, -(32+SIZEOF_PT_REGS+8)($sp) >> 666 .frame $sp, 32+SIZEOF_PT_REGS+8, $26, 0 >> 667 stq $26, 0($sp) >> 668 stq $16, 8($sp) >> 669 stq $17, 16($sp) >> 670 stq $18, 24($sp) >> 671 .prologue 1 >> 672 >> 673 lda $16, 32($sp) >> 674 lda $17, 0 >> 675 lda $18, SIZEOF_PT_REGS >> 676 bsr $26, memset !samegp >> 677 >> 678 /* Avoid the HAE being gratuitously wrong, which would cause us >> 679 to do the whole turn off interrupts thing and restore it. */ >> 680 ldq $2, alpha_mv+HAE_CACHE >> 681 stq $2, 152+32($sp) >> 682 >> 683 ldq $16, 8($sp) >> 684 ldq $17, 16($sp) >> 685 ldq $18, 24($sp) >> 686 lda $19, 32($sp) >> 687 bsr $26, do_execve !samegp >> 688 >> 689 ldq $26, 0($sp) >> 690 bne $0, 1f /* error! */ >> 691 >> 692 /* Move the temporary pt_regs struct from its current location >> 693 to the top of the kernel stack frame. See copy_thread for >> 694 details for a normal process. */ >> 695 lda $16, 0x4000 - SIZEOF_PT_REGS($8) >> 696 lda $17, 32($sp) >> 697 lda $18, SIZEOF_PT_REGS >> 698 bsr $26, memmove !samegp >> 699 >> 700 /* Take that over as our new stack frame and visit userland! */ >> 701 lda $sp, 0x4000 - SIZEOF_PT_REGS($8) >> 702 br $31, ret_from_sys_call 486 703 487 andi r7, r7, %lo(~STATUS_PIE) !! 704 1: lda $sp, 32+SIZEOF_PT_REGS+8($sp) 488 wrctl status, r7 !! 705 ret >> 706 .end kernel_execve 489 707 490 SAVE_SWITCH_STACK !! 708 491 stw sp, TASK_THREAD + THREAD_KSP(r !! 709 /* 492 ldw sp, TASK_THREAD + THREAD_KSP(r !! 710 * Special system calls. Most of these are special in that they either 493 movia r24, _current_thread !! 711 * have to play switch_stack games or in some way use the pt_regs struct. 494 GET_THREAD_INFO r1 !! 712 */ 495 stw r1, 0(r24) !! 713 .align 4 496 RESTORE_SWITCH_STACK !! 714 .globl sys_fork >> 715 .ent sys_fork >> 716 sys_fork: >> 717 .prologue 0 >> 718 mov $sp, $21 >> 719 bsr $1, do_switch_stack >> 720 bis $31, SIGCHLD, $16 >> 721 mov $31, $17 >> 722 mov $31, $18 >> 723 mov $31, $19 >> 724 mov $31, $20 >> 725 jsr $26, alpha_clone >> 726 bsr $1, undo_switch_stack >> 727 ret >> 728 .end sys_fork 497 729 498 ldw r7, TASK_THREAD + THREAD_KPSR( !! 730 .align 4 499 wrctl status, r7 !! 731 .globl sys_clone >> 732 .ent sys_clone >> 733 sys_clone: >> 734 .prologue 0 >> 735 mov $sp, $21 >> 736 bsr $1, do_switch_stack >> 737 /* $16, $17, $18, $19, $20 come from the user. */ >> 738 jsr $26, alpha_clone >> 739 bsr $1, undo_switch_stack 500 ret 740 ret >> 741 .end sys_clone 501 742 502 ENTRY(ret_from_fork) !! 743 .align 4 503 call schedule_tail !! 744 .globl sys_vfork 504 br ret_from_exception !! 745 .ent sys_vfork >> 746 sys_vfork: >> 747 .prologue 0 >> 748 mov $sp, $16 >> 749 bsr $1, do_switch_stack >> 750 jsr $26, alpha_vfork >> 751 bsr $1, undo_switch_stack >> 752 ret >> 753 .end sys_vfork 505 754 506 ENTRY(ret_from_kernel_thread) !! 755 .align 4 507 call schedule_tail !! 756 .globl sys_sigreturn 508 mov r4,r17 /* arg */ !! 757 .ent sys_sigreturn 509 callr r16 /* function */ !! 758 sys_sigreturn: 510 br ret_from_exception !! 759 .prologue 0 >> 760 mov $sp, $17 >> 761 lda $18, -SWITCH_STACK_SIZE($sp) >> 762 lda $sp, -SWITCH_STACK_SIZE($sp) >> 763 jsr $26, do_sigreturn >> 764 br $1, undo_switch_stack >> 765 br ret_from_sys_call >> 766 .end sys_sigreturn >> 767 >> 768 .align 4 >> 769 .globl sys_rt_sigreturn >> 770 .ent sys_rt_sigreturn >> 771 sys_rt_sigreturn: >> 772 .prologue 0 >> 773 mov $sp, $17 >> 774 lda $18, -SWITCH_STACK_SIZE($sp) >> 775 lda $sp, -SWITCH_STACK_SIZE($sp) >> 776 jsr $26, do_rt_sigreturn >> 777 br $1, undo_switch_stack >> 778 br ret_from_sys_call >> 779 .end sys_rt_sigreturn >> 780 >> 781 .align 4 >> 782 .globl sys_sigsuspend >> 783 .ent sys_sigsuspend >> 784 sys_sigsuspend: >> 785 .prologue 0 >> 786 mov $sp, $17 >> 787 br $1, do_switch_stack >> 788 mov $sp, $18 >> 789 subq $sp, 16, $sp >> 790 stq $26, 0($sp) >> 791 jsr $26, do_sigsuspend >> 792 ldq $26, 0($sp) >> 793 lda $sp, SWITCH_STACK_SIZE+16($sp) >> 794 ret >> 795 .end sys_sigsuspend 511 796 512 /* !! 797 .align 4 513 * Kernel user helpers. !! 798 .globl sys_rt_sigsuspend 514 * !! 799 .ent sys_rt_sigsuspend 515 * Each segment is 64-byte aligned and will be !! 800 sys_rt_sigsuspend: 516 * New segments (if ever needed) must be added !! 801 .prologue 0 517 * This mechanism should be used only for thin !! 802 mov $sp, $18 518 * justified, and not be abused freely. !! 803 br $1, do_switch_stack 519 * !! 804 mov $sp, $19 520 */ !! 805 subq $sp, 16, $sp >> 806 stq $26, 0($sp) >> 807 jsr $26, do_rt_sigsuspend >> 808 ldq $26, 0($sp) >> 809 lda $sp, SWITCH_STACK_SIZE+16($sp) >> 810 ret >> 811 .end sys_rt_sigsuspend 521 812 522 /* Filling pads with undefined instructions. !! 813 .align 4 523 .macro kuser_pad sym size !! 814 .globl sys_sethae 524 .if ((. - \sym) & 3) !! 815 .ent sys_sethae 525 .rept (4 - (. - \sym) & 3) !! 816 sys_sethae: 526 .byte 0 !! 817 .prologue 0 527 .endr !! 818 stq $16, 152($sp) 528 .endif !! 819 ret 529 .rept ((\size - (. - \sym)) / 4) !! 820 .end sys_sethae 530 .word 0xdeadbeef << 531 .endr << 532 .endm << 533 << 534 .align 6 << 535 .globl __kuser_helper_start << 536 __kuser_helper_start: << 537 821 538 __kuser_helper_version: !! 822 .align 4 539 .word ((__kuser_helper_end - __kuser !! 823 .globl osf_getpriority >> 824 .ent osf_getpriority >> 825 osf_getpriority: >> 826 lda $sp, -16($sp) >> 827 stq $26, 0($sp) >> 828 .prologue 0 >> 829 >> 830 jsr $26, sys_getpriority >> 831 >> 832 ldq $26, 0($sp) >> 833 blt $0, 1f >> 834 >> 835 /* Return value is the unbiased priority, i.e. 20 - prio. >> 836 This does result in negative return values, so signal >> 837 no error by writing into the R0 slot. */ >> 838 lda $1, 20 >> 839 stq $31, 16($sp) >> 840 subl $1, $0, $0 >> 841 unop 540 842 541 __kuser_cmpxchg: !! 843 1: lda $sp, 16($sp) 542 /* !! 844 ret 543 * r4 pointer to exchange variable !! 845 .end osf_getpriority 544 * r5 old value !! 846 545 * r6 new value !! 847 .align 4 546 */ !! 848 .globl sys_getxuid 547 cmpxchg_ldw: !! 849 .ent sys_getxuid 548 ldw r2, 0(r4) !! 850 sys_getxuid: 549 sub r2, r2, r5 !! 851 .prologue 0 550 bne r2, zero, cmpxchg_ret !! 852 ldq $2, TI_TASK($8) >> 853 ldq $3, TASK_CRED($2) >> 854 ldl $0, CRED_UID($3) >> 855 ldl $1, CRED_EUID($3) >> 856 stq $1, 80($sp) >> 857 ret >> 858 .end sys_getxuid 551 859 552 /* We had a match, store the new value !! 860 .align 4 553 cmpxchg_stw: !! 861 .globl sys_getxgid 554 stw r6, 0(r4) !! 862 .ent sys_getxgid 555 cmpxchg_ret: !! 863 sys_getxgid: >> 864 .prologue 0 >> 865 ldq $2, TI_TASK($8) >> 866 ldq $3, TASK_CRED($2) >> 867 ldl $0, CRED_GID($3) >> 868 ldl $1, CRED_EGID($3) >> 869 stq $1, 80($sp) 556 ret 870 ret >> 871 .end sys_getxgid 557 872 558 kuser_pad __kuser_cmpxchg, 64 !! 873 .align 4 >> 874 .globl sys_getxpid >> 875 .ent sys_getxpid >> 876 sys_getxpid: >> 877 .prologue 0 >> 878 ldq $2, TI_TASK($8) >> 879 >> 880 /* See linux/kernel/timer.c sys_getppid for discussion >> 881 about this loop. */ >> 882 ldq $3, TASK_GROUP_LEADER($2) >> 883 ldq $4, TASK_REAL_PARENT($3) >> 884 ldl $0, TASK_TGID($2) >> 885 1: ldl $1, TASK_TGID($4) >> 886 #ifdef CONFIG_SMP >> 887 mov $4, $5 >> 888 mb >> 889 ldq $3, TASK_GROUP_LEADER($2) >> 890 ldq $4, TASK_REAL_PARENT($3) >> 891 cmpeq $4, $5, $5 >> 892 beq $5, 1b >> 893 #endif >> 894 stq $1, 80($sp) >> 895 ret >> 896 .end sys_getxpid 559 897 560 .globl __kuser_sigtramp !! 898 .align 4 561 __kuser_sigtramp: !! 899 .globl sys_alpha_pipe 562 movi r2, __NR_rt_sigreturn !! 900 .ent sys_alpha_pipe 563 trap !! 901 sys_alpha_pipe: >> 902 lda $sp, -16($sp) >> 903 stq $26, 0($sp) >> 904 .prologue 0 >> 905 >> 906 mov $31, $17 >> 907 lda $16, 8($sp) >> 908 jsr $26, do_pipe_flags >> 909 >> 910 ldq $26, 0($sp) >> 911 bne $0, 1f >> 912 >> 913 /* The return values are in $0 and $20. */ >> 914 ldl $1, 12($sp) >> 915 ldl $0, 8($sp) 564 916 565 kuser_pad __kuser_sigtramp, 64 !! 917 stq $1, 80+16($sp) >> 918 1: lda $sp, 16($sp) >> 919 ret >> 920 .end sys_alpha_pipe 566 921 567 .globl __kuser_helper_end !! 922 .align 4 568 __kuser_helper_end: !! 923 .globl sys_execve >> 924 .ent sys_execve >> 925 sys_execve: >> 926 .prologue 0 >> 927 mov $sp, $19 >> 928 jmp $31, do_sys_execve >> 929 .end sys_execve >> 930 >> 931 .align 4 >> 932 .globl osf_sigprocmask >> 933 .ent osf_sigprocmask >> 934 osf_sigprocmask: >> 935 .prologue 0 >> 936 mov $sp, $18 >> 937 jmp $31, sys_osf_sigprocmask >> 938 .end osf_sigprocmask >> 939 >> 940 .align 4 >> 941 .globl alpha_ni_syscall >> 942 .ent alpha_ni_syscall >> 943 alpha_ni_syscall: >> 944 .prologue 0 >> 945 /* Special because it also implements overflow handling via >> 946 syscall number 0. And if you recall, zero is a special >> 947 trigger for "not an error". Store large non-zero there. */ >> 948 lda $0, -ENOSYS >> 949 unop >> 950 stq $0, 0($sp) >> 951 ret >> 952 .end alpha_ni_syscall
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.