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

📄 entry.s

📁 底层驱动开发
💻 S
📖 第 1 页 / 共 4 页
字号:
	reg_restore %r1	/* strace expects syscall # to be preserved in r20 */	ldi	__NR_fork,%r20	bv %r0(%r2)	STREG	%r20,PT_GR20(%r1)	/* Set the return value for the child */child_return:	BL	schedule_tail, %r2	nop	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1	LDREG	TASK_PT_GR19(%r1),%r2	b	wrapper_exit	copy	%r0,%r28		.export sys_clone_wrappersys_clone_wrapper:	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1	ldo	TASK_REGS(%r1),%r1	/* get pt regs */	reg_save %r1	mfctl	%cr27, %r3	STREG	%r3, PT_CR27(%r1)	STREG	%r2,-RP_OFFSET(%r30)	ldo	FRAME_SIZE(%r30),%r30#ifdef __LP64__	ldo	-16(%r30),%r29		/* Reference param save area */#endif	STREG	%r2,PT_GR19(%r1)	/* save for child */	STREG	%r30,PT_GR21(%r1)	BL	sys_clone,%r2	copy	%r1,%r24	b	wrapper_exit	LDREG	-RP_OFFSET-FRAME_SIZE(%r30),%r2	.export sys_vfork_wrappersys_vfork_wrapper:	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1	ldo	TASK_REGS(%r1),%r1	/* get pt regs */	reg_save %r1	mfctl	%cr27, %r3	STREG	%r3, PT_CR27(%r1)	STREG	%r2,-RP_OFFSET(%r30)	ldo	FRAME_SIZE(%r30),%r30#ifdef __LP64__	ldo	-16(%r30),%r29		/* Reference param save area */#endif	STREG	%r2,PT_GR19(%r1)	/* save for child */	STREG	%r30,PT_GR21(%r1)	BL	sys_vfork,%r2	copy	%r1,%r26	b	wrapper_exit	LDREG	-RP_OFFSET-FRAME_SIZE(%r30),%r2		.macro  execve_wrapper execve	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1	ldo	TASK_REGS(%r1),%r1	/* get pt regs */	/*	 * Do we need to save/restore r3-r18 here?	 * I don't think so. why would new thread need old	 * threads registers?	 */	/* %arg0 - %arg3 are already saved for us. */	STREG %r2,-RP_OFFSET(%r30)	ldo FRAME_SIZE(%r30),%r30#ifdef __LP64__	ldo	-16(%r30),%r29		/* Reference param save area */#endif	bl \execve,%r2	copy %r1,%arg0	ldo -FRAME_SIZE(%r30),%r30	LDREG -RP_OFFSET(%r30),%r2	/* If exec succeeded we need to load the args */	ldo -1024(%r0),%r1	cmpb,>>= %r28,%r1,error_\execve	copy %r2,%r19error_\execve:	bv %r0(%r19)	nop	.endm	.export sys_execve_wrapper	.import sys_execvesys_execve_wrapper:	execve_wrapper sys_execve#ifdef __LP64__	.export sys32_execve_wrapper	.import sys32_execvesys32_execve_wrapper:	execve_wrapper sys32_execve#endif	.export sys_rt_sigreturn_wrappersys_rt_sigreturn_wrapper:	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26	ldo	TASK_REGS(%r26),%r26	/* get pt regs */	/* Don't save regs, we are going to restore them from sigcontext. */	STREG	%r2, -RP_OFFSET(%r30)#ifdef __LP64__	ldo	FRAME_SIZE(%r30), %r30	BL	sys_rt_sigreturn,%r2	ldo	-16(%r30),%r29		/* Reference param save area */#else	BL	sys_rt_sigreturn,%r2	ldo	FRAME_SIZE(%r30), %r30#endif	ldo	-FRAME_SIZE(%r30), %r30	LDREG	-RP_OFFSET(%r30), %r2	/* FIXME: I think we need to restore a few more things here. */	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1	ldo	TASK_REGS(%r1),%r1	/* get pt regs */	reg_restore %r1	/* If the signal was received while the process was blocked on a	 * syscall, then r2 will take us to syscall_exit; otherwise r2 will	 * take us to syscall_exit_rfi and on to intr_return.	 */	bv	%r0(%r2)	LDREG	PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */	.export sys_sigaltstack_wrappersys_sigaltstack_wrapper:	/* Get the user stack pointer */	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1	ldo	TASK_REGS(%r1),%r24	/* get pt regs */	LDREG	TASK_PT_GR30(%r24),%r24	STREG	%r2, -RP_OFFSET(%r30)#ifdef __LP64__	ldo	FRAME_SIZE(%r30), %r30	b,l	do_sigaltstack,%r2	ldo	-16(%r30),%r29		/* Reference param save area */#else	bl	do_sigaltstack,%r2	ldo	FRAME_SIZE(%r30), %r30#endif	ldo	-FRAME_SIZE(%r30), %r30	LDREG	-RP_OFFSET(%r30), %r2	bv	%r0(%r2)	nop#ifdef __LP64__	.export sys32_sigaltstack_wrappersys32_sigaltstack_wrapper:	/* Get the user stack pointer */	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24	LDREG	TASK_PT_GR30(%r24),%r24	STREG	%r2, -RP_OFFSET(%r30)	ldo	FRAME_SIZE(%r30), %r30	b,l	do_sigaltstack32,%r2	ldo	-16(%r30),%r29		/* Reference param save area */	ldo	-FRAME_SIZE(%r30), %r30	LDREG	-RP_OFFSET(%r30), %r2	bv	%r0(%r2)	nop#endif	.export sys_rt_sigsuspend_wrappersys_rt_sigsuspend_wrapper:	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1	ldo	TASK_REGS(%r1),%r24	reg_save %r24	STREG	%r2, -RP_OFFSET(%r30)#ifdef __LP64__	ldo	FRAME_SIZE(%r30), %r30	b,l	sys_rt_sigsuspend,%r2	ldo	-16(%r30),%r29		/* Reference param save area */#else	bl	sys_rt_sigsuspend,%r2	ldo	FRAME_SIZE(%r30), %r30#endif	ldo	-FRAME_SIZE(%r30), %r30	LDREG	-RP_OFFSET(%r30), %r2	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1	ldo	TASK_REGS(%r1),%r1	reg_restore %r1	bv	%r0(%r2)	nop	.export syscall_exitsyscall_exit:	/* NOTE: HP-UX syscalls also come through here	 * after hpux_syscall_exit fixes up return	 * values. */	/* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit	 * via syscall_exit_rfi if the signal was received while the process	 * was running.	 */	/* save return value now */	mfctl     %cr30, %r1	LDREG     TI_TASK(%r1),%r1	STREG     %r28,TASK_PT_GR28(%r1)#ifdef CONFIG_HPUX/* <linux/personality.h> cannot be easily included */#define PER_HPUX 0x10	LDREG     TASK_PERSONALITY(%r1),%r19	/* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */	ldo	  -PER_HPUX(%r19), %r19	CMPIB<>,n 0,%r19,1f	/* Save other hpux returns if personality is PER_HPUX */	STREG     %r22,TASK_PT_GR22(%r1)	STREG     %r29,TASK_PT_GR29(%r1)1:#endif /* CONFIG_HPUX */	/* Seems to me that dp could be wrong here, if the syscall involved	 * calling a module, and nothing got round to restoring dp on return.	 */	loadgpsyscall_check_bh:	/* Check for software interrupts */	.import irq_stat,data	load32	irq_stat,%r19#ifdef CONFIG_SMP	/* sched.h: int processor */	/* %r26 is used as scratch register to index into irq_stat[] */	ldw     TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */	/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */#ifdef __LP64__	shld	%r26, 6, %r20#else	shlw	%r26, 5, %r20#endif	add     %r19,%r20,%r19	/* now have &irq_stat[smp_processor_id()] */#endif /* CONFIG_SMP */	LDREG   IRQSTAT_SIRQ_PEND(%r19),%r20    /* hardirq.h: unsigned long */	cmpib,<>,n 0,%r20,syscall_do_softirq /* forward */syscall_check_resched:	/* check for reschedule */	LDREG	TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19	/* long */	bb,<,n	%r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */syscall_check_sig:	LDREG	TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19    /* get ti flags */	bb,<,n	%r19, 31-TIF_SIGPENDING, syscall_do_signal /* forward */syscall_restore:	/* Are we being ptraced? */	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1	LDREG	TASK_PTRACE(%r1), %r19	bb,<	%r19,31,syscall_restore_rfi	nop	ldo	TASK_PT_FR31(%r1),%r19		   /* reload fpregs */	rest_fp	%r19	LDREG	TASK_PT_SAR(%r1),%r19		   /* restore SAR */	mtsar	%r19	LDREG	TASK_PT_GR2(%r1),%r2		   /* restore user rp */	LDREG	TASK_PT_GR19(%r1),%r19	LDREG   TASK_PT_GR20(%r1),%r20	LDREG	TASK_PT_GR21(%r1),%r21	LDREG	TASK_PT_GR22(%r1),%r22	LDREG	TASK_PT_GR23(%r1),%r23	LDREG	TASK_PT_GR24(%r1),%r24	LDREG	TASK_PT_GR25(%r1),%r25	LDREG	TASK_PT_GR26(%r1),%r26	LDREG	TASK_PT_GR27(%r1),%r27	   /* restore user dp */	LDREG	TASK_PT_GR28(%r1),%r28	   /* syscall return value */	LDREG	TASK_PT_GR29(%r1),%r29	LDREG	TASK_PT_GR31(%r1),%r31	   /* restore syscall rp */	/* NOTE: We use rsm/ssm pair to make this operation atomic */	rsm     PSW_SM_I, %r0	LDREG   TASK_PT_GR30(%r1),%r30             /* restore user sp */	mfsp	%sr3,%r1			   /* Get users space id */	mtsp    %r1,%sr7                           /* Restore sr7 */	ssm     PSW_SM_I, %r0	/* Set sr2 to zero for userspace syscalls to work. */	mtsp	%r0,%sr2 	mtsp	%r1,%sr4			   /* Restore sr4 */	mtsp	%r1,%sr5			   /* Restore sr5 */	mtsp	%r1,%sr6			   /* Restore sr6 */	depi	3,31,2,%r31			   /* ensure return to user mode. */#ifdef __LP64__	/* decide whether to reset the wide mode bit	 *	 * For a syscall, the W bit is stored in the lowest bit	 * of sp.  Extract it and reset W if it is zero */	extrd,u,*<>	%r30,63,1,%r1	rsm	PSW_SM_W, %r0	/* now reset the lowest bit of sp if it was set */	xor	%r30,%r1,%r30#endif	be,n    0(%sr3,%r31)                       /* return to user space */	/* We have to return via an RFI, so that PSW T and R bits can be set	 * appropriately.	 * This sets up pt_regs so we can return via intr_restore, which is not	 * the most efficient way of doing things, but it works.	 */syscall_restore_rfi:	ldo	-1(%r0),%r2			   /* Set recovery cntr to -1 */	mtctl	%r2,%cr0			   /*   for immediate trap */	LDREG	TASK_PT_PSW(%r1),%r2		   /* Get old PSW */	ldi	0x0b,%r20			   /* Create new PSW */	depi	-1,13,1,%r20			   /* C, Q, D, and I bits */	/* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are	 * set in include/linux/ptrace.h and converted to PA bitmap	 * numbers in asm-offsets.c */	/* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */	extru,=	%r19,PA_SINGLESTEP_BIT,1,%r0	depi	-1,27,1,%r20			   /* R bit */	/* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */	extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0	depi	-1,7,1,%r20			   /* T bit */	STREG	%r20,TASK_PT_PSW(%r1)	/* Always store space registers, since sr3 can be changed (e.g. fork) */	mfsp    %sr3,%r25	STREG   %r25,TASK_PT_SR3(%r1)	STREG   %r25,TASK_PT_SR4(%r1)	STREG   %r25,TASK_PT_SR5(%r1)	STREG   %r25,TASK_PT_SR6(%r1)	STREG   %r25,TASK_PT_SR7(%r1)	STREG   %r25,TASK_PT_IASQ0(%r1)	STREG   %r25,TASK_PT_IASQ1(%r1)	/* XXX W bit??? */	/* Now if old D bit is clear, it means we didn't save all registers	 * on syscall entry, so do that now.  This only happens on TRACEME	 * calls, or if someone attached to us while we were on a syscall.	 * We could make this more efficient by not saving r3-r18, but	 * then we wouldn't be able to use the common intr_restore path.	 * It is only for traced processes anyway, so performance is not	 * an issue.	 */	bb,<	%r2,30,pt_regs_ok		   /* Branch if D set */	ldo	TASK_REGS(%r1),%r25	reg_save %r25				   /* Save r3 to r18 */	/* Save the current sr */	mfsp	%sr0,%r2	STREG	%r2,TASK_PT_SR0(%r1)	/* Save the scratch sr */	mfsp	%sr1,%r2	STREG	%r2,TASK_PT_SR1(%r1)	/* sr2 should be set to zero for userspace syscalls */	STREG	%r0,TASK_PT_SR2(%r1)pt_regs_ok:	LDREG	TASK_PT_GR31(%r1),%r2	depi	3,31,2,%r2			   /* ensure return to user mode. */	STREG	%r2,TASK_PT_IAOQ0(%r1)	ldo	4(%r2),%r2	STREG	%r2,TASK_PT_IAOQ1(%r1)	copy	%r25,%r16	b	intr_restore	nop	.import do_softirq,codesyscall_do_softirq:	bl      do_softirq,%r2	nop	/* NOTE: We enable I-bit incase we schedule later,	 * and we might be going back to userspace if we were	 * traced. */	b       syscall_check_resched	ssm     PSW_SM_I, %r0  /* do_softirq returns with I bit off */	.import schedule,codesyscall_do_resched:	BL	schedule,%r2#ifdef __LP64__	ldo	-16(%r30),%r29		/* Reference param save area */#else	nop#endif	b       syscall_check_bh  /* if resched, we start over again */	nop	.import do_signal,codesyscall_do_signal:	/* Save callee-save registers (for sigcontext).	   FIXME: After this point the process structure should be	   consistent with all the relevant state of the process	   before the syscall.  We need to verify this. */	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 	ldo	TASK_REGS(%r1), %r25		/* struct pt_regs *regs */	reg_save %r25	ldi	1, %r24				/* unsigned long in_syscall */#ifdef __LP64__	ldo	-16(%r30),%r29			/* Reference param save area */#endif	BL	do_signal,%r2	copy	%r0, %r26			/* sigset_t *oldset = NULL */	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1	ldo	TASK_REGS(%r1), %r20		/* reload pt_regs */	reg_restore %r20	b,n     syscall_check_sig	/*	 * get_register is used by the non access tlb miss handlers to	 * copy the value of the general register specified in r8 into	 * r1. This routine can't be used for shadowed registers, since	 * the rfir will restore the original value. So, for the shadowed	 * registers we put a -1 into r1 to indicate that the register	 * should not be used (the register being copied could also have	 * a -1 in it, but that is OK, it just means that we will have	 * to use the slow path instead).	 */get_register:	blr     %r8,%r0	nop	bv      %r0(%r25)    /* r0 */	copy    %r0,%r1	bv      %r0(%r25)    /* r1 - shadowed */	ldi     -1,%r1	bv      %r0(%r25)    /* r2 */	copy    %r2,%r1	bv      %r0(%r25)    /* r3 */	copy    %r3,%r1	bv      %r0(%r25)    /* r4 */	copy    %r4,%r1	bv      %r0(%r25)    /* r5 */	copy    %r5,%r1	bv      %r0(%r25)    /* r6 */	copy    %r6,%r1	bv      %r0(%r25)    /* r7 */	copy    %r7,%r1	bv      %r0(%r25)    /* r8 - shadowed */	ldi     -1,%r1	bv      %r0(%r25)    /* r9 - shadowed */	ldi     -1,%r1	bv      %r0(%r25)    /* r10 */	copy    %r10,%r1	bv      %r0(%r25)    /* r11 */	copy    %r11,%r1	bv      %r0(%r25)    /* r12 */	copy    %r12,%r1	bv      %r0(%r25)    /* r13 */	copy    %r13,%r1	bv      %r0(%r25)    /* r14 */	copy    %r14,%r1	bv      %r0(%r25)    /* r15 */	copy    %r15,%r1	bv      %r0(%r25)    /* r16 - shadowed */	ldi     -1,%r1	bv      %r0(%r25)    /* r17 - shadowed */	ldi     -1,%r1	bv      %r0(%r25)    /* r18 */	copy    %r18,%r1	bv      %r0(%r25)    /* r19 */	copy    %r19,%r1	bv      %r0(%r25)    /* r20 */	copy    %r20,%r1	bv      %r0(%r25)    /* r21 */	copy    %r21,%r1	bv      %r0(%r25)    /* r22 */	copy    %r22,%r1	bv      %r0(%r25)    /* r23 */	copy    %r23,%r1	bv      %r0(%r25)    /* r24 - shadowed */	ldi     -1,%r1	bv      %r0(%r25)    /* r25 - shadowed */	ldi     -1,%r1	bv      %r0(%r25)    /* r26 */	copy    %r26,%r1	bv      %r0(%r25)    /* r27 */	copy    %r27,%r1	bv      %r0(%r25)    /* r28 */	copy    %r28,%r1	bv      %r0(%r25)    /* r29 */	copy    %r29,%r1	bv      %r0(%r25)    /* r30 */	copy    %r30,%r1	bv      %r0(%r25)    /* r31 */	copy    %r31,%r1	/*	 * set_register is used by the non access tlb miss handlers to	 * copy the value of r1 into the general register specified in	 * r8.	 */set_register:	blr     %r8,%r0	nop	bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */	copy    %r1,%r0	bv      %r0(%r25)    /* r1 */	copy    %r1,%r1	bv      %r0(%r25)    /* r2 */	copy    %r1,%r2	bv      %r0(%r25)    /* r3 */	copy    %r1,%r3	bv      %r0(%r25)    /* r4 */	copy    %r1,%r4	bv      %r0(%r25)    /* r5 */	copy    %r1,%r5	bv      %r0(%r25)    /* r6 */	copy    %r1,%r6	bv      %r0(%r25)    /* r7 */	copy    %r1,%r7	bv      %r0(%r25)    /* r8 */	copy    %r1,%r8	bv      %r0(%r25)    /* r9 */	copy    %r1,%r9	bv      %r0(%r25)    /* r10 */	copy    %r1,%r10	bv      %r0(%r25)    /* r11 */	copy    %r1,%r11	bv      %r0(%r25)    /* r12 */	copy    %r1,%r12	bv      %r0(%r25)    /* r13 */	copy    %r1,%r13	bv      %r0(%r25)    /* r14 */	copy    %r1,%r14	bv      %r0(%r25)    /* r15 */	copy    %r1,%r15	bv      %r0(%r25)    /* r16 */	copy    %r1,%r16	bv      %r0(%r25)    /* r17 */	copy    %r1,%r17	bv      %r0(%r25)    /* r18 */	copy    %r1,%r18	bv      %r0(%r25)    /* r19 */	copy    %r1,%r19	bv      %r0(%r25)    /* r20 */	copy    %r1,%r20	bv      %r0(%r25)    /* r21 */	copy    %r1,%r21	bv      %r0(%r25)    /* r22 */	copy    %r1,%r22	bv      %r0(%r25)    /* r23 */	copy    %r1,%r23	bv      %r0(%r25)    /* r24 */	copy    %r1,%r24	bv      %r0(%r25)    /* r25 */	copy    %r1,%r25	bv      %r0(%r25)    /* r26 */	copy    %r1,%r26	bv      %r0(%r25)    /* r27 */	copy    %r1,%r27	bv      %r0(%r25)    /* r28 */	copy    %r1,%r28	bv      %r0(%r25)    /* r29 */	copy    %r1,%r29	bv      %r0(%r25)    /* r30 */	copy    %r1,%r30	bv      %r0(%r25)    /* r31 */	copy    %r1,%r31

⌨️ 快捷键说明

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