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

📄 entry.s

📁 linux-2.6.15.6
💻 S
📖 第 1 页 / 共 4 页
字号:
	ld.q	SP, FRAME_R(52), r52	ld.q	SP, FRAME_R(53), r53	ld.q	SP, FRAME_R(54), r54	ld.q	SP, FRAME_R(55), r55	ld.q	SP, FRAME_R(56), r56	ld.q	SP, FRAME_R(57), r57	ld.q	SP, FRAME_R(58), r58	getcon	SR, r59	movi	SR_BLOCK_EXC, r60	or	r59, r60, r59	putcon	r59, SR			/* SR.BL = 1, keep nesting out */	ld.q	SP, FRAME_S(FSSR), r61	ld.q	SP, FRAME_S(FSPC), r62	movi	SR_ASID_MASK, r60	and	r59, r60, r59	andc	r61, r60, r61		/* Clear out older ASID */	or	r59, r61, r61		/* Retain current ASID */	putcon	r61, SSR	putcon	r62, SPC	/* Ignore FSYSCALL_ID */	ld.q	SP, FRAME_R(59), r59	ld.q	SP, FRAME_R(60), r60	ld.q	SP, FRAME_R(61), r61	ld.q	SP, FRAME_R(62), r62	/* Last touch */	ld.q	SP, FRAME_R(15), SP	rte	nop/* * Third level handlers for VBR-based exceptions. Adapting args to * and/or deflecting to fourth level handlers. * * Fourth level handlers interface. * Most are C-coded handlers directly pointed by the trap_jtable. * (Third = Fourth level) * Inputs: * (r2)   fault/interrupt code, entry number (e.g. NMI = 14, *	  IRL0-3 (0000) = 16, RTLBMISS = 2, SYSCALL = 11, etc ...) * (r3)   struct pt_regs *, original register's frame pointer * (r4)   Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault) * (r5)   TRA control register (for syscall/debug benefit only) * (LINK) return address * (SP)   = r3 * * Kernel TLB fault handlers will get a slightly different interface. * (r2)   struct pt_regs *, original register's frame pointer * (r3)   writeaccess, whether it's a store fault as opposed to load fault * (r4)   execaccess, whether it's a ITLB fault as opposed to DTLB fault * (r5)   Effective Address of fault * (LINK) return address * (SP)   = r2 * * fpu_error_or_IRQ? is a helper to deflect to the right cause. * */tlb_miss_load:	or	SP, ZERO, r2	or	ZERO, ZERO, r3		/* Read */	or	ZERO, ZERO, r4		/* Data */	getcon	TEA, r5	pta	call_do_page_fault, tr0	beq	ZERO, ZERO, tr0tlb_miss_store:	or	SP, ZERO, r2	movi	1, r3			/* Write */	or	ZERO, ZERO, r4		/* Data */	getcon	TEA, r5	pta	call_do_page_fault, tr0	beq	ZERO, ZERO, tr0itlb_miss_or_IRQ:	pta	its_IRQ, tr0	beqi/u	r4, EVENT_INTERRUPT, tr0	or	SP, ZERO, r2	or	ZERO, ZERO, r3		/* Read */	movi	1, r4			/* Text */	getcon	TEA, r5	/* Fall through */call_do_page_fault:	movi	do_page_fault, r6        ptabs	r6, tr0        blink	tr0, ZEROfpu_error_or_IRQA:	pta	its_IRQ, tr0	beqi/l	r4, EVENT_INTERRUPT, tr0#ifdef CONFIG_SH_FPU	movi	do_fpu_state_restore, r6#else	movi	do_exception_error, r6#endif	ptabs	r6, tr0	blink	tr0, ZEROfpu_error_or_IRQB:	pta	its_IRQ, tr0	beqi/l	r4, EVENT_INTERRUPT, tr0#ifdef CONFIG_SH_FPU	movi	do_fpu_state_restore, r6#else	movi	do_exception_error, r6#endif	ptabs	r6, tr0	blink	tr0, ZEROits_IRQ:	movi	do_IRQ, r6	ptabs	r6, tr0	blink	tr0, ZERO/* * system_call/unknown_trap third level handler: * * Inputs: * (r2)   fault/interrupt code, entry number (TRAP = 11) * (r3)   struct pt_regs *, original register's frame pointer * (r4)   Not used. Event (0=interrupt, 1=TLB miss fault, 2=Not TLB miss fault) * (r5)   TRA Control Reg (0x00xyzzzz: x=1 SYSCALL, y = #args, z=nr) * (SP)   = r3 * (LINK) return address: ret_from_exception * (*r3)  Syscall parms: SC#, arg0, arg1, ..., arg5 in order (Saved r2/r7) * * Outputs: * (*r3)  Syscall reply (Saved r2) * (LINK) In case of syscall only it can be scrapped. *        Common second level post handler will be ret_from_syscall. *        Common (non-trace) exit point to that is syscall_ret (saving *        result to r2). Common bad exit point is syscall_bad (returning *        ENOSYS then saved to r2). * */unknown_trap:	/* Unknown Trap or User Trace */	movi	do_unknown_trapa, r6	ptabs	r6, tr0        ld.q    r3, FRAME_R(9), r2	/* r2 = #arg << 16 | syscall # */        andi    r2, 0x1ff, r2		/* r2 = syscall # */	blink	tr0, LINK	pta	syscall_ret, tr0	blink	tr0, ZERO        /* New syscall implementation*/system_call:	pta	unknown_trap, tr0        or      r5, ZERO, r4            /* TRA (=r5) -> r4 */        shlri   r4, 20, r4	bnei	r4, 1, tr0		/* unknown_trap if not 0x1yzzzz */        /* It's a system call */	st.q    r3, FRAME_S(FSYSCALL_ID), r5 	/* ID (0x1yzzzz) -> stack */	andi    r5, 0x1ff, r5			/* syscall # -> r5	  */	STI()	pta	syscall_allowed, tr0	movi	NR_syscalls - 1, r4	/* Last valid */	bgeu/l	r4, r5, tr0syscall_bad:	/* Return ENOSYS ! */	movi	-(ENOSYS), r2		/* Fall-through */	.global syscall_retsyscall_ret:	st.q	SP, FRAME_R(9), r2	/* Expecting SP back to BASIC frame */#ifdef CONFIG_POOR_MANS_STRACE	/* nothing useful in registers at this point */	movi	evt_debug2, r5	ori	r5, 1, r5	ptabs	r5, tr0	ld.q	SP, FRAME_R(9), r2	or	SP, ZERO, r3	blink	tr0, LINK#endif	ld.q	SP, FRAME_S(FSPC), r2	addi	r2, 4, r2		/* Move PC, being pre-execution event */	st.q	SP, FRAME_S(FSPC), r2	pta	ret_from_syscall, tr0	blink	tr0, ZERO/*  A different return path for ret_from_fork, because we now need *  to call schedule_tail with the later kernels. Because prev is *  loaded into r2 by switch_to() means we can just call it straight  away */.global	ret_from_forkret_from_fork:	movi	schedule_tail,r5	ori	r5, 1, r5	ptabs	r5, tr0	blink	tr0, LINK#ifdef CONFIG_POOR_MANS_STRACE	/* nothing useful in registers at this point */	movi	evt_debug2, r5	ori	r5, 1, r5	ptabs	r5, tr0	ld.q	SP, FRAME_R(9), r2	or	SP, ZERO, r3	blink	tr0, LINK#endif	ld.q	SP, FRAME_S(FSPC), r2	addi	r2, 4, r2		/* Move PC, being pre-execution event */	st.q	SP, FRAME_S(FSPC), r2	pta	ret_from_syscall, tr0	blink	tr0, ZEROsyscall_allowed:	/* Use LINK to deflect the exit point, default is syscall_ret */	pta	syscall_ret, tr0	gettr	tr0, LINK	pta	syscall_notrace, tr0	getcon	KCR0, r2	ld.l	r2, TI_FLAGS, r4	movi	(1 << TIF_SYSCALL_TRACE), r6	and	r6, r4, r6	beq/l	r6, ZERO, tr0	/* Trace it by calling syscall_trace before and after */	movi	syscall_trace, r4	ptabs	r4, tr0	blink	tr0, LINK	/* Reload syscall number as r5 is trashed by syscall_trace */	ld.q	SP, FRAME_S(FSYSCALL_ID), r5	andi	r5, 0x1ff, r5	pta	syscall_ret_trace, tr0	gettr	tr0, LINKsyscall_notrace:	/* Now point to the appropriate 4th level syscall handler */	movi	sys_call_table, r4	shlli	r5, 2, r5	ldx.l	r4, r5, r5	ptabs	r5, tr0	/* Prepare original args */	ld.q	SP, FRAME_R(2), r2	ld.q	SP, FRAME_R(3), r3	ld.q	SP, FRAME_R(4), r4	ld.q	SP, FRAME_R(5), r5	ld.q	SP, FRAME_R(6), r6	ld.q	SP, FRAME_R(7), r7	/* And now the trick for those syscalls requiring regs * ! */	or	SP, ZERO, r8	/* Call it */	blink	tr0, ZERO	/* LINK is already properly set */syscall_ret_trace:	/* We get back here only if under trace */	st.q	SP, FRAME_R(9), r2	/* Save return value */	movi	syscall_trace, LINK	ptabs	LINK, tr0	blink	tr0, LINK	/* This needs to be done after any syscall tracing */	ld.q	SP, FRAME_S(FSPC), r2	addi	r2, 4, r2	/* Move PC, being pre-execution event */	st.q	SP, FRAME_S(FSPC), r2	pta	ret_from_syscall, tr0	blink	tr0, ZERO		/* Resume normal return sequence *//* * --- Switch to running under a particular ASID and return the previous ASID value * --- The caller is assumed to have done a cli before calling this. * * Input r2 : new ASID * Output r2 : old ASID */	.global switch_and_save_asidswitch_and_save_asid:	getcon	sr, r0	movi	255, r4	shlli 	r4, 16, r4	/* r4 = mask to select ASID */	and	r0, r4, r3	/* r3 = shifted old ASID */	andi	r2, 255, r2	/* mask down new ASID */	shlli	r2, 16, r2	/* align new ASID against SR.ASID */	andc	r0, r4, r0	/* efface old ASID from SR */	or	r0, r2, r0	/* insert the new ASID */	putcon	r0, ssr	movi	1f, r0	putcon	r0, spc	rte	nop1:	ptabs	LINK, tr0	shlri	r3, 16, r2	/* r2 = old ASID */	blink tr0, r63	.global	route_to_panic_handlerroute_to_panic_handler:	/* Switch to real mode, goto panic_handler, don't return.  Useful for	   last-chance debugging, e.g. if no output wants to go to the console.	   */	movi	panic_handler - CONFIG_CACHED_MEMORY_OFFSET, r1	ptabs	r1, tr0	pta	1f, tr1	gettr	tr1, r0	putcon	r0, spc	getcon	sr, r0	movi	1, r1	shlli	r1, 31, r1	andc	r0, r1, r0	putcon	r0, ssr	rte	nop1:	/* Now in real mode */	blink tr0, r63	nop	.global peek_real_address_qpeek_real_address_q:	/* Two args:	   r2 : real mode address to peek	   r2(out) : result quadword	   This is provided as a cheapskate way of manipulating device	   registers for debugging (to avoid the need to onchip_remap the debug	   module, and to avoid the need to onchip_remap the watchpoint	   controller in a way that identity maps sufficient bits to avoid the	   SH5-101 cut2 silicon defect).	   This code is not performance critical	*/	add.l	r2, r63, r2	/* sign extend address */	getcon	sr, r0		/* r0 = saved original SR */	movi	1, r1	shlli	r1, 28, r1	or	r0, r1, r1	/* r0 with block bit set */	putcon	r1, sr		/* now in critical section */	movi	1, r36	shlli	r36, 31, r36	andc	r1, r36, r1	/* turn sr.mmu off in real mode section */	putcon	r1, ssr	movi	.peek0 - CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */	movi	1f, r37		/* virtual mode return addr */	putcon	r36, spc	synco	rte	nop.peek0:	/* come here in real mode, don't touch caches!!           still in critical section (sr.bl==1) */	putcon	r0, ssr	putcon	r37, spc	/* Here's the actual peek.  If the address is bad, all bets are now off	 * what will happen (handlers invoked in real-mode = bad news) */	ld.q	r2, 0, r2	synco	rte	/* Back to virtual mode */	nop1:	ptabs	LINK, tr0	blink	tr0, r63	.global poke_real_address_qpoke_real_address_q:	/* Two args:	   r2 : real mode address to poke	   r3 : quadword value to write.	   This is provided as a cheapskate way of manipulating device	   registers for debugging (to avoid the need to onchip_remap the debug	   module, and to avoid the need to onchip_remap the watchpoint	   controller in a way that identity maps sufficient bits to avoid the	   SH5-101 cut2 silicon defect).	   This code is not performance critical	*/	add.l	r2, r63, r2	/* sign extend address */	getcon	sr, r0		/* r0 = saved original SR */	movi	1, r1	shlli	r1, 28, r1	or	r0, r1, r1	/* r0 with block bit set */	putcon	r1, sr		/* now in critical section */	movi	1, r36	shlli	r36, 31, r36	andc	r1, r36, r1	/* turn sr.mmu off in real mode section */	putcon	r1, ssr	movi	.poke0-CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */	movi	1f, r37		/* virtual mode return addr */	putcon	r36, spc	synco	rte	nop.poke0:	/* come here in real mode, don't touch caches!!           still in critical section (sr.bl==1) */	putcon	r0, ssr	putcon	r37, spc	/* Here's the actual poke.  If the address is bad, all bets are now off	 * what will happen (handlers invoked in real-mode = bad news) */	st.q	r2, 0, r3	synco	rte	/* Back to virtual mode */	nop1:	ptabs	LINK, tr0	blink	tr0, r63/* * --- User Access Handling Section *//* * User Access support. It all moved to non inlined Assembler * functions in here. * * __kernel_size_t __copy_user(void *__to, const void *__from, *			       __kernel_size_t __n) * * Inputs: * (r2)  target address * (r3)  source address * (r4)  size in bytes * * Ouputs: * (*r2) target data * (r2)  non-copied bytes * * If a fault occurs on the user pointer, bail out early and return the * number of bytes not copied in r2. * Strategy : for large blocks, call a real memcpy function which can * move >1 byte at a time using unaligned ld/st instructions, and can * manipulate the cache using prefetch + alloco to improve the speed * further.  If a fault occurs in that function, just revert to the * byte-by-byte approach used for small blocks; this is rare so the * performance hit for that case does not matter. * * For small blocks it's not worth the overhead of setting up and calling * the memcpy routine; do the copy a byte at a time. * */	.global	__copy_user__copy_user:	pta	__copy_user_byte_by_byte, tr1	movi	16, r0 ! this value is a best guess, should tune it by benchmarking	bge/u	r0, r4, tr1	pta copy_user_memcpy, tr0	addi	SP, -32, SP	/* Save arguments in case we have to fix-up unhandled page fault */	st.q	SP, 0, r2	st.q	SP, 8, r3	st.q	SP, 16, r4	st.q	SP, 24, r35 ! r35 is callee-save	/* Save LINK in a register to reduce RTS time later (otherwise	   ld SP,*,LINK;ptabs LINK;trn;blink trn,r63 becomes a critical path) */	ori	LINK, 0, r35	blink	tr0, LINK	/* Copy completed normally if we get back here */	ptabs	r35, tr0	ld.q	SP, 24, r35	/* don't restore r2-r4, pointless */	/* set result=r2 to zero as the copy must have succeeded. */	or	r63, r63, r2	addi	SP, 32, SP	blink	tr0, r63 ! RTS	.global __copy_user_fixup__copy_user_fixup:	/* Restore stack frame */	ori	r35, 0, LINK	ld.q	SP, 24, r35	ld.q	SP, 16, r4	ld.q	SP,  8, r3	ld.q	SP,  0, r2	addi	SP, 32, SP	/* Fall through to original code, in the 'same' state we entered with *//* The slow byte-by-byte method is used if the fast copy traps due to a bad   user address.  In that rare case, the speed drop can be tolerated. */__copy_user_byte_by_byte:	pta	___copy_user_exit, tr1	pta	___copy_user1, tr0	beq/u	r4, r63, tr1	/* early exit for zero length copy */	sub	r2, r3, r0	addi	r0, -1, r0___copy_user1:	ld.b	r3, 0, r5		/* Fault address 1 */	/* Could rewrite this to use just 1 add, but the second comes 'free'	   due to load latency */	addi	r3, 1, r3	addi	r4, -1, r4		/* No real fixup required */___copy_user2:	stx.b	r3, r0, r5		/* Fault address 2 */	bne     r4, ZERO, tr0___copy_user_exit:	or	r4, ZERO, r2	ptabs	LINK, tr0

⌨️ 快捷键说明

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