2 * arch/alpha/kernel/entry.S
7 #include <asm/asm-offsets.h>
8 #include <asm/thread_info.h>
10 #include <asm/errno.h>
11 #include <asm/unistd.h>
18 #define SWITCH_STACK_SIZE 320
21 * This defines the normal kernel pt-regs layout.
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.
31 subq $sp, SP_OFF, $sp; \
46 ldq $2, HAE_CACHE($2); \
65 ldq $20, HAE_CACHE($19); \
73 ldq $20, HAE_REG($19); \
74 stq $21, HAE_CACHE($19); \
92 * Non-syscall kernel entry points.
101 lda $26, ret_from_sys_call
113 lda $26, ret_from_sys_call
124 /* save $9 - $15 so the inline exception code can manipulate them. */
134 /* handle the fault */
137 jsr $26, do_page_fault
138 /* reload the registers after the exception code played. */
147 /* finish up the syscall as normal. */
157 lda $26, ret_from_sys_call
169 ldq $0, 256($sp) /* get PS */
173 and $0, 8, $0 /* user mode? */
175 bne $0, entUnaUser /* yup -> do user-level unaligned fault */
187 /* 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
590 * New processes begin life here.
597 lda $26, ret_from_sys_call
599 jmp $31, schedule_tail
603 * kernel_thread(fn, arg, clone_flags)
609 /* We can be called from a module. */
612 subq $sp, SP_OFF+6*8, $sp
613 br $1, 2f /* load start address */
615 /* We've now "returned" from a fake system call. */
617 blt $0, 1f /* error? */
619 beq $20, 1f /* parent or child? */
621 bic $sp, $1, $8 /* in child. */
628 1: ret /* in parent. */
631 2: /* Fake a system call stack frame, as we can't do system calls
632 from kernel space. Note that we store FN and ARG as they
633 need to be set up in the child for the call. Also store $8
634 and $26 for use in the parent. */
635 stq $31, SP_OFF($sp) /* ps */
636 stq $1, SP_OFF+8($sp) /* pc */
637 stq $gp, SP_OFF+16($sp) /* gp */
638 stq $16, 136($sp) /* $27; FN for child */
639 stq $17, SP_OFF+24($sp) /* $16; ARG for child */
640 stq $8, 64($sp) /* $8 */
641 stq $26, 128($sp) /* $26 */
642 /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */
643 ldq $2, alpha_mv+HAE_CACHE
644 stq $2, 152($sp) /* HAE */
646 /* Shuffle FLAGS to the front; add CLONE_VM. */
647 ldi $1, CLONE_VM|CLONE_UNTRACED
651 /* We don't actually care for a3 success widgetry in the kernel.
652 Not for positive errno values. */
653 stq $0, 0($sp) /* $0 */
658 * kernel_execve(path, argv, envp)
664 /* We can be called from a module. */
666 lda $sp, -(32+SIZEOF_PT_REGS+8)($sp)
667 .frame $sp, 32+SIZEOF_PT_REGS+8, $26, 0
676 lda $18, SIZEOF_PT_REGS
677 bsr $26, memset !samegp
679 /* Avoid the HAE being gratuitously wrong, which would cause us
680 to do the whole turn off interrupts thing and restore it. */
681 ldq $2, alpha_mv+HAE_CACHE
688 bsr $26, do_execve !samegp
691 bne $0, 1f /* error! */
693 /* Move the temporary pt_regs struct from its current location
694 to the top of the kernel stack frame. See copy_thread for
695 details for a normal process. */
696 lda $16, 0x4000 - SIZEOF_PT_REGS($8)
698 lda $18, SIZEOF_PT_REGS
699 bsr $26, memmove !samegp
701 /* Take that over as our new stack frame and visit userland! */
702 lda $sp, 0x4000 - SIZEOF_PT_REGS($8)
703 br $31, ret_from_sys_call
705 1: lda $sp, 32+SIZEOF_PT_REGS+8($sp)
711 * Special system calls. Most of these are special in that they either
712 * have to play switch_stack games or in some way use the pt_regs struct.
720 bsr $1, do_switch_stack
721 bis $31, SIGCHLD, $16
727 bsr $1, undo_switch_stack
737 bsr $1, do_switch_stack
738 /* $16, $17, $18, $19, $20 come from the user. */
740 bsr $1, undo_switch_stack
750 bsr $1, do_switch_stack
752 bsr $1, undo_switch_stack
762 lda $18, -SWITCH_STACK_SIZE($sp)
763 lda $sp, -SWITCH_STACK_SIZE($sp)
764 jsr $26, do_sigreturn
765 br $1, undo_switch_stack
770 .globl sys_rt_sigreturn
771 .ent sys_rt_sigreturn
775 lda $18, -SWITCH_STACK_SIZE($sp)
776 lda $sp, -SWITCH_STACK_SIZE($sp)
777 jsr $26, do_rt_sigreturn
778 br $1, undo_switch_stack
780 .end sys_rt_sigreturn
783 .globl sys_sigsuspend
788 br $1, do_switch_stack
792 jsr $26, do_sigsuspend
794 lda $sp, SWITCH_STACK_SIZE+16($sp)
799 .globl sys_rt_sigsuspend
800 .ent sys_rt_sigsuspend
804 br $1, do_switch_stack
808 jsr $26, do_rt_sigsuspend
810 lda $sp, SWITCH_STACK_SIZE+16($sp)
812 .end sys_rt_sigsuspend
824 .globl osf_getpriority
831 jsr $26, sys_getpriority
836 /* Return value is the unbiased priority, i.e. 20 - prio.
837 This does result in negative return values, so signal
838 no error by writing into the R0 slot. */
855 ldl $1, TASK_EUID($2)
867 ldl $1, TASK_EGID($2)
879 /* See linux/kernel/timer.c sys_getppid for discussion
881 ldq $3, TASK_GROUP_LEADER($2)
882 ldq $4, TASK_REAL_PARENT($3)
883 ldl $0, TASK_TGID($2)
884 1: ldl $1, TASK_TGID($4)
888 ldq $3, TASK_GROUP_LEADER($2)
889 ldq $4, TASK_REAL_PARENT($3)
911 /* The return values are in $0 and $20. */
926 jmp $31, do_sys_ptrace
935 jmp $31, do_sys_execve
939 .globl osf_sigprocmask
944 jmp $31, do_osf_sigprocmask
948 .globl alpha_ni_syscall
949 .ent alpha_ni_syscall
952 /* Special because it also implements overflow handling via
953 syscall number 0. And if you recall, zero is a special
954 trigger for "not an error". Store large non-zero there. */
959 .end alpha_ni_syscall