>> 1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* 2 /* 2 * linux/arch/nios2/kernel/entry.S !! 3 * arch/alpha/kernel/entry.S 3 * 4 * 4 * Copyright (C) 2013-2014 Altera Corporation !! 5 * 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 */ 6 */ 26 7 27 #include <linux/sys.h> << 28 #include <linux/linkage.h> << 29 #include <asm/asm-offsets.h> 8 #include <asm/asm-offsets.h> 30 #include <asm/asm-macros.h> << 31 #include <asm/thread_info.h> 9 #include <asm/thread_info.h> >> 10 #include <asm/pal.h> 32 #include <asm/errno.h> 11 #include <asm/errno.h> 33 #include <asm/setup.h> << 34 #include <asm/entry.h> << 35 #include <asm/unistd.h> 12 #include <asm/unistd.h> 36 #include <asm/processor.h> << 37 13 38 .macro GET_THREAD_INFO reg !! 14 .text 39 .if THREAD_SIZE & 0xffff0000 !! 15 .set noat 40 andhi \reg, sp, %hi(~(THREAD_SIZE-1) !! 16 .cfi_sections .debug_frame 41 .else !! 17 42 addi \reg, r0, %lo(~(THREAD_SIZE-1) !! 18 /* Stack offsets. */ 43 and \reg, \reg, sp !! 19 #define SP_OFF 184 44 .endif !! 20 #define SWITCH_STACK_SIZE 320 >> 21 >> 22 .macro CFI_START_OSF_FRAME func >> 23 .align 4 >> 24 .globl \func >> 25 .type \func,@function >> 26 \func: >> 27 .cfi_startproc simple >> 28 .cfi_return_column 64 >> 29 .cfi_def_cfa $sp, 48 >> 30 .cfi_rel_offset 64, 8 >> 31 .cfi_rel_offset $gp, 16 >> 32 .cfi_rel_offset $16, 24 >> 33 .cfi_rel_offset $17, 32 >> 34 .cfi_rel_offset $18, 40 45 .endm 35 .endm 46 36 47 .macro kuser_cmpxchg_check !! 37 .macro CFI_END_OSF_FRAME func 48 /* !! 38 .cfi_endproc 49 * Make sure our user space atomic hel !! 39 .size \func, . - \func 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 40 .endm 67 41 68 .section .rodata !! 42 /* 69 .align 4 !! 43 * This defines the normal kernel pt-regs layout. 70 exception_table: !! 44 * 71 .word unhandled_exception /* 0 - !! 45 * regs 9-15 preserved by C code 72 .word unhandled_exception /* 1 - !! 46 * regs 16-18 saved by PAL-code 73 .word external_interrupt /* 2 - !! 47 * regs 29-30 saved and set up by PAL-code 74 .word handle_trap /* 3 - !! 48 * JRP - Save regs 16-18 in a special area of the stack, so that 75 !! 49 * the palcode-provided values are available to the signal handler. 76 .word instruction_trap /* 4 - !! 50 */ 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 51 131 .text !! 52 .macro SAVE_ALL 132 .set noat !! 53 subq $sp, SP_OFF, $sp 133 .set nobreak !! 54 .cfi_adjust_cfa_offset SP_OFF >> 55 stq $0, 0($sp) >> 56 stq $1, 8($sp) >> 57 stq $2, 16($sp) >> 58 stq $3, 24($sp) >> 59 stq $4, 32($sp) >> 60 stq $28, 144($sp) >> 61 .cfi_rel_offset $0, 0 >> 62 .cfi_rel_offset $1, 8 >> 63 .cfi_rel_offset $2, 16 >> 64 .cfi_rel_offset $3, 24 >> 65 .cfi_rel_offset $4, 32 >> 66 .cfi_rel_offset $28, 144 >> 67 lda $2, alpha_mv >> 68 stq $5, 40($sp) >> 69 stq $6, 48($sp) >> 70 stq $7, 56($sp) >> 71 stq $8, 64($sp) >> 72 stq $19, 72($sp) >> 73 stq $20, 80($sp) >> 74 stq $21, 88($sp) >> 75 ldq $2, HAE_CACHE($2) >> 76 stq $22, 96($sp) >> 77 stq $23, 104($sp) >> 78 stq $24, 112($sp) >> 79 stq $25, 120($sp) >> 80 stq $26, 128($sp) >> 81 stq $27, 136($sp) >> 82 stq $2, 152($sp) >> 83 stq $16, 160($sp) >> 84 stq $17, 168($sp) >> 85 stq $18, 176($sp) >> 86 .cfi_rel_offset $5, 40 >> 87 .cfi_rel_offset $6, 48 >> 88 .cfi_rel_offset $7, 56 >> 89 .cfi_rel_offset $8, 64 >> 90 .cfi_rel_offset $19, 72 >> 91 .cfi_rel_offset $20, 80 >> 92 .cfi_rel_offset $21, 88 >> 93 .cfi_rel_offset $22, 96 >> 94 .cfi_rel_offset $23, 104 >> 95 .cfi_rel_offset $24, 112 >> 96 .cfi_rel_offset $25, 120 >> 97 .cfi_rel_offset $26, 128 >> 98 .cfi_rel_offset $27, 136 >> 99 .endm 134 100 135 ENTRY(inthandler) !! 101 .macro RESTORE_ALL 136 SAVE_ALL !! 102 lda $19, alpha_mv >> 103 ldq $0, 0($sp) >> 104 ldq $1, 8($sp) >> 105 ldq $2, 16($sp) >> 106 ldq $3, 24($sp) >> 107 ldq $21, 152($sp) >> 108 ldq $20, HAE_CACHE($19) >> 109 ldq $4, 32($sp) >> 110 ldq $5, 40($sp) >> 111 ldq $6, 48($sp) >> 112 ldq $7, 56($sp) >> 113 subq $20, $21, $20 >> 114 ldq $8, 64($sp) >> 115 beq $20, 99f >> 116 ldq $20, HAE_REG($19) >> 117 stq $21, HAE_CACHE($19) >> 118 stq $21, 0($20) >> 119 99: ldq $19, 72($sp) >> 120 ldq $20, 80($sp) >> 121 ldq $21, 88($sp) >> 122 ldq $22, 96($sp) >> 123 ldq $23, 104($sp) >> 124 ldq $24, 112($sp) >> 125 ldq $25, 120($sp) >> 126 ldq $26, 128($sp) >> 127 ldq $27, 136($sp) >> 128 ldq $28, 144($sp) >> 129 addq $sp, SP_OFF, $sp >> 130 .cfi_restore $0 >> 131 .cfi_restore $1 >> 132 .cfi_restore $2 >> 133 .cfi_restore $3 >> 134 .cfi_restore $4 >> 135 .cfi_restore $5 >> 136 .cfi_restore $6 >> 137 .cfi_restore $7 >> 138 .cfi_restore $8 >> 139 .cfi_restore $19 >> 140 .cfi_restore $20 >> 141 .cfi_restore $21 >> 142 .cfi_restore $22 >> 143 .cfi_restore $23 >> 144 .cfi_restore $24 >> 145 .cfi_restore $25 >> 146 .cfi_restore $26 >> 147 .cfi_restore $27 >> 148 .cfi_restore $28 >> 149 .cfi_adjust_cfa_offset -SP_OFF >> 150 .endm 137 151 138 kuser_cmpxchg_check !! 152 .macro DO_SWITCH_STACK >> 153 bsr $1, do_switch_stack >> 154 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE >> 155 .cfi_rel_offset $9, 0 >> 156 .cfi_rel_offset $10, 8 >> 157 .cfi_rel_offset $11, 16 >> 158 .cfi_rel_offset $12, 24 >> 159 .cfi_rel_offset $13, 32 >> 160 .cfi_rel_offset $14, 40 >> 161 .cfi_rel_offset $15, 48 >> 162 /* We don't really care about the FP registers for debugging. */ >> 163 .endm 139 164 140 /* Clear EH bit before we get a new ex !! 165 .macro UNDO_SWITCH_STACK 141 * and after we have saved it to the e !! 166 bsr $1, undo_switch_stack 142 * whether it's trap, tlb-miss or inte !! 167 .cfi_restore $9 143 * estatus is not updated the next exc !! 168 .cfi_restore $10 144 */ !! 169 .cfi_restore $11 145 rdctl r24, status !! 170 .cfi_restore $12 146 movi r9, %lo(~STATUS_EH) !! 171 .cfi_restore $13 147 and r24, r24, r9 !! 172 .cfi_restore $14 148 wrctl status, r24 !! 173 .cfi_restore $15 149 !! 174 .cfi_adjust_cfa_offset -SWITCH_STACK_SIZE 150 /* Read cause and vector and branch to !! 175 .endm 151 mov r4, sp << 152 rdctl r5, exception << 153 movia r9, exception_table << 154 add r24, r9, r5 << 155 ldw r24, 0(r24) << 156 jmp r24 << 157 << 158 << 159 /********************************************* << 160 * Handle traps << 161 ********************************************* << 162 */ << 163 ENTRY(handle_trap) << 164 ldwio r24, -4(ea) /* instruction << 165 srli r24, r24, 4 << 166 andi r24, r24, 0x7c << 167 movia r9,trap_table << 168 add r24, r24, r9 << 169 ldw r24, 0(r24) << 170 jmp r24 << 171 << 172 << 173 /********************************************* << 174 * Handle system calls << 175 ********************************************* << 176 */ << 177 ENTRY(handle_system_call) << 178 /* Enable interrupts */ << 179 rdctl r10, status << 180 ori r10, r10, STATUS_PIE << 181 wrctl status, r10 << 182 << 183 /* Reload registers destroyed by commo << 184 ldw r4, PT_R4(sp) << 185 ldw r5, PT_R5(sp) << 186 << 187 local_restart: << 188 stw r2, PT_ORIG_R2(sp) << 189 /* Check that the requested system cal << 190 movui r1, __NR_syscalls << 191 bgeu r2, r1, ret_invsyscall << 192 slli r1, r2, 2 << 193 movhi r11, %hiadj(sys_call_table) << 194 add r1, r1, r11 << 195 ldw r1, %lo(sys_call_table)(r1) << 196 << 197 /* Check if we are being traced */ << 198 GET_THREAD_INFO r11 << 199 ldw r11,TI_FLAGS(r11) << 200 BTBNZ r11,r11,TIF_SYSCALL_TRACE,trac << 201 << 202 /* Execute the system call */ << 203 callr r1 << 204 << 205 /* If the syscall returns a negative r << 206 * Set r7 to 1 to indicate error, << 207 * Negate r2 to get a positive error << 208 * If the syscall returns zero or a po << 209 * Set r7 to 0. << 210 * The sigreturn system calls will ski << 211 * adding to register ra. To avoid des << 212 */ << 213 translate_rc_and_ret: << 214 movi r1, 0 << 215 bge r2, zero, 3f << 216 ldw r1, PT_ORIG_R2(sp) << 217 addi r1, r1, 1 << 218 beq r1, zero, 3f << 219 sub r2, zero, r2 << 220 movi r1, 1 << 221 3: << 222 stw r2, PT_R2(sp) << 223 stw r1, PT_R7(sp) << 224 end_translate_rc_and_ret: << 225 << 226 ret_from_exception: << 227 ldw r1, PT_ESTATUS(sp) << 228 /* if so, skip resched, signals */ << 229 TSTBNZ r1, r1, ESTATUS_EU, Luser_retu << 230 176 231 restore_all: !! 177 /* 232 rdctl r10, status !! 178 * Non-syscall kernel entry points. 233 andi r10, r10, %lo(~STATUS_PIE) !! 179 */ 234 wrctl status, r10 << 235 RESTORE_ALL << 236 eret << 237 180 238 /* If the syscall number was invalid r !! 181 CFI_START_OSF_FRAME entInt 239 ret_invsyscall: !! 182 SAVE_ALL 240 movi r2, -ENOSYS !! 183 lda $8, 0x3fff 241 br translate_rc_and_ret !! 184 lda $26, ret_from_sys_call 242 !! 185 bic $sp, $8, $8 243 /* This implements the same as above, !! 186 mov $sp, $19 244 * do_syscall_trace_enter and do_sysca !! 187 jsr $31, do_entInt 245 * syscall in order for utilities like !! 188 CFI_END_OSF_FRAME entInt 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 189 350 /* !! 190 CFI_START_OSF_FRAME entArith 351 * Process an external hardware interr !! 191 SAVE_ALL 352 */ !! 192 lda $8, 0x3fff >> 193 lda $26, ret_from_sys_call >> 194 bic $sp, $8, $8 >> 195 mov $sp, $18 >> 196 jsr $31, do_entArith >> 197 CFI_END_OSF_FRAME entArith 353 198 354 addi ea, ea, -4 /* re-issue th !! 199 CFI_START_OSF_FRAME entMM 355 stw ea, PT_EA(sp) !! 200 SAVE_ALL 356 2: movi r4, %lo(-1) /* Start from !! 201 /* save $9 - $15 so the inline exception code can manipulate them. */ 357 highes !! 202 subq $sp, 56, $sp 358 /* This is the !! 203 .cfi_adjust_cfa_offset 56 359 1: andi r10, r12, 1 /* Isolate bit !! 204 stq $9, 0($sp) 360 srli r12, r12, 1 /* shift count !! 205 stq $10, 8($sp) 361 multip !! 206 stq $11, 16($sp) 362 addi r4, r4, 1 !! 207 stq $12, 24($sp) 363 beq r10, r0, 1b !! 208 stq $13, 32($sp) 364 mov r5, sp /* Setup pt_re !! 209 stq $14, 40($sp) 365 call do_IRQ !! 210 stq $15, 48($sp) 366 rdctl r12, ipending /* check again !! 211 .cfi_rel_offset $9, 0 367 rdctl r9, ienable /* Isolate pos !! 212 .cfi_rel_offset $10, 8 368 and r12, r12, r9 !! 213 .cfi_rel_offset $11, 16 369 bne r12, r0, 2b !! 214 .cfi_rel_offset $12, 24 370 /* br ret_from_interrupt */ /* fall !! 215 .cfi_rel_offset $13, 32 371 !! 216 .cfi_rel_offset $14, 40 372 ENTRY(ret_from_interrupt) !! 217 .cfi_rel_offset $15, 48 373 ldw r1, PT_ESTATUS(sp) /* che !! 218 addq $sp, 56, $19 374 TSTBNZ r1, r1, ESTATUS_EU, Luser_retu !! 219 /* handle the fault */ 375 !! 220 lda $8, 0x3fff 376 #ifdef CONFIG_PREEMPTION !! 221 bic $sp, $8, $8 377 GET_THREAD_INFO r1 !! 222 jsr $26, do_page_fault 378 ldw r4, TI_PREEMPT_COUNT(r1) !! 223 /* reload the registers after the exception code played. */ 379 bne r4, r0, restore_all !! 224 ldq $9, 0($sp) 380 ldw r4, TI_FLAGS(r1) !! 225 ldq $10, 8($sp) 381 BTBZ r10, r4, TIF_NEED_RESCHED, res !! 226 ldq $11, 16($sp) 382 ldw r4, PT_ESTATUS(sp) /* ? I !! 227 ldq $12, 24($sp) 383 andi r10, r4, ESTATUS_EPIE !! 228 ldq $13, 32($sp) 384 beq r10, r0, restore_all !! 229 ldq $14, 40($sp) 385 call preempt_schedule_irq !! 230 ldq $15, 48($sp) 386 #endif !! 231 addq $sp, 56, $sp 387 br restore_all !! 232 .cfi_restore $9 >> 233 .cfi_restore $10 >> 234 .cfi_restore $11 >> 235 .cfi_restore $12 >> 236 .cfi_restore $13 >> 237 .cfi_restore $14 >> 238 .cfi_restore $15 >> 239 .cfi_adjust_cfa_offset -56 >> 240 /* finish up the syscall as normal. */ >> 241 br ret_from_sys_call >> 242 CFI_END_OSF_FRAME entMM 388 243 389 /********************************************* !! 244 CFI_START_OSF_FRAME entIF 390 * A few syscall wrappers !! 245 SAVE_ALL 391 ********************************************* !! 246 lda $8, 0x3fff 392 */ !! 247 lda $26, ret_from_sys_call 393 /* !! 248 bic $sp, $8, $8 394 * int clone(unsigned long clone_flags, unsign !! 249 mov $sp, $17 395 * int __user * parent_tidptr, in !! 250 jsr $31, do_entIF 396 * int tls_val) !! 251 CFI_END_OSF_FRAME entIF 397 */ !! 252 398 ENTRY(sys_clone) !! 253 CFI_START_OSF_FRAME entUna 399 SAVE_SWITCH_STACK !! 254 lda $sp, -256($sp) 400 subi sp, sp, 4 /* make space for tl !! 255 .cfi_adjust_cfa_offset 256 401 stw r8, 0(sp) /* pass tls pointer !! 256 stq $0, 0($sp) 402 call nios2_clone !! 257 .cfi_rel_offset $0, 0 403 addi sp, sp, 4 !! 258 .cfi_remember_state 404 RESTORE_SWITCH_STACK !! 259 ldq $0, 256($sp) /* get PS */ 405 ret !! 260 stq $1, 8($sp) >> 261 stq $2, 16($sp) >> 262 stq $3, 24($sp) >> 263 and $0, 8, $0 /* user mode? */ >> 264 stq $4, 32($sp) >> 265 bne $0, entUnaUser /* yup -> do user-level unaligned fault */ >> 266 stq $5, 40($sp) >> 267 stq $6, 48($sp) >> 268 stq $7, 56($sp) >> 269 stq $8, 64($sp) >> 270 stq $9, 72($sp) >> 271 stq $10, 80($sp) >> 272 stq $11, 88($sp) >> 273 stq $12, 96($sp) >> 274 stq $13, 104($sp) >> 275 stq $14, 112($sp) >> 276 stq $15, 120($sp) >> 277 /* 16-18 PAL-saved */ >> 278 stq $19, 152($sp) >> 279 stq $20, 160($sp) >> 280 stq $21, 168($sp) >> 281 stq $22, 176($sp) >> 282 stq $23, 184($sp) >> 283 stq $24, 192($sp) >> 284 stq $25, 200($sp) >> 285 stq $26, 208($sp) >> 286 stq $27, 216($sp) >> 287 stq $28, 224($sp) >> 288 mov $sp, $19 >> 289 stq $gp, 232($sp) >> 290 .cfi_rel_offset $1, 1*8 >> 291 .cfi_rel_offset $2, 2*8 >> 292 .cfi_rel_offset $3, 3*8 >> 293 .cfi_rel_offset $4, 4*8 >> 294 .cfi_rel_offset $5, 5*8 >> 295 .cfi_rel_offset $6, 6*8 >> 296 .cfi_rel_offset $7, 7*8 >> 297 .cfi_rel_offset $8, 8*8 >> 298 .cfi_rel_offset $9, 9*8 >> 299 .cfi_rel_offset $10, 10*8 >> 300 .cfi_rel_offset $11, 11*8 >> 301 .cfi_rel_offset $12, 12*8 >> 302 .cfi_rel_offset $13, 13*8 >> 303 .cfi_rel_offset $14, 14*8 >> 304 .cfi_rel_offset $15, 15*8 >> 305 .cfi_rel_offset $19, 19*8 >> 306 .cfi_rel_offset $20, 20*8 >> 307 .cfi_rel_offset $21, 21*8 >> 308 .cfi_rel_offset $22, 22*8 >> 309 .cfi_rel_offset $23, 23*8 >> 310 .cfi_rel_offset $24, 24*8 >> 311 .cfi_rel_offset $25, 25*8 >> 312 .cfi_rel_offset $26, 26*8 >> 313 .cfi_rel_offset $27, 27*8 >> 314 .cfi_rel_offset $28, 28*8 >> 315 .cfi_rel_offset $29, 29*8 >> 316 lda $8, 0x3fff >> 317 stq $31, 248($sp) >> 318 bic $sp, $8, $8 >> 319 jsr $26, do_entUna >> 320 ldq $0, 0($sp) >> 321 ldq $1, 8($sp) >> 322 ldq $2, 16($sp) >> 323 ldq $3, 24($sp) >> 324 ldq $4, 32($sp) >> 325 ldq $5, 40($sp) >> 326 ldq $6, 48($sp) >> 327 ldq $7, 56($sp) >> 328 ldq $8, 64($sp) >> 329 ldq $9, 72($sp) >> 330 ldq $10, 80($sp) >> 331 ldq $11, 88($sp) >> 332 ldq $12, 96($sp) >> 333 ldq $13, 104($sp) >> 334 ldq $14, 112($sp) >> 335 ldq $15, 120($sp) >> 336 /* 16-18 PAL-saved */ >> 337 ldq $19, 152($sp) >> 338 ldq $20, 160($sp) >> 339 ldq $21, 168($sp) >> 340 ldq $22, 176($sp) >> 341 ldq $23, 184($sp) >> 342 ldq $24, 192($sp) >> 343 ldq $25, 200($sp) >> 344 ldq $26, 208($sp) >> 345 ldq $27, 216($sp) >> 346 ldq $28, 224($sp) >> 347 ldq $gp, 232($sp) >> 348 lda $sp, 256($sp) >> 349 .cfi_restore $1 >> 350 .cfi_restore $2 >> 351 .cfi_restore $3 >> 352 .cfi_restore $4 >> 353 .cfi_restore $5 >> 354 .cfi_restore $6 >> 355 .cfi_restore $7 >> 356 .cfi_restore $8 >> 357 .cfi_restore $9 >> 358 .cfi_restore $10 >> 359 .cfi_restore $11 >> 360 .cfi_restore $12 >> 361 .cfi_restore $13 >> 362 .cfi_restore $14 >> 363 .cfi_restore $15 >> 364 .cfi_restore $19 >> 365 .cfi_restore $20 >> 366 .cfi_restore $21 >> 367 .cfi_restore $22 >> 368 .cfi_restore $23 >> 369 .cfi_restore $24 >> 370 .cfi_restore $25 >> 371 .cfi_restore $26 >> 372 .cfi_restore $27 >> 373 .cfi_restore $28 >> 374 .cfi_restore $29 >> 375 .cfi_adjust_cfa_offset -256 >> 376 call_pal PAL_rti >> 377 >> 378 .align 4 >> 379 entUnaUser: >> 380 .cfi_restore_state >> 381 ldq $0, 0($sp) /* restore original $0 */ >> 382 lda $sp, 256($sp) /* pop entUna's stack frame */ >> 383 .cfi_restore $0 >> 384 .cfi_adjust_cfa_offset -256 >> 385 SAVE_ALL /* setup normal kernel stack */ >> 386 lda $sp, -56($sp) >> 387 .cfi_adjust_cfa_offset 56 >> 388 stq $9, 0($sp) >> 389 stq $10, 8($sp) >> 390 stq $11, 16($sp) >> 391 stq $12, 24($sp) >> 392 stq $13, 32($sp) >> 393 stq $14, 40($sp) >> 394 stq $15, 48($sp) >> 395 .cfi_rel_offset $9, 0 >> 396 .cfi_rel_offset $10, 8 >> 397 .cfi_rel_offset $11, 16 >> 398 .cfi_rel_offset $12, 24 >> 399 .cfi_rel_offset $13, 32 >> 400 .cfi_rel_offset $14, 40 >> 401 .cfi_rel_offset $15, 48 >> 402 lda $8, 0x3fff >> 403 addq $sp, 56, $19 >> 404 bic $sp, $8, $8 >> 405 jsr $26, do_entUnaUser >> 406 ldq $9, 0($sp) >> 407 ldq $10, 8($sp) >> 408 ldq $11, 16($sp) >> 409 ldq $12, 24($sp) >> 410 ldq $13, 32($sp) >> 411 ldq $14, 40($sp) >> 412 ldq $15, 48($sp) >> 413 lda $sp, 56($sp) >> 414 .cfi_restore $9 >> 415 .cfi_restore $10 >> 416 .cfi_restore $11 >> 417 .cfi_restore $12 >> 418 .cfi_restore $13 >> 419 .cfi_restore $14 >> 420 .cfi_restore $15 >> 421 .cfi_adjust_cfa_offset -56 >> 422 br ret_from_sys_call >> 423 CFI_END_OSF_FRAME entUna 406 424 407 ENTRY(sys_rt_sigreturn) !! 425 CFI_START_OSF_FRAME entDbg 408 SAVE_SWITCH_STACK !! 426 SAVE_ALL 409 mov r4, sp !! 427 lda $8, 0x3fff 410 call do_rt_sigreturn !! 428 lda $26, ret_from_sys_call 411 RESTORE_SWITCH_STACK !! 429 bic $sp, $8, $8 412 addi ra, ra, (end_translate_rc_and_ !! 430 mov $sp, $16 413 ret !! 431 jsr $31, do_entDbg >> 432 CFI_END_OSF_FRAME entDbg >> 433 >> 434 /* >> 435 * The system call entry point is special. Most importantly, it looks >> 436 * like a function call to userspace as far as clobbered registers. We >> 437 * do preserve the argument registers (for syscall restarts) and $26 >> 438 * (for leaf syscall functions). >> 439 * >> 440 * So much for theory. We don't take advantage of this yet. >> 441 * >> 442 * Note that a0-a2 are not saved by PALcode as with the other entry points. >> 443 */ 414 444 415 /********************************************* !! 445 .align 4 416 * A few other wrappers and stubs !! 446 .globl entSys 417 ********************************************* !! 447 .type entSys, @function 418 */ !! 448 .cfi_startproc simple 419 protection_exception_pte: !! 449 .cfi_return_column 64 420 rdctl r6, pteaddr !! 450 .cfi_def_cfa $sp, 48 421 slli r6, r6, 10 !! 451 .cfi_rel_offset 64, 8 422 call do_page_fault !! 452 .cfi_rel_offset $gp, 16 423 br ret_from_exception !! 453 entSys: 424 !! 454 SAVE_ALL 425 protection_exception_ba: !! 455 lda $8, 0x3fff 426 rdctl r6, badaddr !! 456 bic $sp, $8, $8 427 call do_page_fault !! 457 lda $4, NR_SYSCALLS($31) 428 br ret_from_exception !! 458 stq $16, SP_OFF+24($sp) 429 !! 459 lda $5, sys_call_table 430 protection_exception_instr: !! 460 lda $27, sys_ni_syscall 431 call handle_supervisor_instr !! 461 cmpult $0, $4, $4 432 br ret_from_exception !! 462 ldl $3, TI_FLAGS($8) 433 !! 463 stq $17, SP_OFF+32($sp) 434 handle_breakpoint: !! 464 s8addq $0, $5, $5 435 call breakpoint_c !! 465 stq $18, SP_OFF+40($sp) 436 br ret_from_exception !! 466 .cfi_rel_offset $16, SP_OFF+24 437 !! 467 .cfi_rel_offset $17, SP_OFF+32 438 #ifdef CONFIG_NIOS2_ALIGNMENT_TRAP !! 468 .cfi_rel_offset $18, SP_OFF+40 439 handle_unaligned: !! 469 #ifdef CONFIG_AUDITSYSCALL 440 SAVE_SWITCH_STACK !! 470 lda $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT 441 call handle_unaligned_c !! 471 and $3, $6, $3 442 RESTORE_SWITCH_STACK !! 472 bne $3, strace 443 br ret_from_exception << 444 #else 473 #else 445 handle_unaligned: !! 474 blbs $3, strace /* check for SYSCALL_TRACE in disguise */ 446 call handle_unaligned_c << 447 br ret_from_exception << 448 #endif << 449 << 450 handle_illegal: << 451 call handle_illegal_c << 452 br ret_from_exception << 453 << 454 handle_diverror: << 455 call handle_diverror_c << 456 br ret_from_exception << 457 << 458 #ifdef CONFIG_KGDB << 459 handle_kgdb_breakpoint: << 460 call kgdb_breakpoint_c << 461 br ret_from_exception << 462 #endif 475 #endif >> 476 beq $4, 1f >> 477 ldq $27, 0($5) >> 478 1: jsr $26, ($27), alpha_ni_syscall >> 479 ldgp $gp, 0($26) >> 480 blt $0, $syscall_error /* the call failed */ >> 481 stq $0, 0($sp) >> 482 stq $31, 72($sp) /* a3=0 => no error */ >> 483 >> 484 .align 4 >> 485 .globl ret_from_sys_call >> 486 ret_from_sys_call: >> 487 cmovne $26, 0, $18 /* $18 = 0 => non-restartable */ >> 488 ldq $0, SP_OFF($sp) >> 489 and $0, 8, $0 >> 490 beq $0, ret_to_kernel >> 491 ret_to_user: >> 492 /* Make sure need_resched and sigpending don't change between >> 493 sampling and the rti. */ >> 494 lda $16, 7 >> 495 call_pal PAL_swpipl >> 496 ldl $17, TI_FLAGS($8) >> 497 and $17, _TIF_WORK_MASK, $2 >> 498 bne $2, work_pending >> 499 restore_all: >> 500 .cfi_remember_state >> 501 RESTORE_ALL >> 502 call_pal PAL_rti 463 503 464 handle_trap_1: !! 504 ret_to_kernel: 465 call handle_trap_1_c !! 505 .cfi_restore_state 466 br ret_from_exception !! 506 lda $16, 7 467 !! 507 call_pal PAL_swpipl 468 handle_trap_2: !! 508 br restore_all 469 call handle_trap_2_c << 470 br ret_from_exception << 471 << 472 handle_trap_3: << 473 handle_trap_reserved: << 474 call handle_trap_3_c << 475 br ret_from_exception << 476 << 477 /* << 478 * Beware - when entering resume, prev (the cu << 479 * in r4, next (the new task) is in r5, don't << 480 * registers. << 481 */ << 482 ENTRY(resume) << 483 << 484 rdctl r7, status << 485 stw r7, TASK_THREAD + THREAD_KPSR( << 486 << 487 andi r7, r7, %lo(~STATUS_PIE) << 488 wrctl status, r7 << 489 << 490 SAVE_SWITCH_STACK << 491 stw sp, TASK_THREAD + THREAD_KSP(r << 492 ldw sp, TASK_THREAD + THREAD_KSP(r << 493 movia r24, _current_thread << 494 GET_THREAD_INFO r1 << 495 stw r1, 0(r24) << 496 RESTORE_SWITCH_STACK << 497 509 498 ldw r7, TASK_THREAD + THREAD_KPSR( !! 510 .align 3 499 wrctl status, r7 !! 511 $syscall_error: 500 ret !! 512 /* >> 513 * Some system calls (e.g., ptrace) can return arbitrary >> 514 * values which might normally be mistaken as error numbers. >> 515 * Those functions must zero $0 (v0) directly in the stack >> 516 * frame to indicate that a negative return value wasn't an >> 517 * error number.. >> 518 */ >> 519 ldq $18, 0($sp) /* old syscall nr (zero if success) */ >> 520 beq $18, $ret_success 501 521 502 ENTRY(ret_from_fork) !! 522 ldq $19, 72($sp) /* .. and this a3 */ 503 call schedule_tail !! 523 subq $31, $0, $0 /* with error in v0 */ 504 br ret_from_exception !! 524 addq $31, 1, $1 /* set a3 for errno return */ 505 !! 525 stq $0, 0($sp) 506 ENTRY(ret_from_kernel_thread) !! 526 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ 507 call schedule_tail !! 527 stq $1, 72($sp) /* a3 for return */ 508 mov r4,r17 /* arg */ !! 528 br ret_from_sys_call 509 callr r16 /* function */ !! 529 510 br ret_from_exception !! 530 $ret_success: >> 531 stq $0, 0($sp) >> 532 stq $31, 72($sp) /* a3=0 => no error */ >> 533 br ret_from_sys_call 511 534 512 /* 535 /* 513 * Kernel user helpers. !! 536 * Do all cleanup when returning from all interrupts and system calls. 514 * << 515 * Each segment is 64-byte aligned and will be << 516 * New segments (if ever needed) must be added << 517 * This mechanism should be used only for thin << 518 * justified, and not be abused freely. << 519 * 537 * >> 538 * Arguments: >> 539 * $8: current. >> 540 * $17: TI_FLAGS. >> 541 * $18: The old syscall number, or zero if this is not a return >> 542 * from a syscall that errored and is possibly restartable. >> 543 * $19: The old a3 value 520 */ 544 */ 521 545 522 /* Filling pads with undefined instructions. !! 546 .align 4 523 .macro kuser_pad sym size !! 547 .type work_pending, @function 524 .if ((. - \sym) & 3) !! 548 work_pending: 525 .rept (4 - (. - \sym) & 3) !! 549 and $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING, $2 526 .byte 0 !! 550 bne $2, $work_notifysig 527 .endr << 528 .endif << 529 .rept ((\size - (. - \sym)) / 4) << 530 .word 0xdeadbeef << 531 .endr << 532 .endm << 533 << 534 .align 6 << 535 .globl __kuser_helper_start << 536 __kuser_helper_start: << 537 << 538 __kuser_helper_version: << 539 .word ((__kuser_helper_end - __kuser << 540 551 541 __kuser_cmpxchg: !! 552 $work_resched: 542 /* 553 /* 543 * r4 pointer to exchange variable !! 554 * We can get here only if we returned from syscall without SIGPENDING 544 * r5 old value !! 555 * or got through work_notifysig already. Either case means no syscall 545 * r6 new value !! 556 * restarts for us, so let $18 and $19 burn. 546 */ 557 */ 547 cmpxchg_ldw: !! 558 jsr $26, schedule 548 ldw r2, 0(r4) !! 559 mov 0, $18 549 sub r2, r2, r5 !! 560 br ret_to_user 550 bne r2, zero, cmpxchg_ret !! 561 551 !! 562 $work_notifysig: 552 /* We had a match, store the new value !! 563 mov $sp, $16 553 cmpxchg_stw: !! 564 DO_SWITCH_STACK 554 stw r6, 0(r4) !! 565 jsr $26, do_work_pending 555 cmpxchg_ret: !! 566 UNDO_SWITCH_STACK >> 567 br restore_all >> 568 >> 569 /* >> 570 * PTRACE syscall handler >> 571 */ >> 572 >> 573 .align 4 >> 574 .type strace, @function >> 575 strace: >> 576 /* set up signal stack, call syscall_trace */ >> 577 DO_SWITCH_STACK >> 578 jsr $26, syscall_trace_enter /* returns the syscall number */ >> 579 UNDO_SWITCH_STACK >> 580 >> 581 /* get the arguments back.. */ >> 582 ldq $16, SP_OFF+24($sp) >> 583 ldq $17, SP_OFF+32($sp) >> 584 ldq $18, SP_OFF+40($sp) >> 585 ldq $19, 72($sp) >> 586 ldq $20, 80($sp) >> 587 ldq $21, 88($sp) >> 588 >> 589 /* get the system call pointer.. */ >> 590 lda $1, NR_SYSCALLS($31) >> 591 lda $2, sys_call_table >> 592 lda $27, alpha_ni_syscall >> 593 cmpult $0, $1, $1 >> 594 s8addq $0, $2, $2 >> 595 beq $1, 1f >> 596 ldq $27, 0($2) >> 597 1: jsr $26, ($27), sys_gettimeofday >> 598 ret_from_straced: >> 599 ldgp $gp, 0($26) >> 600 >> 601 /* check return.. */ >> 602 blt $0, $strace_error /* the call failed */ >> 603 stq $31, 72($sp) /* a3=0 => no error */ >> 604 $strace_success: >> 605 stq $0, 0($sp) /* save return value */ >> 606 >> 607 DO_SWITCH_STACK >> 608 jsr $26, syscall_trace_leave >> 609 UNDO_SWITCH_STACK >> 610 br $31, ret_from_sys_call >> 611 >> 612 .align 3 >> 613 $strace_error: >> 614 ldq $18, 0($sp) /* old syscall nr (zero if success) */ >> 615 beq $18, $strace_success >> 616 ldq $19, 72($sp) /* .. and this a3 */ >> 617 >> 618 subq $31, $0, $0 /* with error in v0 */ >> 619 addq $31, 1, $1 /* set a3 for errno return */ >> 620 stq $0, 0($sp) >> 621 stq $1, 72($sp) /* a3 for return */ >> 622 >> 623 DO_SWITCH_STACK >> 624 mov $18, $9 /* save old syscall number */ >> 625 mov $19, $10 /* save old a3 */ >> 626 jsr $26, syscall_trace_leave >> 627 mov $9, $18 >> 628 mov $10, $19 >> 629 UNDO_SWITCH_STACK >> 630 >> 631 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ >> 632 br ret_from_sys_call >> 633 CFI_END_OSF_FRAME entSys >> 634 >> 635 /* >> 636 * Save and restore the switch stack -- aka the balance of the user context. >> 637 */ >> 638 >> 639 .align 4 >> 640 .type do_switch_stack, @function >> 641 .cfi_startproc simple >> 642 .cfi_return_column 64 >> 643 .cfi_def_cfa $sp, 0 >> 644 .cfi_register 64, $1 >> 645 do_switch_stack: >> 646 lda $sp, -SWITCH_STACK_SIZE($sp) >> 647 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE >> 648 stq $9, 0($sp) >> 649 stq $10, 8($sp) >> 650 stq $11, 16($sp) >> 651 stq $12, 24($sp) >> 652 stq $13, 32($sp) >> 653 stq $14, 40($sp) >> 654 stq $15, 48($sp) >> 655 stq $26, 56($sp) >> 656 stt $f0, 64($sp) >> 657 stt $f1, 72($sp) >> 658 stt $f2, 80($sp) >> 659 stt $f3, 88($sp) >> 660 stt $f4, 96($sp) >> 661 stt $f5, 104($sp) >> 662 stt $f6, 112($sp) >> 663 stt $f7, 120($sp) >> 664 stt $f8, 128($sp) >> 665 stt $f9, 136($sp) >> 666 stt $f10, 144($sp) >> 667 stt $f11, 152($sp) >> 668 stt $f12, 160($sp) >> 669 stt $f13, 168($sp) >> 670 stt $f14, 176($sp) >> 671 stt $f15, 184($sp) >> 672 stt $f16, 192($sp) >> 673 stt $f17, 200($sp) >> 674 stt $f18, 208($sp) >> 675 stt $f19, 216($sp) >> 676 stt $f20, 224($sp) >> 677 stt $f21, 232($sp) >> 678 stt $f22, 240($sp) >> 679 stt $f23, 248($sp) >> 680 stt $f24, 256($sp) >> 681 stt $f25, 264($sp) >> 682 stt $f26, 272($sp) >> 683 stt $f27, 280($sp) >> 684 mf_fpcr $f0 # get fpcr >> 685 stt $f28, 288($sp) >> 686 stt $f29, 296($sp) >> 687 stt $f30, 304($sp) >> 688 stt $f0, 312($sp) # save fpcr in slot of $f31 >> 689 ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state. >> 690 ret $31, ($1), 1 >> 691 .cfi_endproc >> 692 .size do_switch_stack, .-do_switch_stack >> 693 >> 694 .align 4 >> 695 .type undo_switch_stack, @function >> 696 .cfi_startproc simple >> 697 .cfi_def_cfa $sp, 0 >> 698 .cfi_register 64, $1 >> 699 undo_switch_stack: >> 700 ldq $9, 0($sp) >> 701 ldq $10, 8($sp) >> 702 ldq $11, 16($sp) >> 703 ldq $12, 24($sp) >> 704 ldq $13, 32($sp) >> 705 ldq $14, 40($sp) >> 706 ldq $15, 48($sp) >> 707 ldq $26, 56($sp) >> 708 ldt $f30, 312($sp) # get saved fpcr >> 709 ldt $f0, 64($sp) >> 710 ldt $f1, 72($sp) >> 711 ldt $f2, 80($sp) >> 712 ldt $f3, 88($sp) >> 713 mt_fpcr $f30 # install saved fpcr >> 714 ldt $f4, 96($sp) >> 715 ldt $f5, 104($sp) >> 716 ldt $f6, 112($sp) >> 717 ldt $f7, 120($sp) >> 718 ldt $f8, 128($sp) >> 719 ldt $f9, 136($sp) >> 720 ldt $f10, 144($sp) >> 721 ldt $f11, 152($sp) >> 722 ldt $f12, 160($sp) >> 723 ldt $f13, 168($sp) >> 724 ldt $f14, 176($sp) >> 725 ldt $f15, 184($sp) >> 726 ldt $f16, 192($sp) >> 727 ldt $f17, 200($sp) >> 728 ldt $f18, 208($sp) >> 729 ldt $f19, 216($sp) >> 730 ldt $f20, 224($sp) >> 731 ldt $f21, 232($sp) >> 732 ldt $f22, 240($sp) >> 733 ldt $f23, 248($sp) >> 734 ldt $f24, 256($sp) >> 735 ldt $f25, 264($sp) >> 736 ldt $f26, 272($sp) >> 737 ldt $f27, 280($sp) >> 738 ldt $f28, 288($sp) >> 739 ldt $f29, 296($sp) >> 740 ldt $f30, 304($sp) >> 741 lda $sp, SWITCH_STACK_SIZE($sp) >> 742 ret $31, ($1), 1 >> 743 .cfi_endproc >> 744 .size undo_switch_stack, .-undo_switch_stack >> 745 >> 746 /* >> 747 * The meat of the context switch code. >> 748 */ >> 749 >> 750 .align 4 >> 751 .globl alpha_switch_to >> 752 .type alpha_switch_to, @function >> 753 .cfi_startproc >> 754 alpha_switch_to: >> 755 DO_SWITCH_STACK >> 756 call_pal PAL_swpctx >> 757 lda $8, 0x3fff >> 758 UNDO_SWITCH_STACK >> 759 bic $sp, $8, $8 >> 760 mov $17, $0 556 ret 761 ret >> 762 .cfi_endproc >> 763 .size alpha_switch_to, .-alpha_switch_to >> 764 >> 765 /* >> 766 * New processes begin life here. >> 767 */ 557 768 558 kuser_pad __kuser_cmpxchg, 64 !! 769 .globl ret_from_fork >> 770 .align 4 >> 771 .ent ret_from_fork >> 772 ret_from_fork: >> 773 lda $26, ret_from_sys_call >> 774 mov $17, $16 >> 775 jmp $31, schedule_tail >> 776 .end ret_from_fork 559 777 560 .globl __kuser_sigtramp !! 778 /* 561 __kuser_sigtramp: !! 779 * ... and new kernel threads - here 562 movi r2, __NR_rt_sigreturn !! 780 */ 563 trap !! 781 .align 4 >> 782 .globl ret_from_kernel_thread >> 783 .ent ret_from_kernel_thread >> 784 ret_from_kernel_thread: >> 785 mov $17, $16 >> 786 jsr $26, schedule_tail >> 787 mov $9, $27 >> 788 mov $10, $16 >> 789 jsr $26, ($9) >> 790 mov $31, $19 /* to disable syscall restarts */ >> 791 br $31, ret_to_user >> 792 .end ret_from_kernel_thread 564 793 565 kuser_pad __kuser_sigtramp, 64 !! 794 >> 795 /* >> 796 * Special system calls. Most of these are special in that they either >> 797 * have to play switch_stack games or in some way use the pt_regs struct. >> 798 */ 566 799 567 .globl __kuser_helper_end !! 800 .macro fork_like name 568 __kuser_helper_end: !! 801 .align 4 >> 802 .globl alpha_\name >> 803 .ent alpha_\name >> 804 alpha_\name: >> 805 .prologue 0 >> 806 bsr $1, do_switch_stack >> 807 jsr $26, sys_\name >> 808 ldq $26, 56($sp) >> 809 lda $sp, SWITCH_STACK_SIZE($sp) >> 810 ret >> 811 .end alpha_\name >> 812 .endm >> 813 >> 814 fork_like fork >> 815 fork_like vfork >> 816 fork_like clone >> 817 >> 818 .align 4 >> 819 .globl sys_sigreturn >> 820 .ent sys_sigreturn >> 821 sys_sigreturn: >> 822 .prologue 0 >> 823 lda $9, ret_from_straced >> 824 cmpult $26, $9, $9 >> 825 lda $sp, -SWITCH_STACK_SIZE($sp) >> 826 jsr $26, do_sigreturn >> 827 bne $9, 1f >> 828 jsr $26, syscall_trace_leave >> 829 1: br $1, undo_switch_stack >> 830 br ret_from_sys_call >> 831 .end sys_sigreturn >> 832 >> 833 .align 4 >> 834 .globl sys_rt_sigreturn >> 835 .ent sys_rt_sigreturn >> 836 sys_rt_sigreturn: >> 837 .prologue 0 >> 838 lda $9, ret_from_straced >> 839 cmpult $26, $9, $9 >> 840 lda $sp, -SWITCH_STACK_SIZE($sp) >> 841 jsr $26, do_rt_sigreturn >> 842 bne $9, 1f >> 843 jsr $26, syscall_trace_leave >> 844 1: br $1, undo_switch_stack >> 845 br ret_from_sys_call >> 846 .end sys_rt_sigreturn >> 847 >> 848 .align 4 >> 849 .globl alpha_ni_syscall >> 850 .ent alpha_ni_syscall >> 851 alpha_ni_syscall: >> 852 .prologue 0 >> 853 /* Special because it also implements overflow handling via >> 854 syscall number 0. And if you recall, zero is a special >> 855 trigger for "not an error". Store large non-zero there. */ >> 856 lda $0, -ENOSYS >> 857 unop >> 858 stq $0, 0($sp) >> 859 ret >> 860 .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.