⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 entry.s

📁 linux-2.6.15.6
💻 S
📖 第 1 页 / 共 3 页
字号:
	la	%r2,SP_PTREGS(%r15)    # load pt_regs	la	%r3,1	la	%r14,BASED(sysc_return)	br	%r1## a new process exits the kernel with ret_from_fork#        .globl  ret_from_forkret_from_fork:	l	%r13,__LC_SVC_NEW_PSW+4	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct	tm	SP_PSW+1(%r15),0x01	# forking a kernel thread ?	bo	BASED(0f)	st	%r15,SP_R15(%r15)	# store stack pointer for new kthread0:	l       %r1,BASED(.Lschedtail)	basr    %r14,%r1        stosm   __SF_EMPTY(%r15),0x03     # reenable interrupts	b	BASED(sysc_return)## clone, fork, vfork, exec and sigreturn need glue,# because they all expect pt_regs as parameter,# but are called with different parameter.# return-address is set up above#sys_clone_glue:         la      %r2,SP_PTREGS(%r15)    # load pt_regs        l       %r1,BASED(.Lclone)        br      %r1                   # branch to sys_clonesys_fork_glue:          la      %r2,SP_PTREGS(%r15)    # load pt_regs        l       %r1,BASED(.Lfork)        br      %r1                   # branch to sys_forksys_vfork_glue:         la      %r2,SP_PTREGS(%r15)    # load pt_regs        l       %r1,BASED(.Lvfork)        br      %r1                   # branch to sys_vforksys_execve_glue:                la      %r2,SP_PTREGS(%r15)   # load pt_regs        l       %r1,BASED(.Lexecve)	lr      %r12,%r14             # save return address        basr    %r14,%r1              # call sys_execve        ltr     %r2,%r2               # check if execve failed        bnz     0(%r12)               # it did fail -> store result in gpr2        b       4(%r12)               # SKIP ST 2,SP_R2(15) after BASR 14,8                                      # in system_call/sysc_tracesyssys_sigreturn_glue:             la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter        l       %r1,BASED(.Lsigreturn)        br      %r1                   # branch to sys_sigreturnsys_rt_sigreturn_glue:             la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter        l       %r1,BASED(.Lrt_sigreturn)        br      %r1                   # branch to sys_sigreturn## sigsuspend and rt_sigsuspend need pt_regs as an additional# parameter and they have to skip the store of %r2 into the# user register %r2 because the return value was set in # sigsuspend and rt_sigsuspend already and must not be overwritten!#sys_sigsuspend_glue:            lr      %r5,%r4               # move mask back        lr      %r4,%r3               # move history1 parameter        lr      %r3,%r2               # move history0 parameter        la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter        l       %r1,BASED(.Lsigsuspend)	la      %r14,4(%r14)          # skip store of return value        br      %r1                   # branch to sys_sigsuspendsys_rt_sigsuspend_glue:         lr      %r4,%r3               # move sigsetsize parameter        lr      %r3,%r2               # move unewset parameter        la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter        l       %r1,BASED(.Lrt_sigsuspend)	la      %r14,4(%r14)          # skip store of return value        br      %r1                   # branch to sys_rt_sigsuspendsys_sigaltstack_glue:        la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter        l       %r1,BASED(.Lsigaltstack)        br      %r1                   # branch to sys_sigreturn/* * Program check handler routine */        .globl  pgm_check_handlerpgm_check_handler:/* * First we need to check for a special case: * Single stepping an instruction that disables the PER event mask will * cause a PER event AFTER the mask has been set. Example: SVC or LPSW. * For a single stepped SVC the program check handler gets control after * the SVC new PSW has been loaded. But we want to execute the SVC first and * then handle the PER event. Therefore we update the SVC old PSW to point * to the pgm_check_handler and branch to the SVC handler after we checked * if we have to load the kernel stack register. * For every other possible cause for PER event without the PER mask set * we just ignore the PER event (FIXME: is there anything we have to do * for LPSW?). */	STORE_TIMER __LC_SYNC_ENTER_TIMER	SAVE_ALL_BASE __LC_SAVE_AREA        tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception        bnz     BASED(pgm_per)           # got per exception -> special case	SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1	CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA#ifdef CONFIG_VIRT_CPU_ACCOUNTING	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?	bz	BASED(pgm_no_vtime)	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMERpgm_no_vtime:#endif	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct        l       %r3,__LC_PGM_ILC         # load program interruption code	la	%r8,0x7f	nr	%r8,%r3pgm_do_call:        l       %r7,BASED(.Ljump_table)        sll     %r8,2        l       %r7,0(%r8,%r7)		 # load address of handler routine        la      %r2,SP_PTREGS(%r15)	 # address of register-save area	la      %r14,BASED(sysc_return)	br      %r7			 # branch to interrupt-handler## handle per exception#pgm_per:        tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on        bnz     BASED(pgm_per_std)       # ok, normal per event from user space# ok its one of the special cases, now we need to find out which one        clc     __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW        be      BASED(pgm_svcper)# no interesting special case, ignore PER event        lm      %r12,%r15,__LC_SAVE_AREA	lpsw    0x28## Normal per exception#pgm_per_std:	SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1	CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA#ifdef CONFIG_VIRT_CPU_ACCOUNTING	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?	bz	BASED(pgm_no_vtime2)	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMERpgm_no_vtime2:#endif	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct	l	%r1,__TI_task(%r9)	mvc	__THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID	mvc	__THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS	mvc	__THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID	oi	__TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP	l	%r3,__LC_PGM_ILC	 # load program interruption code	la	%r8,0x7f	nr	%r8,%r3                  # clear per-event-bit and ilc	be	BASED(sysc_return)       # only per or per+check ?	b	BASED(pgm_do_call)## it was a single stepped SVC that is causing all the trouble#pgm_svcper:	SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1	CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA#ifdef CONFIG_VIRT_CPU_ACCOUNTING	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?	bz	BASED(pgm_no_vtime3)	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMERpgm_no_vtime3:#endif	lh	%r7,0x8a		# get svc number from lowcore	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct	l	%r1,__TI_task(%r9)	mvc	__THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID	mvc	__THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS	mvc	__THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID	oi	__TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP	stosm	__SF_EMPTY(%r15),0x03	# reenable interrupts	b	BASED(sysc_do_svc)/* * IO interrupt handler routine */        .globl io_int_handlerio_int_handler:	STORE_TIMER __LC_ASYNC_ENTER_TIMER	stck	__LC_INT_CLOCK	SAVE_ALL_BASE __LC_SAVE_AREA+16        SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0	CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16#ifdef CONFIG_VIRT_CPU_ACCOUNTING	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?	bz	BASED(io_no_vtime)	UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMERio_no_vtime:#endif	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct        l       %r1,BASED(.Ldo_IRQ)        # load address of do_IRQ        la      %r2,SP_PTREGS(%r15) # address of register-save area        basr    %r14,%r1          # branch to standard irq handlerio_return:        tm      SP_PSW+1(%r15),0x01    # returning to user ?#ifdef CONFIG_PREEMPT	bno     BASED(io_preempt)      # no -> check for preemptive scheduling#else        bno     BASED(io_leave)        # no-> skip resched & signal#endif	tm	__TI_flags+3(%r9),_TIF_WORK_INT	bnz	BASED(io_work)         # there is work to do (signals etc.)io_leave:        RESTORE_ALL __LC_RETURN_PSW,0io_done:#ifdef CONFIG_PREEMPTio_preempt:	icm	%r0,15,__TI_precount(%r9)	bnz     BASED(io_leave)	l	%r1,SP_R15(%r15)	s	%r1,BASED(.Lc_spsize)	mvc	SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)        xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain	lr	%r15,%r1io_resume_loop:	tm	__TI_flags+3(%r9),_TIF_NEED_RESCHED	bno	BASED(io_leave)	mvc     __TI_precount(4,%r9),BASED(.Lc_pactive)        stosm   __SF_EMPTY(%r15),0x03  # reenable interrupts        l       %r1,BASED(.Lschedule)	basr	%r14,%r1	       # call schedule        stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts	xc      __TI_precount(4,%r9),__TI_precount(%r9)	b	BASED(io_resume_loop)#endif## switch to kernel stack, then check the TIF bits#io_work:	l	%r1,__LC_KERNEL_STACK	s	%r1,BASED(.Lc_spsize)	mvc	SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)        xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain	lr	%r15,%r1## One of the work bits is on. Find out which one.# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING#io_work_loop:	tm	__TI_flags+3(%r9),_TIF_MCCK_PENDING	bo      BASED(io_mcck_pending)	tm	__TI_flags+3(%r9),_TIF_NEED_RESCHED	bo	BASED(io_reschedule)	tm	__TI_flags+3(%r9),_TIF_SIGPENDING	bo	BASED(io_sigpending)	b	BASED(io_leave)## _TIF_MCCK_PENDING is set, call handler#io_mcck_pending:	l	%r1,BASED(.Ls390_handle_mcck)	la	%r14,BASED(io_work_loop)	br	%r1		       # TIF bit will be cleared by handler## _TIF_NEED_RESCHED is set, call schedule#	io_reschedule:                l       %r1,BASED(.Lschedule)        stosm   __SF_EMPTY(%r15),0x03  # reenable interrupts	basr    %r14,%r1	       # call scheduler        stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts	tm	__TI_flags+3(%r9),_TIF_WORK_INT	bz	BASED(io_leave)        # there is no work to do	b	BASED(io_work_loop)## _TIF_SIGPENDING is set, call do_signal#io_sigpending:             stosm   __SF_EMPTY(%r15),0x03  # reenable interrupts        la      %r2,SP_PTREGS(%r15)    # load pt_regs        sr      %r3,%r3                # clear *oldset        l       %r1,BASED(.Ldo_signal)	basr    %r14,%r1	       # call do_signal        stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts	b	BASED(io_work_loop)/* * External interrupt handler routine */        .globl  ext_int_handlerext_int_handler:	STORE_TIMER __LC_ASYNC_ENTER_TIMER	stck	__LC_INT_CLOCK	SAVE_ALL_BASE __LC_SAVE_AREA+16        SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0	CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16#ifdef CONFIG_VIRT_CPU_ACCOUNTING	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?	bz	BASED(ext_no_vtime)	UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMERext_no_vtime:#endif	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct	la	%r2,SP_PTREGS(%r15)    # address of register-save area	lh	%r3,__LC_EXT_INT_CODE  # get interruption code	l	%r1,BASED(.Ldo_extint)	basr	%r14,%r1	b	BASED(io_return)__critical_end:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -