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 */
221 /* 16-18 PAL-saved */
240 ldq $0, 0($sp) /* restore original $0 */
241 lda $sp, 256($sp) /* pop entUna's stack frame */
242 SAVE_ALL /* setup normal kernel stack */
254 jsr $26, do_entUnaUser
272 lda $26, ret_from_sys_call
279 * The system call entry point is special. Most importantly, it looks
280 * like a function call to userspace as far as clobbered registers. We
281 * do preserve the argument registers (for syscall restarts) and $26
282 * (for leaf syscall functions).
284 * So much for theory. We don't take advantage of this yet.
286 * Note that a0-a2 are not saved by PALcode as with the other entry points.
291 .globl ret_from_sys_call
297 lda $4, NR_SYSCALLS($31)
298 stq $16, SP_OFF+24($sp)
299 lda $5, sys_call_table
300 lda $27, sys_ni_syscall
303 stq $17, SP_OFF+32($sp)
305 stq $18, SP_OFF+40($sp)
309 1: jsr $26, ($27), alpha_ni_syscall
311 blt $0, $syscall_error /* the call failed */
313 stq $31, 72($sp) /* a3=0 => no error */
317 cmovne $26, 0, $19 /* $19 = 0 => non-restartable */
322 /* Make sure need_resched and sigpending don't change between
323 sampling and the rti. */
327 and $5, _TIF_WORK_MASK, $2
336 * Some system calls (e.g., ptrace) can return arbitrary
337 * values which might normally be mistaken as error numbers.
338 * Those functions must zero $0 (v0) directly in the stack
339 * frame to indicate that a negative return value wasn't an
342 ldq $19, 0($sp) /* old syscall nr (zero if success) */
343 beq $19, $ret_success
345 ldq $20, 72($sp) /* .. and this a3 */
346 subq $31, $0, $0 /* with error in v0 */
347 addq $31, 1, $1 /* set a3 for errno return */
349 mov $31, $26 /* tell "ret_from_sys_call" we can restart */
350 stq $1, 72($sp) /* a3 for return */
355 stq $31, 72($sp) /* a3=0 => no error */
360 * Do all cleanup when returning from all interrupts and system calls.
365 * $19: The old syscall number, or zero if this is not a return
366 * from a syscall that errored and is possibly restartable.
367 * $20: Error indication.
373 and $5, _TIF_NEED_RESCHED, $2
374 beq $2, $work_notifysig
378 stq $19, 0($sp) /* save syscall nr */
379 stq $20, 8($sp) /* and error indication (a3) */
384 /* Make sure need_resched and sigpending don't change between
385 sampling and the rti. */
389 and $5, _TIF_WORK_MASK, $2
391 and $5, _TIF_NEED_RESCHED, $2
392 bne $2, $work_resched
396 br $1, do_switch_stack
400 jsr $26, do_notify_resume
401 bsr $1, undo_switch_stack
406 * PTRACE syscall handler
412 /* set up signal stack, call syscall_trace */
413 bsr $1, do_switch_stack
414 jsr $26, syscall_trace
415 bsr $1, undo_switch_stack
417 /* get the system call number and the arguments back.. */
419 ldq $16, SP_OFF+24($sp)
420 ldq $17, SP_OFF+32($sp)
421 ldq $18, SP_OFF+40($sp)
426 /* get the system call pointer.. */
427 lda $1, NR_SYSCALLS($31)
428 lda $2, sys_call_table
429 lda $27, alpha_ni_syscall
434 1: jsr $26, ($27), sys_gettimeofday
438 blt $0, $strace_error /* the call failed */
439 stq $31, 72($sp) /* a3=0 => no error */
441 stq $0, 0($sp) /* save return value */
443 bsr $1, do_switch_stack
444 jsr $26, syscall_trace
445 bsr $1, undo_switch_stack
446 br $31, ret_from_sys_call
450 ldq $19, 0($sp) /* old syscall nr (zero if success) */
451 beq $19, $strace_success
452 ldq $20, 72($sp) /* .. and this a3 */
454 subq $31, $0, $0 /* with error in v0 */
455 addq $31, 1, $1 /* set a3 for errno return */
457 stq $1, 72($sp) /* a3 for return */
459 bsr $1, do_switch_stack
460 mov $19, $9 /* save old syscall number */
461 mov $20, $10 /* save old a3 */
462 jsr $26, syscall_trace
465 bsr $1, undo_switch_stack
467 mov $31, $26 /* tell "ret_from_sys_call" we can restart */
472 * Save and restore the switch stack -- aka the balance of the user context.
478 lda $sp, -SWITCH_STACK_SIZE($sp)
515 mf_fpcr $f0 # get fpcr
519 stt $f0, 312($sp) # save fpcr in slot of $f31
520 ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state.
525 .ent undo_switch_stack
535 ldt $f30, 312($sp) # get saved fpcr
540 mt_fpcr $f30 # install saved fpcr
568 lda $sp, SWITCH_STACK_SIZE($sp)
570 .end undo_switch_stack
573 * The meat of the context switch code.
577 .globl alpha_switch_to
581 bsr $1, do_switch_stack
584 bsr $1, undo_switch_stack
591 * New processes begin life here.
598 lda $26, ret_from_sys_call
600 jmp $31, schedule_tail
604 * kernel_thread(fn, arg, clone_flags)
610 /* We can be called from a module. */
613 subq $sp, SP_OFF+6*8, $sp
614 br $1, 2f /* load start address */
616 /* We've now "returned" from a fake system call. */
618 blt $0, 1f /* error? */
620 beq $20, 1f /* parent or child? */
622 bic $sp, $1, $8 /* in child. */
629 1: ret /* in parent. */
632 2: /* Fake a system call stack frame, as we can't do system calls
633 from kernel space. Note that we store FN and ARG as they
634 need to be set up in the child for the call. Also store $8
635 and $26 for use in the parent. */
636 stq $31, SP_OFF($sp) /* ps */
637 stq $1, SP_OFF+8($sp) /* pc */
638 stq $gp, SP_OFF+16($sp) /* gp */
639 stq $16, 136($sp) /* $27; FN for child */
640 stq $17, SP_OFF+24($sp) /* $16; ARG for child */
641 stq $8, 64($sp) /* $8 */
642 stq $26, 128($sp) /* $26 */
643 /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */
644 ldq $2, alpha_mv+HAE_CACHE
645 stq $2, 152($sp) /* HAE */
647 /* Shuffle FLAGS to the front; add CLONE_VM. */
648 ldi $1, CLONE_VM|CLONE_UNTRACED
652 /* We don't actually care for a3 success widgetry in the kernel.
653 Not for positive errno values. */
654 stq $0, 0($sp) /* $0 */
659 * execve(path, argv, envp)
665 /* We can be called from a module. */
667 lda $sp, -(32+SIZEOF_PT_REGS+8)($sp)
668 .frame $sp, 32+SIZEOF_PT_REGS+8, $26, 0
677 lda $18, SIZEOF_PT_REGS
678 bsr $26, memset !samegp
680 /* Avoid the HAE being gratuitously wrong, which would cause us
681 to do the whole turn off interrupts thing and restore it. */
682 ldq $2, alpha_mv+HAE_CACHE
689 bsr $26, do_execve !samegp
692 bne $0, 1f /* error! */
694 /* Move the temporary pt_regs struct from its current location
695 to the top of the kernel stack frame. See copy_thread for
696 details for a normal process. */
697 lda $16, 0x4000 - SIZEOF_PT_REGS($8)
699 lda $18, SIZEOF_PT_REGS
700 bsr $26, memmove !samegp
702 /* Take that over as our new stack frame and visit userland! */
703 lda $sp, 0x4000 - SIZEOF_PT_REGS($8)
704 br $31, ret_from_sys_call
706 1: lda $sp, 32+SIZEOF_PT_REGS+8($sp)
712 * Special system calls. Most of these are special in that they either
713 * have to play switch_stack games or in some way use the pt_regs struct.
721 bsr $1, do_switch_stack
722 bis $31, SIGCHLD, $16
728 bsr $1, undo_switch_stack
738 bsr $1, do_switch_stack
739 /* $16, $17, $18, $19, $20 come from the user. */
741 bsr $1, undo_switch_stack
751 bsr $1, do_switch_stack
753 bsr $1, undo_switch_stack
763 lda $18, -SWITCH_STACK_SIZE($sp)
764 lda $sp, -SWITCH_STACK_SIZE($sp)
765 jsr $26, do_sigreturn
766 br $1, undo_switch_stack
771 .globl sys_rt_sigreturn
772 .ent sys_rt_sigreturn
776 lda $18, -SWITCH_STACK_SIZE($sp)
777 lda $sp, -SWITCH_STACK_SIZE($sp)
778 jsr $26, do_rt_sigreturn
779 br $1, undo_switch_stack
781 .end sys_rt_sigreturn
784 .globl sys_sigsuspend
789 br $1, do_switch_stack
793 jsr $26, do_sigsuspend
795 lda $sp, SWITCH_STACK_SIZE+16($sp)
800 .globl sys_rt_sigsuspend
801 .ent sys_rt_sigsuspend
805 br $1, do_switch_stack
809 jsr $26, do_rt_sigsuspend
811 lda $sp, SWITCH_STACK_SIZE+16($sp)
813 .end sys_rt_sigsuspend
825 .globl osf_getpriority
832 jsr $26, sys_getpriority
837 /* Return value is the unbiased priority, i.e. 20 - prio.
838 This does result in negative return values, so signal
839 no error by writing into the R0 slot. */
856 ldl $1, TASK_EUID($2)
868 ldl $1, TASK_EGID($2)
880 /* See linux/kernel/timer.c sys_getppid for discussion
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)
889 ldq $3, TASK_GROUP_LEADER($2)
890 ldq $4, TASK_REAL_PARENT($3)
912 /* The return values are in $0 and $20. */
927 jmp $31, do_sys_ptrace
936 jmp $31, do_sys_execve
940 .globl osf_sigprocmask
945 jmp $31, do_osf_sigprocmask
949 .globl alpha_ni_syscall
950 .ent alpha_ni_syscall
953 /* Special because it also implements overflow handling via
954 syscall number 0. And if you recall, zero is a special
955 trigger for "not an error". Store large non-zero there. */
960 .end alpha_ni_syscall