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

📄 entry.s

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 S
📖 第 1 页 / 共 3 页
字号:
	;;			// WAW on CFM at the br.call	mov loc0=rp	br.call.sptk.many rp=save_switch_stack_with_current_frame	// must preserve b6!!.ret4:	mov loc2=b6	br.call.sptk.few rp=syscall_trace.ret5:	adds sp=IA64_SWITCH_STACK_SIZE,sp	// drop switch_stack frame	mov rp=loc0	mov ar.pfs=loc1	mov b6=loc2	;;	br.ret.sptk.few rp#endif /* !CONFIG_IA64_NEW_SYSCALL */END(invoke_syscall_trace)	//	// Invoke a system call, but do some tracing before and after the call.	// We MUST preserve the current register frame throughout this routine	// because some system calls (such as ia64_execve) directly	// manipulate ar.pfs.	//	// Input:	//	r15 = syscall number	//	b6  = syscall entry point	//	.global ia64_strace_leave_kernelGLOBAL_ENTRY(ia64_trace_syscall)	PT_REGS_UNWIND_INFO(0)	br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall args.ret6:	br.call.sptk.few rp=b6			// do the syscallstrace_check_retval:	cmp.lt p6,p0=r8,r0			// syscall failed?	adds r2=IA64_PT_REGS_R8_OFFSET+16,sp	// r2 = &pt_regs.r8	adds r3=IA64_PT_REGS_R8_OFFSET+32,sp	// r3 = &pt_regs.r10	mov r10=0(p6)	br.cond.sptk.few strace_error		// syscall failed ->	;;					// avoid RAW on r10strace_save_retval:.mem.offset 0,0;	st8.spill [r2]=r8	// store return value in slot for r8.mem.offset 8,0;	st8.spill [r3]=r10	// clear error indication in slot for r10ia64_strace_leave_kernel:	br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch return value.rety:	br.cond.sptk.many ia64_leave_kernelstrace_error:	ld8 r3=[r2]				// load pt_regs.r8	sub r9=0,r8				// negate return value to get errno value	;;	cmp.ne p6,p0=r3,r0			// is pt_regs.r8!=0?	adds r3=16,r2				// r3=&pt_regs.r10	;;(p6)	mov r10=-1(p6)	mov r8=r9	br.cond.sptk.few strace_save_retvalEND(ia64_trace_syscall)/* * A couple of convenience macros to help implement/understand the state * restoration that happens at the end of ia64_ret_from_syscall. */#define rARPR		r31#define rCRIFS		r30#define rCRIPSR		r29#define rCRIIP		r28#define rARRSC		r27#define rARPFS		r26#define rARUNAT		r25#define rARRNAT		r24#define rARBSPSTORE	r23#define rKRBS		r22#define rB6		r21GLOBAL_ENTRY(ia64_ret_from_clone)	PT_REGS_UNWIND_INFO(0)#ifdef CONFIG_SMP	// In SMP mode, we need to call schedule_tail to complete the scheduling process.	// Called by ia64_switch_to after do_fork()->copy_thread().  r8 contains the	// address of the previously executing task.	br.call.sptk.few rp=invoke_schedule_tail.ret8:#endif	adds r2=IA64_TASK_PTRACE_OFFSET,r13	;;	ld8 r2=[r2]	;;	mov r8=0	tbit.nz p6,p0=r2,PT_TRACESYS_BIT(p6)	br strace_check_retval	;;					// added stop bits to prevent r8 dependencyEND(ia64_ret_from_clone)	// fall throughGLOBAL_ENTRY(ia64_ret_from_syscall)	PT_REGS_UNWIND_INFO(0)	cmp.ge p6,p7=r8,r0			// syscall executed successfully?	adds r2=IA64_PT_REGS_R8_OFFSET+16,sp	// r2 = &pt_regs.r8	adds r3=IA64_PT_REGS_R8_OFFSET+32,sp	// r3 = &pt_regs.r10	;;	.mem.offset 0,0(p6)	st8.spill [r2]=r8	// store return value in slot for r8 and set unat bit	.mem.offset 8,0(p6)	st8.spill [r3]=r0	// clear error indication in slot for r10 and set unat bit(p7)	br.cond.spnt.few handle_syscall_error	// handle potential syscall failureEND(ia64_ret_from_syscall)	// fall throughGLOBAL_ENTRY(ia64_leave_kernel)	// check & deliver software interrupts:	PT_REGS_UNWIND_INFO(0)#ifdef CONFIG_SMP	adds r2=IA64_TASK_PROCESSOR_OFFSET,r13	movl r3=irq_stat		// softirq_active	;;	ld4 r2=[r2]	;;	shl r2=r2,SMP_CACHE_SHIFT	// can't use shladd here...	;;	add r3=r2,r3#else	movl r3=irq_stat		// softirq_active#endif	;;	ld8 r2=[r3]		// r3 (softirq_active+softirq_mask) is guaranteed to be 8-byte aligned!	;;	shr r3=r2,32	;;	and r2=r2,r3	;;	cmp4.ne p6,p7=r2,r0(p6)	br.call.spnt.many rp=invoke_do_softirq1:(pKern)	br.cond.dpnt.many restore_all	// yup -> skip check for rescheduling & signal delivery	// call schedule() until we find a task that doesn't have need_resched set:back_from_resched:	{ .mii	  adds r2=IA64_TASK_NEED_RESCHED_OFFSET,r13	  mov r3=ip	  adds r14=IA64_TASK_SIGPENDING_OFFSET,r13	}	;;	ld8 r2=[r2]	ld4 r14=[r14]	mov rp=r3			// arrange for schedule() to return to back_from_resched	;;	cmp.ne p6,p0=r2,r0	cmp.ne p2,p0=r14,r0		// NOTE: pKern is an alias for p2!!	srlz.d(p6)	br.call.spnt.many b6=invoke_schedule	// ignore return value2:	// check & deliver pending signals:(p2)	br.call.spnt.few rp=handle_signal_delivery.ret9:#ifdef CONFIG_IA64_SOFTSDV_HACKS	// Check for lost ticks	rsm psr.i	mov r2 = ar.itc	movl r14 = 1000			// latency tolerance	mov r3 = cr.itm	;;	sub r2 = r2, r3	;;	sub r2 = r2, r14	;;	cmp.ge p6,p7 = r2, r0(p6)	br.call.spnt.few rp=invoke_ia64_reset_itm.ret10:	;;	ssm psr.i#endif restore_all:	// start restoring the state saved on the kernel stack (struct pt_regs):	adds r2=IA64_PT_REGS_R8_OFFSET+16,r12	adds r3=IA64_PT_REGS_R8_OFFSET+24,r12	;;	ld8.fill r8=[r2],16	ld8.fill r9=[r3],16	;;	ld8.fill r10=[r2],16	ld8.fill r11=[r3],16	;;	ld8.fill r16=[r2],16	ld8.fill r17=[r3],16	;;	ld8.fill r18=[r2],16	ld8.fill r19=[r3],16	;;	ld8.fill r20=[r2],16	ld8.fill r21=[r3],16	;;	ld8.fill r22=[r2],16	ld8.fill r23=[r3],16	;;	ld8.fill r24=[r2],16	ld8.fill r25=[r3],16	;;	ld8.fill r26=[r2],16	ld8.fill r27=[r3],16	;;	ld8.fill r28=[r2],16	ld8.fill r29=[r3],16	;;	ld8.fill r30=[r2],16	ld8.fill r31=[r3],16	;;	ld8 r1=[r2],16		// ar.ccv	ld8 r13=[r3],16		// ar.fpsr	;;	ld8 r14=[r2],16		// b0	ld8 r15=[r3],16+8	// b7	;;	ldf.fill f6=[r2],32	ldf.fill f7=[r3],32	;;	ldf.fill f8=[r2],32	ldf.fill f9=[r3],32	;;	mov ar.ccv=r1	mov ar.fpsr=r13	mov b0=r14	// turn off interrupts, interrupt collection	rsm psr.i | psr.ic	;;	srlz.i			// EAS 2.5	mov b7=r15	;;	invala			// invalidate ALAT	bsw.0;;			// switch back to bank 0 (must be last in insn group)	;;#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC	nop.i 0x0	;;	nop.i 0x0	;;	nop.i 0x0	;;#endif	adds r16=16,r12	adds r17=24,r12	;;	ld8 rCRIPSR=[r16],16	// load cr.ipsr	ld8 rCRIIP=[r17],16	// load cr.iip	;;	ld8 rCRIFS=[r16],16	// load cr.ifs	ld8 rARUNAT=[r17],16	// load ar.unat	;;	ld8 rARPFS=[r16],16	// load ar.pfs	ld8 rARRSC=[r17],16	// load ar.rsc	;;	ld8 rARRNAT=[r16],16	// load ar.rnat (may be garbage)	ld8 rARBSPSTORE=[r17],16	// load ar.bspstore (may be garbage)	;;	ld8 rARPR=[r16],16	// load predicates	ld8 rB6=[r17],16	// load b6	;;	ld8 r18=[r16],16	// load ar.rsc value for "loadrs"	ld8.fill r1=[r17],16	// load r1	;;	ld8.fill r2=[r16],16	ld8.fill r3=[r17],16	;;	ld8.fill r12=[r16],16	ld8.fill r13=[r17],16	extr.u r19=rCRIPSR,32,2	// extract ps.cpl	;;	ld8.fill r14=[r16],16	ld8.fill r15=[r17],16	cmp.eq p6,p7=r0,r19	// are we returning to kernel mode? (psr.cpl==0)	;;	mov b6=rB6	mov ar.pfs=rARPFS(p6)	br.cond.dpnt.few skip_rbs_switch	/*	 * Restore user backing store.	 *	 * NOTE: alloc, loadrs, and cover can't be predicated.	 *	 * XXX This needs some scheduling/tuning once we believe it	 *     really does work as intended.	 */	mov r16=ar.bsp			// get existing backing store pointer(pNonSys) br.cond.dpnt.few dont_preserve_current_frame	cover				// add current frame into dirty partition	;;	mov rCRIFS=cr.ifs		// fetch the cr.ifs value that "cover" produced	mov r17=ar.bsp			// get new backing store pointer	;;	sub r16=r17,r16			// calculate number of bytes that were added to rbs	;;	shl r16=r16,16			// shift additional frame size into position for loadrs	;;	add r18=r16,r18			// adjust the loadrs value	;;dont_preserve_current_frame:	alloc r16=ar.pfs,0,0,0,0	// drop the current call frame (noop for syscalls)	;;	mov ar.rsc=r18			// load ar.rsc to be used for "loadrs"#ifdef CONFIG_IA32_SUPPORT	tbit.nz p6,p0=rCRIPSR,IA64_PSR_IS_BIT	;;(p6)	mov ar.rsc=r0                   // returning to IA32 mode#endif 	;;	loadrs	;;	mov ar.bspstore=rARBSPSTORE	;;	mov ar.rnat=rARRNAT	// must happen with RSE in lazy modeskip_rbs_switch:	mov ar.rsc=rARRSC	mov ar.unat=rARUNAT	mov cr.ifs=rCRIFS	// restore cr.ifs only if not a (synchronous) syscall	mov pr=rARPR,-1	mov cr.iip=rCRIIP	mov cr.ipsr=rCRIPSR	;;	rfi;;			// must be last instruction in an insn groupEND(ia64_leave_kernel)ENTRY(handle_syscall_error)	/*	 * Some system calls (e.g., ptrace, mmap) can return arbitrary	 * values which could lead us to mistake a negative return	 * value as a failed syscall.  Those syscall must deposit	 * a non-zero value in pt_regs.r8 to indicate an error.	 * If pt_regs.r8 is zero, we assume that the call completed	 * successfully.	 */	PT_REGS_UNWIND_INFO(0)	ld8 r3=[r2]		// load pt_regs.r8	sub r9=0,r8		// negate return value to get errno	;;	mov r10=-1		// return -1 in pt_regs.r10 to indicate error	cmp.eq p6,p7=r3,r0	// is pt_regs.r8==0?	adds r3=16,r2		// r3=&pt_regs.r10	;;(p6)	mov r9=r8(p6)	mov r10=0	;;.mem.offset 0,0; st8.spill [r2]=r9	// store errno in pt_regs.r8 and set unat bit.mem.offset 8,0; st8.spill [r3]=r10	// store error indication in pt_regs.r10 and set unat bit	br.cond.sptk.many ia64_leave_kernelEND(handle_syscall_error)#ifdef CONFIG_SMP	/*	 * Invoke schedule_tail(task) while preserving in0-in7, which may be needed	 * in case a system call gets restarted.	 */ENTRY(invoke_schedule_tail)	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))	alloc loc1=ar.pfs,8,2,1,0	mov loc0=rp	mov out0=r8				// Address of previous task	;;	br.call.sptk.few rp=schedule_tail.ret11:	mov ar.pfs=loc1	mov rp=loc0	br.ret.sptk.many rpEND(invoke_schedule_tail)#endif /* CONFIG_SMP */#ifdef CONFIG_IA64_SOFTSDV_HACKSENTRY(invoke_ia64_reset_itm)	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))	alloc loc1=ar.pfs,8,2,0,0	mov loc0=rp	;;	UNW(.body)	br.call.sptk.many rp=ia64_reset_itm.ret12:	;;	mov ar.pfs=loc1	mov rp=loc0	br.ret.sptk.many rpEND(invoke_ia64_reset_itm)#endif /* CONFIG_IA64_SOFTSDV_HACKS */	/*	 * Invoke do_softirq() while preserving in0-in7, which may be needed	 * in case a system call gets restarted.	 */ENTRY(invoke_do_softirq)	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))	alloc loc1=ar.pfs,8,2,0,0	mov loc0=rp	;;	UNW(.body)	br.call.sptk.few rp=do_softirq.ret13:	mov ar.pfs=loc1	mov rp=loc0	br.ret.sptk.many rpEND(invoke_do_softirq)	/*	 * Invoke schedule() while preserving in0-in7, which may be needed	 * in case a system call gets restarted.	 */ENTRY(invoke_schedule)	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))	alloc loc1=ar.pfs,8,2,0,0	mov loc0=rp	;;	UNW(.body)	br.call.sptk.few rp=schedule.ret14:	mov ar.pfs=loc1	mov rp=loc0	br.ret.sptk.many rpEND(invoke_schedule)	//	// Setup stack and call ia64_do_signal.  Note that pSys and pNonSys need to	// be set up by the caller.  We declare 8 input registers so the system call	// args get preserved, in case we need to restart a system call.	//ENTRY(handle_signal_delivery)#ifdef CONFIG_IA64_NEW_UNWIND	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)	alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!	mov r9=ar.unat	mov loc0=rp				// save return address	mov out0=0				// there is no "oldset"	adds out1=0,sp				// out1=&sigscratch(pSys)	mov out2=1				// out2==1 => we're in a syscall	;;(pNonSys) mov out2=0				// out2==0 => not a syscall	.fframe 16	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)	st8 [sp]=r9,-16				// allocate space for ar.unat and save it	.body	br.call.sptk.few rp=ia64_do_signal.ret15:	.restore sp

⌨️ 快捷键说明

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