2 * arch/alpha/kernel/entry.S
7 #include <linux/config.h>
8 #include <asm/asm_offsets.h>
9 #include <asm/thread_info.h>
11 #include <asm/errno.h>
12 #include <asm/unistd.h>
19 #define SWITCH_STACK_SIZE 320
22 * This defines the normal kernel pt-regs layout.
24 * regs 9-15 preserved by C code
25 * regs 16-18 saved by PAL-code
26 * regs 29-30 saved and set up by PAL-code
27 * JRP - Save regs 16-18 in a special area of the stack, so that
28 * the palcode-provided values are available to the signal handler.
32 subq $sp, SP_OFF, $sp; \
47 ldq $2, HAE_CACHE($2); \
66 ldq $20, HAE_CACHE($19); \
74 ldq $20, HAE_REG($19); \
75 stq $21, HAE_CACHE($19); \
93 * Non-syscall kernel entry points.
102 lda $26, ret_from_sys_call
114 lda $26, ret_from_sys_call
125 /* save $9 - $15 so the inline exception code can manipulate them. */
135 /* handle the fault */
138 jsr $26, do_page_fault
139 /* reload the registers after the exception code played. */
148 /* finish up the syscall as normal. */
158 lda $26, ret_from_sys_call
170 ldq $0, 256($sp) /* get PS */
174 and $0, 8, $0 /* user mode? */
176 bne $0, entUnaUser /* yup -> do user-level unaligned fault */
188 /* 16-18 PAL-saved */
220 /* 16-18 PAL-saved */
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 */
253 jsr $26, do_entUnaUser
271 lda $26, ret_from_sys_call
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).
283 * So much for theory. We don't take advantage of this yet.
285 * Note that a0-a2 are not saved by PALcode as with the other entry points.
290 .globl ret_from_sys_call
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
302 stq $17, SP_OFF+32($sp)
304 stq $18, SP_OFF+40($sp)
308 1: jsr $26, ($27), alpha_ni_syscall
310 blt $0, $syscall_error /* the call failed */
312 stq $31, 72($sp) /* a3=0 => no error */
316 cmovne $26, 0, $19 /* $19 = 0 => non-restartable */
321 /* Make sure need_resched and sigpending don't change between
322 sampling and the rti. */
326 and $5, _TIF_WORK_MASK, $2
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
341 ldq $19, 0($sp) /* old syscall nr (zero if success) */
342 beq $19, $ret_success
344 ldq $20, 72($sp) /* .. and this a3 */
345 subq $31, $0, $0 /* with error in v0 */
346 addq $31, 1, $1 /* set a3 for errno return */
348 mov $31, $26 /* tell "ret_from_sys_call" we can restart */
349 stq $1, 72($sp) /* a3 for return */
354 stq $31, 72($sp) /* a3=0 => no error */
359 * Do all cleanup when returning from all interrupts and system calls.
364 * $19: The old syscall number, or zero if this is not a return
365 * from a syscall that errored and is possibly restartable.
366 * $20: Error indication.
372 and $5, _TIF_NEED_RESCHED, $2
373 beq $2, $work_notifysig
377 stq $19, 0($sp) /* save syscall nr */
378 stq $20, 8($sp) /* and error indication (a3) */
383 /* Make sure need_resched and sigpending don't change between
384 sampling and the rti. */
388 and $5, _TIF_WORK_MASK, $2
390 and $5, _TIF_NEED_RESCHED, $2
391 bne $2, $work_resched
395 br $1, do_switch_stack
399 jsr $26, do_notify_resume
400 bsr $1, undo_switch_stack
405 * PTRACE syscall handler
411 /* set up signal stack, call syscall_trace */
412 bsr $1, do_switch_stack
413 jsr $26, syscall_trace
414 bsr $1, undo_switch_stack
416 /* get the system call number and the arguments back.. */
418 ldq $16, SP_OFF+24($sp)
419 ldq $17, SP_OFF+32($sp)
420 ldq $18, SP_OFF+40($sp)
425 /* get the system call pointer.. */
426 lda $1, NR_SYSCALLS($31)
427 lda $2, sys_call_table
428 lda $27, alpha_ni_syscall
433 1: jsr $26, ($27), sys_gettimeofday
437 blt $0, $strace_error /* the call failed */
438 stq $31, 72($sp) /* a3=0 => no error */
440 stq $0, 0($sp) /* save return value */
442 bsr $1, do_switch_stack
443 jsr $26, syscall_trace
444 bsr $1, undo_switch_stack
445 br $31, ret_from_sys_call
449 ldq $19, 0($sp) /* old syscall nr (zero if success) */
450 beq $19, $strace_success
451 ldq $20, 72($sp) /* .. and this a3 */
453 subq $31, $0, $0 /* with error in v0 */
454 addq $31, 1, $1 /* set a3 for errno return */
456 stq $1, 72($sp) /* a3 for return */
458 bsr $1, do_switch_stack
459 mov $19, $9 /* save old syscall number */
460 mov $20, $10 /* save old a3 */
461 jsr $26, syscall_trace
464 bsr $1, undo_switch_stack
466 mov $31, $26 /* tell "ret_from_sys_call" we can restart */
471 * Save and restore the switch stack -- aka the balance of the user context.
477 lda $sp, -SWITCH_STACK_SIZE($sp)
514 mf_fpcr $f0 # get fpcr
518 stt $f0, 312($sp) # save fpcr in slot of $f31
519 ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state.
524 .ent undo_switch_stack
534 ldt $f30, 312($sp) # get saved fpcr
539 mt_fpcr $f30 # install saved fpcr
567 lda $sp, SWITCH_STACK_SIZE($sp)
569 .end undo_switch_stack
572 * The meat of the context switch code.
576 .globl alpha_switch_to
580 bsr $1, do_switch_stack
583 bsr $1, undo_switch_stack
589 * New processes begin life here.
593 #if CONFIG_SMP || CONFIG_PREEMPT
597 lda $26, ret_from_sys_call
599 jmp $31, schedule_tail
602 ret_from_fork = ret_from_sys_call
606 * kernel_thread(fn, arg, clone_flags)
612 ldgp $gp, 0($27) /* we can be called from a module */
614 subq $sp, SP_OFF+6*8, $sp
615 br $1, 2f /* load start address */
617 /* We've now "returned" from a fake system call. */
619 blt $0, 1f /* error? */
621 beq $20, 1f /* parent or child? */
623 bic $sp, $1, $8 /* in child. */
630 1: ret /* in parent. */
633 2: /* Fake a system call stack frame, as we can't do system calls
634 from kernel space. Note that we store FN and ARG as they
635 need to be set up in the child for the call. Also store $8
636 and $26 for use in the parent. */
637 stq $31, SP_OFF($sp) /* ps */
638 stq $1, SP_OFF+8($sp) /* pc */
639 stq $gp, SP_OFF+16($sp) /* gp */
640 stq $16, 136($sp) /* $27; FN for child */
641 stq $17, SP_OFF+24($sp) /* $16; ARG for child */
642 stq $8, 64($sp) /* $8 */
643 stq $26, 128($sp) /* $26 */
644 /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */
645 ldq $2, alpha_mv+HAE_CACHE
646 stq $2, 152($sp) /* HAE */
648 /* Shuffle FLAGS to the front; add CLONE_VM. */
649 ldi $1, CLONE_VM|CLONE_UNTRACED
653 /* We don't actually care for a3 success widgetry in the kernel.
654 Not for positive errno values. */
655 stq $0, 0($sp) /* $0 */
660 * __kernel_execve(path, argv, envp, regs)
663 .globl __kernel_execve
666 ldgp $gp, 0($27) /* we can be called from modules. */
668 .frame $sp, 16, $26, 0
673 bne $0, 1f /* error! */
675 br $31, ret_from_sys_call
683 * Special system calls. Most of these are special in that they either
684 * have to play switch_stack games or in some way use the pt_regs struct.
692 bsr $1, do_switch_stack
693 bis $31, SIGCHLD, $16
699 bsr $1, undo_switch_stack
709 bsr $1, do_switch_stack
710 /* $16, $17, $18, $19, $20 come from the user. */
712 bsr $1, undo_switch_stack
722 bsr $1, do_switch_stack
724 bsr $1, undo_switch_stack
734 lda $18, -SWITCH_STACK_SIZE($sp)
735 lda $sp, -SWITCH_STACK_SIZE($sp)
736 jsr $26, do_sigreturn
737 br $1, undo_switch_stack
742 .globl sys_rt_sigreturn
743 .ent sys_rt_sigreturn
747 lda $18, -SWITCH_STACK_SIZE($sp)
748 lda $sp, -SWITCH_STACK_SIZE($sp)
749 jsr $26, do_rt_sigreturn
750 br $1, undo_switch_stack
752 .end sys_rt_sigreturn
755 .globl sys_sigsuspend
760 br $1, do_switch_stack
764 jsr $26, do_sigsuspend
766 lda $sp, SWITCH_STACK_SIZE+16($sp)
771 .globl sys_rt_sigsuspend
772 .ent sys_rt_sigsuspend
776 br $1, do_switch_stack
780 jsr $26, do_rt_sigsuspend
782 lda $sp, SWITCH_STACK_SIZE+16($sp)
784 .end sys_rt_sigsuspend
796 .globl osf_getpriority
803 jsr $26, sys_getpriority
808 /* Return value is the unbiased priority, i.e. 20 - prio.
809 This does result in negative return values, so signal
810 no error by writing into the R0 slot. */
827 ldl $1, TASK_EUID($2)
839 ldl $1, TASK_EGID($2)
851 /* See linux/kernel/timer.c sys_getppid for discussion
853 ldq $3, TASK_REAL_PARENT($2)
854 1: ldl $1, TASK_TGID($3)
858 ldq $3, TASK_REAL_PARENT($2)
863 ldl $0, TASK_TGID($2)
881 /* The return values are in $0 and $20. */
896 jmp $31, do_sys_ptrace
900 .globl alpha_ni_syscall
901 .ent alpha_ni_syscall
904 /* Special because it also implements overflow handling via
905 syscall number 0. And if you recall, zero is a special
906 trigger for "not an error". Store large non-zero there. */
911 .end alpha_ni_syscall