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

📄 entry.s

📁 优龙2410linux2.6.8内核源代码
💻 S
📖 第 1 页 / 共 4 页
字号:
	/* The alias region is an 8MB aligned 16MB to do clear and	 * copy user pages at addresses congruent with the user	 * virtual address.	 *	 * To use the alias page, you set %r26 up with the to TLB	 * entry (identifying the physical page) and %r23 up with	 * the from tlb entry (or nothing if only a to entry---for	 * clear_user_page_asm) */	.macro		do_alias	spc,tmp,tmp1,va,pte,prot,fault	cmpib,COND(<>),n 0,\spc,\fault	ldil		L%(TMPALIAS_MAP_START),\tmp#if defined(__LP64__) && (TMPALIAS_MAP_START >= 0x80000000)	/* on LP64, ldi will sign extend into the upper 32 bits,	 * which is behaviour we don't want */	depdi		0,31,32,\tmp#endif	copy		\va,\tmp1	DEPI		0,31,23,\tmp1	cmpb,COND(<>),n	\tmp,\tmp1,\fault	ldi		(_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot	depd,z		\prot,8,7,\prot	/*	 * OK, it is in the temp alias region, check whether "from" or "to".	 * Check "subtle" note in pacache.S re: r23/r26.	 */#ifdef __LP64__	extrd,u,*=	\va,41,1,%r0#else	extrw,u,=	\va,9,1,%r0#endif	or,COND(tr)	%r23,%r0,\pte	or		%r26,%r0,\pte	.endm 	/*	 * Align fault_vector_20 on 4K boundary so that both	 * fault_vector_11 and fault_vector_20 are on the	 * same page. This is only necessary as long as we	 * write protect the kernel text, which we may stop	 * doing once we use large page translations to cover	 * the static part of the kernel address space.	 */	.export fault_vector_20	.text	.align 4096fault_vector_20:	/* First vector is invalid (0) */	.ascii	"cows can fly"	.byte 0	.align 32	hpmc		 1	def		 2	def		 3	extint		 4	def		 5	itlb_20		 6	def		 7	def		 8	def              9	def		10	def		11	def		12	def		13	def		14	dtlb_20		15#if 0	naitlb_20	16#else	def             16#endif	nadtlb_20	17	def		18	def		19	dbit_20		20	def		21	def		22	def		23	def		24	def		25	def		26	def		27	def		28	def		29	def		30	def		31#ifndef __LP64__	.export fault_vector_11		.align 2048fault_vector_11:	/* First vector is invalid (0) */	.ascii	"cows can fly"	.byte 0	.align 32	hpmc		 1	def		 2	def		 3	extint		 4	def		 5	itlb_11		 6	def		 7	def		 8	def              9	def		10	def		11	def		12	def		13	def		14	dtlb_11		15#if 0	naitlb_11	16#else	def             16#endif	nadtlb_11	17	def		18	def		19	dbit_11		20	def		21	def		22	def		23	def		24	def		25	def		26	def		27	def		28	def		29	def		30	def		31#endif	.import		handle_interruption,code	.import		do_cpu_irq_mask,code	/*	 * r26 = function to be called	 * r25 = argument to pass in	 * r24 = flags for do_fork()	 *	 * Kernel threads don't ever return, so they don't need	 * a true register context. We just save away the arguments	 * for copy_thread/ret_ to properly set up the child.	 */#define CLONE_VM 0x100	/* Must agree with <linux/sched.h> */#define CLONE_UNTRACED 0x00800000	.export __kernel_thread, code	.import do_fork__kernel_thread:	STREG	%r2, -RP_OFFSET(%r30)	copy	%r30, %r1	ldo	PT_SZ_ALGN(%r30),%r30#ifdef __LP64__	/* Yo, function pointers in wide mode are little structs... -PB */	ldd	24(%r26), %r2	STREG	%r2, PT_GR27(%r1)	/* Store childs %dp */	ldd	16(%r26), %r26	STREG	%r22, PT_GR22(%r1)	/* save r22 (arg5) */	copy	%r0, %r22		/* user_tid */#endif	STREG	%r26, PT_GR26(%r1)  /* Store function & argument for child */	STREG	%r25, PT_GR25(%r1)	ldil	L%CLONE_UNTRACED, %r26	ldo	CLONE_VM(%r26), %r26   /* Force CLONE_VM since only init_mm */	or	%r26, %r24, %r26      /* will have kernel mappings.	 */	ldi	1, %r25			/* stack_start, signals kernel thread */	stw	%r0, -52(%r30)	     	/* user_tid */#ifdef __LP64__	ldo	-16(%r30),%r29		/* Reference param save area */#endif	bl	do_fork, %r2	copy	%r1, %r24		/* pt_regs */	/* Parent Returns here */	LDREG	-PT_SZ_ALGN-RP_OFFSET(%r30), %r2	ldo	-PT_SZ_ALGN(%r30), %r30	bv	%r0(%r2)	nop	/*	 * Child Returns here	 *	 * copy_thread moved args from temp save area set up above	 * into task save area.	 */	.export	ret_from_kernel_threadret_from_kernel_thread:	/* Call schedule_tail first though */	BL	schedule_tail, %r2	nop	LDREG	TI_TASK-THREAD_SZ_ALGN(%r30), %r1	LDREG	TASK_PT_GR25(%r1), %r26#ifdef __LP64__	LDREG	TASK_PT_GR27(%r1), %r27	LDREG	TASK_PT_GR22(%r1), %r22#endif	LDREG	TASK_PT_GR26(%r1), %r1	ble	0(%sr7, %r1)	copy	%r31, %r2#ifdef __LP64__	ldo	-16(%r30),%r29		/* Reference param save area */	loadgp				/* Thread could have been in a module */#endif	b	sys_exit	ldi	0, %r26	.import	sys_execve, code	.export	__execve, code__execve:	copy	%r2, %r15	copy	%r30, %r16	ldo	PT_SZ_ALGN(%r30), %r30	STREG	%r26, PT_GR26(%r16)	STREG	%r25, PT_GR25(%r16)	STREG	%r24, PT_GR24(%r16)#ifdef __LP64__	ldo	-16(%r30),%r29		/* Reference param save area */#endif	bl	sys_execve, %r2	copy	%r16, %r26	cmpib,=,n 0,%r28,intr_return    /* forward */	/* yes, this will trap and die. */	copy	%r15, %r2	copy	%r16, %r30	bv	%r0(%r2)	nop	.align 4	/*	 * struct task_struct *_switch_to(struct task_struct *prev,	 *	struct task_struct *next)	 *	 * switch kernel stacks and return prev */	.export	_switch_to, code_switch_to:	STREG	 %r2, -RP_OFFSET(%r30)	callee_save	ldil	L%_switch_to_ret, %r2	ldo	R%_switch_to_ret(%r2), %r2	STREG	%r2, TASK_PT_KPC(%r26)	LDREG	TASK_PT_KPC(%r25), %r2	STREG	%r30, TASK_PT_KSP(%r26)	LDREG	TASK_PT_KSP(%r25), %r30	LDREG	TASK_THREAD_INFO(%r25), %r25	bv	%r0(%r2)	mtctl   %r25,%cr30_switch_to_ret:	mtctl	%r0, %cr0		/* Needed for single stepping */	callee_rest	LDREG	-RP_OFFSET(%r30), %r2	bv	%r0(%r2)	copy	%r26, %r28	/*	 * Common rfi return path for interruptions, kernel execve, and	 * sys_rt_sigreturn (sometimes).  The sys_rt_sigreturn syscall will	 * return via this path if the signal was received when the process	 * was running; if the process was blocked on a syscall then the	 * normal syscall_exit path is used.  All syscalls for traced	 * proceses exit via intr_restore.	 *	 * XXX If any syscalls that change a processes space id ever exit	 * this way, then we will need to copy %sr3 in to PT_SR[3..7], and	 * adjust IASQ[0..1].	 *	 * Note that the following code uses a "relied upon translation".	 * See the parisc ACD for details. The ssm is necessary due to a	 * PCXT bug.	 */	.align 4096	.export	syscall_exit_rfisyscall_exit_rfi:	mfctl   %cr30,%r16	LDREG	TI_TASK(%r16), %r16	/* thread_info -> task_struct */	ldo	TASK_REGS(%r16),%r16	/* Force iaoq to userspace, as the user has had access to our current	 * context via sigcontext. Also Filter the PSW for the same reason.	 */	LDREG	PT_IAOQ0(%r16),%r19	depi	3,31,2,%r19	STREG	%r19,PT_IAOQ0(%r16)	LDREG	PT_IAOQ1(%r16),%r19	depi	3,31,2,%r19	STREG	%r19,PT_IAOQ1(%r16)	LDREG   PT_PSW(%r16),%r19	ldil    L%USER_PSW_MASK,%r1	ldo     R%USER_PSW_MASK(%r1),%r1#ifdef __LP64__	ldil    L%USER_PSW_HI_MASK,%r20	ldo     R%USER_PSW_HI_MASK(%r20),%r20	depd    %r20,31,32,%r1#endif	and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */	ldil    L%USER_PSW,%r1	ldo     R%USER_PSW(%r1),%r1	or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */	STREG   %r19,PT_PSW(%r16)	/*	 * If we aren't being traced, we never saved space registers	 * (we don't store them in the sigcontext), so set them	 * to "proper" values now (otherwise we'll wind up restoring	 * whatever was last stored in the task structure, which might	 * be inconsistent if an interrupt occured while on the gateway	 * page) Note that we may be "trashing" values the user put in	 * them, but we don't support the the user changing them.	 */	STREG   %r0,PT_SR2(%r16)	mfsp    %sr3,%r19	STREG   %r19,PT_SR0(%r16)	STREG   %r19,PT_SR1(%r16)	STREG   %r19,PT_SR3(%r16)	STREG   %r19,PT_SR4(%r16)	STREG   %r19,PT_SR5(%r16)	STREG   %r19,PT_SR6(%r16)	STREG   %r19,PT_SR7(%r16)intr_return:	ssm     PSW_SM_I, %r0	/* Check for software interrupts */	.import irq_stat,data	ldil	L%irq_stat,%r19	ldo	R%irq_stat(%r19),%r19#ifdef CONFIG_SMP	mfctl   %cr30,%r1	ldw	TI_CPU(%r1),%r1 /* get cpu # - int */	/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount	** irq_stat[] is defined using ____cacheline_aligned.	*/#ifdef __LP64__	shld	%r1, 6, %r20#else	shlw	%r1, 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,intr_do_softirq /* forward */intr_check_resched:	/* check for reschedule */	mfctl   %cr30,%r1	LDREG   TI_FLAGS(%r1),%r19	/* sched.h: TIF_NEED_RESCHED */	bb,<,n	%r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */intr_check_sig:	/* As above */	mfctl   %cr30,%r1	LDREG	TI_FLAGS(%r1),%r19	/* sched.h: TIF_SIGPENDING */	bb,<,n %r19, 31-TIF_SIGPENDING, intr_do_signal /* forward */intr_restore:	copy            %r16,%r29	ldo             PT_FR31(%r29),%r1	rest_fp         %r1	rest_general    %r29	ssm		0,%r0	nop	nop	nop	nop	nop	nop	nop	tophys_r1       %r29	rsm             (PSW_SM_Q|PSW_SM_P|PSW_SM_D|PSW_SM_I),%r0	rest_specials	%r29	rest_stack	rfi	nop	nop	nop	nop	nop	nop	nop	nop	.import do_softirq,codeintr_do_softirq:	bl      do_softirq,%r2#ifdef __LP64__	ldo	-16(%r30),%r29		/* Reference param save area */#else	nop#endif	b       intr_check_resched	nop	.import schedule,codeintr_do_resched:	/* Only do reschedule if we are returning to user space */	LDREG	PT_IASQ0(%r16), %r20	CMPIB= 0,%r20,intr_restore /* backward */	nop	LDREG	PT_IASQ1(%r16), %r20	CMPIB= 0,%r20,intr_restore /* backward */	nop#ifdef __LP64__	ldo	-16(%r30),%r29		/* Reference param save area */#endif	ldil	L%intr_check_sig, %r2	b	schedule	ldo	R%intr_check_sig(%r2), %r2	.import do_signal,codeintr_do_signal:	/* Only do signals if we are returning to user space */	LDREG	PT_IASQ0(%r16), %r20	CMPIB= 0,%r20,intr_restore /* backward */	nop	LDREG	PT_IASQ1(%r16), %r20	CMPIB= 0,%r20,intr_restore /* backward */	nop	copy	%r0, %r24			/* unsigned long in_syscall */	copy	%r16, %r25			/* struct pt_regs *regs */#ifdef __LP64__	ldo	-16(%r30),%r29			/* Reference param save area */#endif	bl	do_signal,%r2	copy	%r0, %r26			/* sigset_t *oldset = NULL */	b	intr_restore	nop	/*	 * External interrupts.	 */intr_extint:	CMPIB=,n 0,%r16,1f	get_stack_use_cr30	b,n 3f1:#if 0  /* Interrupt Stack support not working yet! */	mfctl	%cr31,%r1	copy	%r30,%r17	/* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/#ifdef __LP64__	depdi	0,63,15,%r17#else	depi	0,31,15,%r17#endif	CMPB=,n	%r1,%r17,2f	get_stack_use_cr31	b,n 3f#endif2:	get_stack_use_r303:	save_specials	%r29	virt_map	save_general	%r29	ldo	PT_FR0(%r29), %r24	save_fp	%r24		loadgp	copy	%r29, %r26	/* arg0 is pt_regs */	copy	%r29, %r16	/* save pt_regs */	ldil	L%intr_return, %r2#ifdef __LP64__	ldo	-16(%r30),%r29	/* Reference param save area */#endif	b	do_cpu_irq_mask	ldo	R%intr_return(%r2), %r2	/* return to intr_return, not here */	/* Generic interruptions (illegal insn, unaligned, page fault, etc) */	.export         intr_save, code /* for os_hpmc */intr_save:	mfsp    %sr7,%r16	CMPIB=,n 0,%r16,1f	get_stack_use_cr30	b	2f	copy    %r8,%r261:	get_stack_use_r30	copy    %r8,%r262:	save_specials	%r29	/* If this trap is a itlb miss, skip saving/adjusting isr/ior */	/*	 * FIXME: 1) Use a #define for the hardwired "6" below (and in	 *           traps.c.	 *        2) Once we start executing code above 4 Gb, we need	 *           to adjust iasq/iaoq here in the same way we	 *           adjust isr/ior below.	 */	CMPIB=,n        6,%r26,skip_save_ior	/* save_specials left ipsw value in r8 for us to test */	mfctl           %cr20, %r16 /* isr */	mfctl           %cr21, %r17 /* ior */#ifdef __LP64__	/*	 * If the interrupted code was running with W bit off (32 bit),	 * clear the b bits (bits 0 & 1) in the ior.	 */	extrd,u,*<>     %r8,PSW_W_BIT,1,%r0	depdi           0,1,2,%r17	/*	 * FIXME: This code has hardwired assumptions about the split	 *        between space bits and offset bits. This will change	 *        when we allow alternate page sizes.	 */	/* adjust isr/ior. */	extrd,u         %r16,63,7,%r1    /* get high bits from isr for ior */	depd            %r1,31,7,%r17    /* deposit them into ior */	depdi           0,63,7,%r16      /* clear them from isr */#endif	STREG           %r16, PT_ISR(%r29)	STREG           %r17, PT_IOR(%r29)skip_save_ior:	virt_map	save_general	%r29	ldo		PT_FR0(%r29), %r25	save_fp		%r25		loadgp	copy		%r29, %r25	/* arg1 is pt_regs */#ifdef __LP64__	ldo		-16(%r30),%r29	/* Reference param save area */#endif	ldil		L%intr_check_sig, %r2	copy		%r25, %r16	/* save pt_regs */	b		handle_interruption

⌨️ 快捷键说明

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