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

📄 entry.s

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 S
📖 第 1 页 / 共 3 页
字号:
	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0	depdi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */	/* Get rid of prot bits and convert to page addr for idtlbt */	depdi		0,63,12,pte	extrd,u         pte,56,32,pte	idtlbt		%r16,%r17	rfir	nop#elsedbit_trap_11:	mfctl           %cr25,ptp	/* Assume user space trap */	or,<>           %r0,spc,%r0	/* If it is user space, nullify */	mfctl           %cr24,ptp	/* Load kernel pgd instead */	extru		va,9,10,t1	/* Get pgd index */	mfsp            %sr7,t0		/* Get current space */	or,=            %r0,t0,%r0	/* If kernel, nullify following test */	comb,<>,n       t0,spc,dbit_fault /* forward */	/* First level page table lookup */	ldwx,s		t1(ptp),ptp	extru		va,19,10,t0	/* get second-level index */	bb,>=,n 	ptp,_PAGE_PRESENT_BIT,dbit_fault	depi		0,31,12,ptp	/* clear prot bits */	/* Second level page table lookup */	sh2addl 	 t0,ptp,ptp	ldi		(_PAGE_ACCESSED|_PAGE_DIRTY),t1	ldw		 0(ptp),pte	bb,>=,n 	 pte,_PAGE_PRESENT_BIT,dbit_fault	/* Set Accessed and Dirty bits in the pte */	or		t1,pte,pte	stw		pte,0(ptp)	/* write back pte */	copy            spc,prot        /* init prot with faulting space */	dep		pte,8,7,prot	extru,=		pte,_PAGE_NO_CACHE_BIT,1,r0	depi		1,12,1,prot	extru,=         pte,_PAGE_USER_BIT,1,r0	depi		7,11,3,prot /* Set for user space (1 rsvd for read) */	extru,= 	pte,_PAGE_GATEWAY_BIT,1,r0	depi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */	/* Get rid of prot bits and convert to page addr for idtlba */	depi		0,31,12,pte	extru		pte,24,25,pte	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */	mtsp		spc,%sr1	idtlba		pte,(%sr1,va)	idtlbp		prot,(%sr1,va)	mtsp		t0, %sr1     /* Restore sr1 */	rfir	nopdbit_trap_20:	mfctl           %cr25,ptp	/* Assume user space trap */	or,<>           %r0,spc,%r0	/* If it is user space, nullify */	mfctl           %cr24,ptp	/* Load kernel pgd instead */	extru		va,9,10,t1	/* Get pgd index */	mfsp            %sr7,t0		/* Get current space */	or,=            %r0,t0,%r0	/* If kernel, nullify following test */	comb,<>,n       t0,spc,dbit_fault /* forward */	/* First level page table lookup */	ldwx,s		t1(ptp),ptp	extru		va,19,10,t0	/* get second-level index */	bb,>=,n 	ptp,_PAGE_PRESENT_BIT,dbit_fault	depi		0,31,12,ptp	/* clear prot bits */	/* Second level page table lookup */	sh2addl 	 t0,ptp,ptp	ldi		(_PAGE_ACCESSED|_PAGE_DIRTY),t1	ldw		 0(ptp),pte	bb,>=,n 	 pte,_PAGE_PRESENT_BIT,dbit_fault	/* Set Accessed and Dirty bits in the pte */	or		t1,pte,pte	stw		pte,0(ptp)	/* write back pte */	copy            spc,prot        /* init prot with faulting space */		.level 2.0	depd		pte,8,7,prot	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0	depdi		1,12,1,prot	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0	depdi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */	/* Get rid of prot bits and convert to page addr for idtlbt */	depdi		0,63,12,pte	extrd,u		pte,56,25,pte	idtlbt		%r16,%r17	.level		1.1	rfir	nop#endif	.import handle_interruption,codekernel_bad_space:	b		tlb_fault	ldi		31,%r1	/* Use an unused code */dbit_fault:	b		tlb_fault	ldi		20,%r1itlb_fault:	b		tlb_fault	ldi		6,%r1dtlb_fault:	ldi		15,%r1	/* Fall Through */tlb_fault:	mtctl		%r1,%cr29	mtctl		%r29,%cr31	get_stack	save_specials	%r29		/* Note this saves a trashed r1 */	SAVE_CR		(%cr20, PT_ISR(%r29))	SAVE_CR		(%cr21, PT_IOR(%r29))	virt_map	rfir	STREG		%r1,PT_GR1(%r29)	/* save good value after rfir */	save_general	%r29	ldo	PT_FR0(%r29), %r25	save_fp		%r25		loadgp	copy		%r29, %r25	bl		handle_interruption, %r2	copy		%r29, %r16	b		intr_return	nop	/* Register saving semantics for system calls:	   %r1		   clobbered by system call macro in userspace	   %r2		   saved in PT_REGS by gateway page	   %r3  - %r18	   preserved by C code (saved by signal code)	   %r19 - %r20	   saved in PT_REGS by gateway page	   %r21 - %r22	   non-standard syscall args			   stored in kernel stack by gateway page	   %r23 - %r26	   arg3-arg0, saved in PT_REGS by gateway page	   %r27 - %r30	   saved in PT_REGS by gateway page	   %r31		   syscall return pointer	 */	/* Floating point registers (FIXME: what do we do with these?)	   %fr0  - %fr3	   status/exception, not preserved	   %fr4  - %fr7	   arguments	   %fr8	 - %fr11   not preserved by C code	   %fr12 - %fr21   preserved by C code	   %fr22 - %fr31   not preserved by C code	 */	.macro	reg_save regs	STREG	%r3, PT_GR3(\regs)	STREG	%r4, PT_GR4(\regs)	STREG	%r5, PT_GR5(\regs)	STREG	%r6, PT_GR6(\regs)	STREG	%r7, PT_GR7(\regs)	STREG	%r8, PT_GR8(\regs)	STREG	%r9, PT_GR9(\regs)	STREG   %r10,PT_GR10(\regs)	STREG   %r11,PT_GR11(\regs)	STREG   %r12,PT_GR12(\regs)	STREG   %r13,PT_GR13(\regs)	STREG   %r14,PT_GR14(\regs)	STREG   %r15,PT_GR15(\regs)	STREG   %r16,PT_GR16(\regs)	STREG   %r17,PT_GR17(\regs)	STREG   %r18,PT_GR18(\regs)	.endm	.macro	reg_restore regs	LDREG	PT_GR3(\regs), %r3	LDREG	PT_GR4(\regs), %r4	LDREG	PT_GR5(\regs), %r5	LDREG	PT_GR6(\regs), %r6	LDREG	PT_GR7(\regs), %r7	LDREG	PT_GR8(\regs), %r8	LDREG	PT_GR9(\regs), %r9	LDREG   PT_GR10(\regs),%r10	LDREG   PT_GR11(\regs),%r11	LDREG   PT_GR12(\regs),%r12	LDREG   PT_GR13(\regs),%r13	LDREG   PT_GR14(\regs),%r14	LDREG   PT_GR15(\regs),%r15	LDREG   PT_GR16(\regs),%r16	LDREG   PT_GR17(\regs),%r17	LDREG   PT_GR18(\regs),%r18	.endm	.export sys_fork_wrappersys_fork_wrapper:	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1	/* get pt regs */	reg_save %r1	STREG	%r2,-RP_OFFSET(%r30)	ldo	FRAME_SIZE(%r30),%r30	/* These are call-clobbered registers and therefore	   also syscall-clobbered (we hope). */	STREG	%r2,PT_GR19(%r1)	/* save for child */	STREG	%r30,PT_GR20(%r1)	ldil	L%child_return, %r3	ldo	R%child_return(%r3), %r3	LDIL_FIXUP(%r3)	STREG	%r3,PT_GR21(%r1)	/* save for child */	LDREG	PT_GR30(%r1),%r25	copy	%r1,%r24	bl	sys_clone,%r2	ldi	SIGCHLD,%r26	LDREG	-RP_OFFSET-FRAME_SIZE(%r30),%r2wrapper_exit:	ldo	-FRAME_SIZE(%r30),%r30		/* get the stackframe */	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1    /* get pt regs */	reg_restore %r1	bv %r0(%r2)	nop	/* Set the return value for the child */child_return:	LDREG	TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2	b	wrapper_exit	copy	%r0,%r28		.export sys_clone_wrappersys_clone_wrapper:	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1	/* get pt regs */	reg_save %r1	STREG	%r2,-RP_OFFSET(%r30)	ldo	FRAME_SIZE(%r30),%r30	STREG	%r30,PT_GR20(%r1)	ldil	L%child_return,%r3	ldo	R%child_return(%r3),%r3	LDIL_FIXUP(%r3)	bl	sys_clone,%r2	STREG	%r3,PT_GR21(%r1)	/* save for child */	b	wrapper_exit	LDREG	-RP_OFFSET-FRAME_SIZE(%r30),%r2	.export sys_vfork_wrappersys_vfork_wrapper:	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1	/* get pt regs */	reg_save %r1	STREG	%r2,-RP_OFFSET(%r30)	ldo	FRAME_SIZE(%r30),%r30	STREG	%r30,PT_GR20(%r1)	ldil	L%child_return,%r3	ldo	R%child_return(%r3),%r3	LDIL_FIXUP(%r3)	STREG	%r3,PT_GR21(%r1)	/* save for child */	bl	sys_vfork,%r2	copy	%r1,%r26	b	wrapper_exit	LDREG	-RP_OFFSET-FRAME_SIZE(%r30),%r2		.macro  execve_wrapper execve	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%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	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	comb,>>= %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:	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30), %r26	/* Don't save regs, we are going to restore them from sigcontext. */	STREG	%r2, -RP_OFFSET(%r30)	bl	sys_rt_sigreturn,%r2	ldo	FRAME_SIZE(%r30), %r30	ldo	-FRAME_SIZE(%r30), %r30	LDREG	-RP_OFFSET(%r30), %r2	/* FIXME: I think we need to restore a few more things here. */	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%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	-TASK_SZ_ALGN-FRAME_SIZE+TASK_PT_GR30(%r30), %r24	STREG	%r2, -RP_OFFSET(%r30)	bl	do_sigaltstack,%r2	ldo	FRAME_SIZE(%r30), %r30	ldo	-FRAME_SIZE(%r30), %r30	LDREG	-RP_OFFSET(%r30), %r2	bv	%r0(%r2)	nop	.export sys_rt_sigsuspend_wrappersys_rt_sigsuspend_wrapper:	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30), %r24	reg_save %r24	STREG	%r2, -RP_OFFSET(%r30)	bl	sys_rt_sigsuspend,%r2	ldo	FRAME_SIZE(%r30), %r30	ldo	-FRAME_SIZE(%r30), %r30	LDREG	-RP_OFFSET(%r30), %r2	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%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.  All traced processes will probably exit via	 * syscall_exit_rfi in the future.	 */	/* save return value now */	STREG     %r28,TASK_PT_GR28-TASK_SZ_ALGN-FRAME_SIZE(%r30)syscall_check_bh:/* #ifdef NOTNOW */	/* Check for software interrupts */	.import irq_stat,data	ldil    L%irq_stat,%r19	ldo     R%irq_stat(%r19),%r19	LDIL_FIXUP(%r19)#ifdef CONFIG_SMP	/* sched.h: int processor */	ldw     TASK_PROCESSOR-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r20 /* get cpu # */#if (IRQSTAT_SZ == 32)	dep     %r20,26,27,%r20 /* shift left 5 bits */#else#error IRQSTAT_SZ changed, fix dep#endif /* IRQSTAT_SZ */	add     %r19,%r20,%r19#endif /* CONFIG_SMP */	ldw     IRQSTAT_SI_ACTIVE(%r19),%r20	/* hardirq.h: unsigned int */	ldw     IRQSTAT_SI_MASK(%r19),%r19	/* hardirq.h: unsigned int */	and     %r19,%r20,%r20	comib,<>,n 0,%r20,syscall_do_softirq /* forward *//* #endif */syscall_check_resched:	/* check for reschedule */	LDREG  TASK_NEED_RESCHED-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r19	/* long */	comib,<>,n 0,%r19,syscall_do_resched /* forward */syscall_check_sig:	ldo     -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1         /* get task ptr */	/* check for pending signals */	ldw     TASK_SIGPENDING(%r1),%r19	comib,<>,n 0,%r19,syscall_do_signal  /* forward */syscall_restore:	/* disable interrupts while dicking with the kernel stack, */	/* or life can become unpleasant */	rsm	PSW_SM_I, %r20	LDREG	TASK_PTRACE(%r1), %r19		/* Are we being ptraced? */	bb,<,n	%r19,31,syscall_restore_rfi	LDREG	TASK_PT_GR20(%r1),%r19	mtctl	%r19, %cr27	LDREG	TASK_PT_GR2(%r1),%r2		   /* restore user rp */	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_GR30(%r1),%r30	   /* restore user sp */	LDREG	TASK_PT_GR31(%r1),%r31	   /* restore syscall rp */	ldo	TASK_PT_FR31(%r1),%r19		   /* reload fpregs */	rest_fp	%r19	LDREG	TASK_PT_SAR(%r1),%r19		   /* restore SAR */	mtsar	%r19	LDREG	TASK_PT_GR19(%r1),%r19	mtctl	%r1,%cr30			   /* intrhandler okay. */	mfsp	%sr3,%r1			   /* Get users space id */	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. */	mtsm	%r20				   /* restore irq state  */	mfctl	%cr27,%r20		/*	 * Due to a dependency in the tlb miss handlers on sr7, it	 * is essential that sr7 get set in the delay slot.	 */#ifdef __LP64__	/* Note the be (and mtsp) is executed in narrow mode. This is OK	 * for 32 bit processes, but won't work once we support 64 bit	 * processes.	 */	rsm	PSW_SM_W, %r0	be	0(%sr3,%r31)			   /* return to user space */	mtsp	%r1,%sr7			   /* Restore sr7 */#else	be	0(%sr3,%r31)			   /* return to user space */	mtsp	%r1,%sr7			   /* Restore sr7 */#endif	/* 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 */	copy	%r0,%r2				   /* Create a reasonable PSW */	/* XXX W bit??? */	depi	-1,13,1,%r2	depi	-1,28,1,%r2	depi	-1,30,1,%r2	depi	-1,31,1,%r2	bb,<,n	%r19,15,set_rbit		   /* PT_SINGLESTEP */	bb,>=,n	%r19,14,set_nobit		   /* PT_BLOCKSTEP, see ptrace.c */set_tbit:	depi	-1,7,1,%r2	b,n	set_nobitset_rbit:	depi	-1,27,1,%r2set_nobit:	STREG	%r2,TASK_PT_PSW(%r1)	STREG	%r1,TASK_PT_CR30(%r1)	mfsp	%sr0,%r2	STREG	%r2,TASK_PT_SR0(%r1)	mfsp	%sr1,%r2	STREG	%r2,TASK_PT_SR1(%r1)	mfsp	%sr2,%r2	STREG	%r2,TASK_PT_SR2(%r1)	mfsp	%sr3,%r2	STREG	%r2,TASK_PT_SR3(%r1)	STREG	%r2,TASK_PT_SR4(%r1)	STREG	%r2,TASK_PT_SR5(%r1)	STREG	%r2,TASK_PT_SR6(%r1)	STREG	%r2,TASK_PT_SR7(%r1)	STREG	%r2,TASK_PT_IASQ0(%r1)	STREG	%r2,TASK_PT_IASQ1(%r1)	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)	ldo	TASK_REGS(%r1),%r25	reg_save %r25				   /* Save r3 to r18 */	copy	%r25,%r16	b	intr_restore	nop	.import do_softirq,codesyscall_do_softirq:	bl      do_softirq,%r2	nop	b       syscall_check_resched	ssm     PSW_SM_I, %r0  /* do_softirq returns with I bit off */	.import schedule,codesyscall_do_resched:	bl	schedule,%r2	nop	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. */	ldo	TASK_REGS(%r1), %r25		/* struct pt_regs *regs */	reg_save %r25	ldi	1, %r24				/* unsigned long in_syscall */	bl	do_signal,%r2	copy	%r0, %r26			/* sigset_t *oldset = NULL */	ldo     -TASK_SZ_ALGN-FRAME_SIZE(%r30), %r1     /* reload task ptr */	ldo	TASK_REGS(%r1), %r20		/* reload pt_regs */	reg_restore %r20	b,n     syscall_restore#ifdef __LP64__unimplemented_64bitirq:	ssm PSW_SM_Q+PSW_SM_I, %r0	/* indicate that we had an interrupt */	ldi	0x77, %r28	ldi	0x77, %r29	/* save interrupt registers in GRs for diagnosis */	mfctl %cr17, %r17	mfctl %cr18, %r18	mfctl %cr19, %r19	mfctl %cr20, %r20	mfctl %cr21, %r21	mfctl %cr22, %r22	b,n .	nop#endif

⌨️ 快捷键说明

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