📄 entry.s
字号:
stq $11, 16($sp) stq $12, 24($sp) stq $13, 32($sp) stq $14, 40($sp) stq $15, 48($sp) stq $26, 56($sp) stt $f0, 64($sp) stt $f1, 72($sp) stt $f2, 80($sp) stt $f3, 88($sp) stt $f4, 96($sp) stt $f5, 104($sp) stt $f6, 112($sp) stt $f7, 120($sp) stt $f8, 128($sp) stt $f9, 136($sp) stt $f10, 144($sp) stt $f11, 152($sp) stt $f12, 160($sp) stt $f13, 168($sp) stt $f14, 176($sp) stt $f15, 184($sp) stt $f16, 192($sp) stt $f17, 200($sp) stt $f18, 208($sp) stt $f19, 216($sp) stt $f20, 224($sp) stt $f21, 232($sp) stt $f22, 240($sp) stt $f23, 248($sp) stt $f24, 256($sp) stt $f25, 264($sp) stt $f26, 272($sp) stt $f27, 280($sp) mf_fpcr $f0 # get fpcr stt $f28, 288($sp) stt $f29, 296($sp) stt $f30, 304($sp) stt $f0, 312($sp) # save fpcr in slot of $f31 ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state. ret $31, ($1), 1.end do_switch_stack .align 4 .ent undo_switch_stackundo_switch_stack: ldq $9, 0($sp) ldq $10, 8($sp) ldq $11, 16($sp) ldq $12, 24($sp) ldq $13, 32($sp) ldq $14, 40($sp) ldq $15, 48($sp) ldq $26, 56($sp) ldt $f30, 312($sp) # get saved fpcr ldt $f0, 64($sp) ldt $f1, 72($sp) ldt $f2, 80($sp) ldt $f3, 88($sp) mt_fpcr $f30 # install saved fpcr ldt $f4, 96($sp) ldt $f5, 104($sp) ldt $f6, 112($sp) ldt $f7, 120($sp) ldt $f8, 128($sp) ldt $f9, 136($sp) ldt $f10, 144($sp) ldt $f11, 152($sp) ldt $f12, 160($sp) ldt $f13, 168($sp) ldt $f14, 176($sp) ldt $f15, 184($sp) ldt $f16, 192($sp) ldt $f17, 200($sp) ldt $f18, 208($sp) ldt $f19, 216($sp) ldt $f20, 224($sp) ldt $f21, 232($sp) ldt $f22, 240($sp) ldt $f23, 248($sp) ldt $f24, 256($sp) ldt $f25, 264($sp) ldt $f26, 272($sp) ldt $f27, 280($sp) ldt $f28, 288($sp) ldt $f29, 296($sp) ldt $f30, 304($sp) lda $sp, SWITCH_STACK_SIZE($sp) ret $31, ($1), 1.end undo_switch_stack/* * The meat of the context switch code. */ .align 4 .globl alpha_switch_to .ent alpha_switch_toalpha_switch_to: .prologue 0 bsr $1, do_switch_stack call_pal PAL_swpctx lda $8, 0x3fff bsr $1, undo_switch_stack bic $sp, $8, $8 mov $17, $0 ret.end alpha_switch_to/* * New processes begin life here. */ .globl ret_from_fork .align 4 .ent ret_from_forkret_from_fork: lda $26, ret_from_sys_call mov $17, $16 jmp $31, schedule_tail.end ret_from_fork/* * kernel_thread(fn, arg, clone_flags) */ .align 4 .globl kernel_thread .ent kernel_threadkernel_thread: /* We can be called from a module. */ ldgp $gp, 0($27) .prologue 1 subq $sp, SP_OFF+6*8, $sp br $1, 2f /* load start address */ /* We've now "returned" from a fake system call. */ unop blt $0, 1f /* error? */ ldi $1, 0x3fff beq $20, 1f /* parent or child? */ bic $sp, $1, $8 /* in child. */ jsr $26, ($27) ldgp $gp, 0($26) mov $0, $16 mov $31, $26 jmp $31, sys_exit1: ret /* in parent. */ .align 42: /* Fake a system call stack frame, as we can't do system calls from kernel space. Note that we store FN and ARG as they need to be set up in the child for the call. Also store $8 and $26 for use in the parent. */ stq $31, SP_OFF($sp) /* ps */ stq $1, SP_OFF+8($sp) /* pc */ stq $gp, SP_OFF+16($sp) /* gp */ stq $16, 136($sp) /* $27; FN for child */ stq $17, SP_OFF+24($sp) /* $16; ARG for child */ stq $8, 64($sp) /* $8 */ stq $26, 128($sp) /* $26 */ /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */ ldq $2, alpha_mv+HAE_CACHE stq $2, 152($sp) /* HAE */ /* Shuffle FLAGS to the front; add CLONE_VM. */ ldi $1, CLONE_VM|CLONE_UNTRACED or $18, $1, $16 bsr $26, sys_clone /* We don't actually care for a3 success widgetry in the kernel. Not for positive errno values. */ stq $0, 0($sp) /* $0 */ br restore_all.end kernel_thread/* * execve(path, argv, envp) */ .align 4 .globl execve .ent execveexecve: /* We can be called from a module. */ ldgp $gp, 0($27) lda $sp, -(32+SIZEOF_PT_REGS+8)($sp) .frame $sp, 32+SIZEOF_PT_REGS+8, $26, 0 stq $26, 0($sp) stq $16, 8($sp) stq $17, 16($sp) stq $18, 24($sp) .prologue 1 lda $16, 32($sp) lda $17, 0 lda $18, SIZEOF_PT_REGS bsr $26, memset !samegp /* Avoid the HAE being gratuitously wrong, which would cause us to do the whole turn off interrupts thing and restore it. */ ldq $2, alpha_mv+HAE_CACHE stq $2, 152+32($sp) ldq $16, 8($sp) ldq $17, 16($sp) ldq $18, 24($sp) lda $19, 32($sp) bsr $26, do_execve !samegp ldq $26, 0($sp) bne $0, 1f /* error! */ /* Move the temporary pt_regs struct from its current location to the top of the kernel stack frame. See copy_thread for details for a normal process. */ lda $16, 0x4000 - SIZEOF_PT_REGS($8) lda $17, 32($sp) lda $18, SIZEOF_PT_REGS bsr $26, memmove !samegp /* Take that over as our new stack frame and visit userland! */ lda $sp, 0x4000 - SIZEOF_PT_REGS($8) br $31, ret_from_sys_call1: lda $sp, 32+SIZEOF_PT_REGS+8($sp) ret.end execve/* * Special system calls. Most of these are special in that they either * have to play switch_stack games or in some way use the pt_regs struct. */ .align 4 .globl sys_fork .ent sys_forksys_fork: .prologue 0 mov $sp, $21 bsr $1, do_switch_stack bis $31, SIGCHLD, $16 mov $31, $17 mov $31, $18 mov $31, $19 mov $31, $20 jsr $26, alpha_clone bsr $1, undo_switch_stack ret.end sys_fork .align 4 .globl sys_clone .ent sys_clonesys_clone: .prologue 0 mov $sp, $21 bsr $1, do_switch_stack /* $16, $17, $18, $19, $20 come from the user. */ jsr $26, alpha_clone bsr $1, undo_switch_stack ret.end sys_clone .align 4 .globl sys_vfork .ent sys_vforksys_vfork: .prologue 0 mov $sp, $16 bsr $1, do_switch_stack jsr $26, alpha_vfork bsr $1, undo_switch_stack ret.end sys_vfork .align 4 .globl sys_sigreturn .ent sys_sigreturnsys_sigreturn: .prologue 0 mov $sp, $17 lda $18, -SWITCH_STACK_SIZE($sp) lda $sp, -SWITCH_STACK_SIZE($sp) jsr $26, do_sigreturn br $1, undo_switch_stack br ret_from_sys_call.end sys_sigreturn .align 4 .globl sys_rt_sigreturn .ent sys_rt_sigreturnsys_rt_sigreturn: .prologue 0 mov $sp, $17 lda $18, -SWITCH_STACK_SIZE($sp) lda $sp, -SWITCH_STACK_SIZE($sp) jsr $26, do_rt_sigreturn br $1, undo_switch_stack br ret_from_sys_call.end sys_rt_sigreturn .align 4 .globl sys_sigsuspend .ent sys_sigsuspendsys_sigsuspend: .prologue 0 mov $sp, $17 br $1, do_switch_stack mov $sp, $18 subq $sp, 16, $sp stq $26, 0($sp) jsr $26, do_sigsuspend ldq $26, 0($sp) lda $sp, SWITCH_STACK_SIZE+16($sp) ret.end sys_sigsuspend .align 4 .globl sys_rt_sigsuspend .ent sys_rt_sigsuspendsys_rt_sigsuspend: .prologue 0 mov $sp, $18 br $1, do_switch_stack mov $sp, $19 subq $sp, 16, $sp stq $26, 0($sp) jsr $26, do_rt_sigsuspend ldq $26, 0($sp) lda $sp, SWITCH_STACK_SIZE+16($sp) ret.end sys_rt_sigsuspend .align 4 .globl sys_sethae .ent sys_sethaesys_sethae: .prologue 0 stq $16, 152($sp) ret.end sys_sethae .align 4 .globl osf_getpriority .ent osf_getpriorityosf_getpriority: lda $sp, -16($sp) stq $26, 0($sp) .prologue 0 jsr $26, sys_getpriority ldq $26, 0($sp) blt $0, 1f /* Return value is the unbiased priority, i.e. 20 - prio. This does result in negative return values, so signal no error by writing into the R0 slot. */ lda $1, 20 stq $31, 16($sp) subl $1, $0, $0 unop1: lda $sp, 16($sp) ret.end osf_getpriority .align 4 .globl sys_getxuid .ent sys_getxuidsys_getxuid: .prologue 0 ldq $2, TI_TASK($8) ldl $0, TASK_UID($2) ldl $1, TASK_EUID($2) stq $1, 80($sp) ret.end sys_getxuid .align 4 .globl sys_getxgid .ent sys_getxgidsys_getxgid: .prologue 0 ldq $2, TI_TASK($8) ldl $0, TASK_GID($2) ldl $1, TASK_EGID($2) stq $1, 80($sp) ret.end sys_getxgid .align 4 .globl sys_getxpid .ent sys_getxpidsys_getxpid: .prologue 0 ldq $2, TI_TASK($8) /* See linux/kernel/timer.c sys_getppid for discussion about this loop. */ ldq $3, TASK_REAL_PARENT($2)1: ldl $1, TASK_TGID($3)#ifdef CONFIG_SMP mov $3, $4 mb ldq $3, TASK_REAL_PARENT($2) cmpeq $3, $4, $4 beq $4, 1b#endif stq $1, 80($sp) ldl $0, TASK_TGID($2) ret.end sys_getxpid .align 4 .globl sys_pipe .ent sys_pipesys_pipe: lda $sp, -16($sp) stq $26, 0($sp) .prologue 0 lda $16, 8($sp) jsr $26, do_pipe ldq $26, 0($sp) bne $0, 1f /* The return values are in $0 and $20. */ ldl $1, 12($sp) ldl $0, 8($sp) stq $1, 80+16($sp)1: lda $sp, 16($sp) ret.end sys_pipe .align 4 .globl sys_ptrace .ent sys_ptracesys_ptrace: .prologue 0 mov $sp, $20 jmp $31, do_sys_ptrace.end sys_ptrace .align 4 .globl sys_execve .ent sys_execvesys_execve: .prologue 0 mov $sp, $19 jmp $31, do_sys_execve.end sys_execve .align 4 .globl osf_sigprocmask .ent osf_sigprocmaskosf_sigprocmask: .prologue 0 mov $sp, $18 jmp $31, do_osf_sigprocmask.end osf_sigprocmask .align 4 .globl alpha_ni_syscall .ent alpha_ni_syscallalpha_ni_syscall: .prologue 0 /* Special because it also implements overflow handling via syscall number 0. And if you recall, zero is a special trigger for "not an error". Store large non-zero there. */ lda $0, -ENOSYS unop stq $0, 0($sp) ret.end alpha_ni_syscall
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -