entry.s

来自「linux-2.4.29操作系统的源码」· S 代码 · 共 2,106 行 · 第 1/4 页

S
2,106
字号
	getcon	KCR1, SP	_ptar	handle_exception, t0	blink	t0, ZERO	/*	 * Instead of the natural .balign 1024 place RESVEC here	 * respecting the final 1KB alignment.	 */	.balign TEXT_SIZE	/*	 * Instead of '.space 1024-TEXT_SIZE' place the RESVEC	 * block making sure the final alignment is correct.	 */LRESVEC_block:	/* Panic handler. Called with MMU off. Possible causes/actions:	 * - Reset:		Jump to program start.	 * - Single Step:	Turn off Single Step & return.	 * - Others:		Call panic handler, passing PC as arg.	 *			(this may need to be extended...)	 */reset_or_panic:	putcon	SP, DCR	/* First save r0-1 and tr0, as we need to use these */	_loada	resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP	st.q	SP, 0, r0	st.q	SP, 8, r1	gettr	t0, r0	st.q	SP, 32, r0		/* Check cause */	getcon	EXPEVT, r0	movi	RESET_CAUSE, r1	sub	r1, r0, r1		/* r1=0 if reset */	_loada	_stext-CONFIG_CACHED_MEMORY_OFFSET, r0	ori	r0, 1, r0	ptabs	r0, t0	beqi	r1, 0, t0		/* Jump to start address if reset */	getcon	EXPEVT, r0	movi	DEBUGSS_CAUSE, r1	sub	r1, r0, r1		/* r1=0 if single step */	_ptar	single_step_panic, t0	beqi	r1, 0, t0		/* jump if single step */	/* If we get here, we have an unknown panic. Just call the panic	 * handler, passing saved PC. We never expect to return, so we can	 * use any regs now. */	getcon	SPC,r2	getcon	SSR,r3	getcon	EXPEVT,r4	/* Prepare to jump to C - physical address */	_loada	panic_handler-CONFIG_CACHED_MEMORY_OFFSET, r1	ori	r1, 1, r1	ptabs   r1, t0	getcon	DCR, SP	blink	t0, ZEROsingle_step_panic:	/* We are in a handler with Single Step set. We need to resume the	 * handler, by turning on MMU & turning off Single Step. */	getcon	SSR, r0	movi	SR_MMU, r1	or	r0, r1, r0	movi	~SR_SS, r1	and	r0, r1, r0	putcon	r0, SSR	/* Restore EXPEVT, as the rte won't do this */	getcon	PEXPEVT, r0	putcon	r0, EXPEVT	/* Restore regs */	ld.q	SP, 32, r0	ptabs	r0, tr0	ld.q	SP, 0, r0	ld.q	SP, 8, r1	getcon	DCR, SP	synco	rte	.balign	TEXT_SIZEdebug_exception:	/*	 * Single step/software_break_point first level handler.	 * Called with MMU off, so the first thing we do is enable it	 * by doing an rte with appropriate SSR.	 */	putcon	SP, DCR	/* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */	_loada	resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP	/* With the MMU off, we are bypassing the cache, so purge any          * data that will be made stale by the following stores.         */	ocbp	SP, 0	synco	st.q	SP, 0, r0	st.q	SP, 8, r1	getcon	SPC, r0	st.q	SP, 16, r0	getcon	SSR, r0	st.q	SP, 24, r0	/* Enable MMU, block exceptions, set priv mode, disable single step */	movi	SR_MMU | SR_BL | SR_MD, r1	or	r0, r1, r0	movi	~SR_SS, r1	and	r0, r1, r0	putcon	r0, SSR	/* Force control to debug_exception_2 when rte is executed */	_loada	debug_exeception_2, r0	ori	r0, 1, r0      /* force SHmedia, just in case */	putcon	r0, SPC	getcon	DCR, SP	synco	rtedebug_exeception_2:	/* Restore saved regs */	putcon	SP, KCR1	_loada	resvec_save_area, SP	ld.q	SP, 24, r0	putcon	r0, SSR	ld.q	SP, 16, r0	putcon	r0, SPC	ld.q	SP, 0, r0	ld.q	SP, 8, r1	/* Save other original registers into reg_save_area */        _loada  reg_save_area, SP	st.q	SP, SAVED_R2, r2	st.q	SP, SAVED_R3, r3	st.q	SP, SAVED_R4, r4	st.q	SP, SAVED_R5, r5	st.q	SP, SAVED_R6, r6	st.q	SP, SAVED_R18, r18	gettr	t0, r3	st.q	SP, SAVED_T0, r3	/* Set args for debug class handler */	getcon	EXPEVT, r2	_loada	ret_from_exception, r3	ori	r3, 1, r3	movi	EVENT_DEBUG, r4	or	SP, ZERO, r5	getcon	KCR1, SP	_ptar	handle_exception, t0	blink	t0, ZERO	.balign	TEXT_SIZEdebug_interrupt:	/*	 * Not supported. If we ever get here loop forever	 * We may be MMUOFF or MMUON. Just use pic code.	 */	_ptar	debug_interrupt, t0	blink	t0, ZERO	.balign	TEXT_SIZELRESVEC_block_end:			/* Marker. Unused. */tlb_miss:	putcon	SP, KCR1	_loada	reg_save_area, SP	/* SP is guaranteed 32-byte aligned. */	st.q	SP, TLB_SAVED_R0 , r0	st.q	SP, TLB_SAVED_R1 , r1	st.q	SP, SAVED_R2 , r2	st.q	SP, SAVED_R3 , r3	st.q	SP, SAVED_R4 , r4	st.q	SP, SAVED_R5 , r5	st.q	SP, SAVED_R6 , r6	st.q	SP, SAVED_R18, r18	/* Save R25 for safety; as/ld may want to use it to achieve the call to	 * the code in mm/tlbmiss.c */	st.q	SP, TLB_SAVED_R25, r25	gettr	tr0, r2	gettr	tr1, r3	gettr	tr2, r4	gettr	tr3, r5	gettr	tr4, r18	st.q	SP, SAVED_T0 , r2	st.q	SP, TLB_SAVED_T1 , r3	st.q	SP, TLB_SAVED_T2 , r4	st.q	SP, TLB_SAVED_T3 , r5	st.q	SP, TLB_SAVED_T4 , r18	pt	do_fast_page_fault, tr0	getcon	SSR, r2	getcon	EXPEVT, r3	getcon	TEA, r4	shlri	r2, 30, r2	andi	r2, 1, r2	/* r2 = SSR.MD */	blink 	tr0, r18	pt	fixup_to_invoke_general_handler, tr1	/* If the fast path handler fixed the fault, just drop through quickly	   to the restore code right away to return to the excepting context.	   */	beqi/u	r2, 0, tr1fast_tlb_miss_restore:	ld.q	SP, SAVED_T0, r2	ld.q	SP, TLB_SAVED_T1, r3	ld.q	SP, TLB_SAVED_T2, r4	ld.q	SP, TLB_SAVED_T3, r5	ld.q	SP, TLB_SAVED_T4, r18	ptabs	r2, tr0	ptabs	r3, tr1	ptabs	r4, tr2	ptabs	r5, tr3	ptabs	r18, tr4	ld.q	SP, TLB_SAVED_R0, r0	ld.q	SP, TLB_SAVED_R1, r1	ld.q	SP, SAVED_R2, r2	ld.q	SP, SAVED_R3, r3	ld.q	SP, SAVED_R4, r4	ld.q	SP, SAVED_R5, r5	ld.q	SP, SAVED_R6, r6	ld.q	SP, SAVED_R18, r18	ld.q	SP, TLB_SAVED_R25, r25	getcon	KCR1, SP	rte	nop /* for safety, in case the code is run on sh5-101 cut1.x */fixup_to_invoke_general_handler:	/* OK, new method.  Restore stuff that's not expected to get saved into	   the 'first-level' reg save area, then just fall through to setting	   up the registers and calling the second-level handler. */	/* 2nd level expects r2,3,4,5,6,18,tr0 to be saved.  So we must restore	   r25,tr1-4 and save r6 to get into the right state.  */	ld.q	SP, TLB_SAVED_T1, r3	ld.q	SP, TLB_SAVED_T2, r4	ld.q	SP, TLB_SAVED_T3, r5	ld.q	SP, TLB_SAVED_T4, r18	ld.q	SP, TLB_SAVED_R25, r25		ld.q	SP, TLB_SAVED_R0, r0	ld.q	SP, TLB_SAVED_R1, r1	ptabs/u	r3, tr1	ptabs/u	r4, tr2	ptabs/u	r5, tr3	ptabs/u	r18, tr4#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT	/* This use of DCR is not really legal, but there's nowhere else convenient to store this and it's only for last-resort debug anyway. */	movi    0x400, r3	putcon  r3, dcr#endif	/* Set args for Non-debug, TLB miss class handler */	getcon	EXPEVT, r2	_loada	ret_from_exception, r3	ori	r3, 1, r3	movi	EVENT_FAULT_TLB, r4	or	SP, ZERO, r5	getcon	KCR1, SP	_ptar	handle_exception, t0	blink	t0, ZERO/* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE   DOES END UP AT VBR+0x600 */	nop	nop	nop	nop	nop	nop#if 0	.balign 256	nop#endif	.balign 256	/* VBR + 0x600 */interrupt:	/* Save original stack pointer into KCR1 */	putcon	SP, KCR1	/* Save other original registers into reg_save_area */        _loada  reg_save_area, SP	st.q	SP, SAVED_R2, r2	st.q	SP, SAVED_R3, r3	st.q	SP, SAVED_R4, r4	st.q	SP, SAVED_R5, r5	st.q	SP, SAVED_R6, r6	st.q	SP, SAVED_R18, r18	gettr	t0, r3	st.q	SP, SAVED_T0, r3#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT	/* This use of DCR is not really legal, but there's nowhere else convenient to store this and it's only for last-resort debug anyway. */	movi    0x600, r3	putcon  r3, dcr#endif	/* Set args for interrupt class handler */	getcon	INTEVT, r2	_loada	ret_from_irq, r3	ori	r3, 1, r3	movi	EVENT_INTERRUPT, r4	or	SP, ZERO, r5	getcon	KCR1, SP	_ptar	handle_exception, t0	blink	t0, ZERO	.balign	TEXT_SIZE		/* let's waste the bare minimum */LVBR_block_end:				/* Marker. Used for total checking */	/* * Second level handler for VBR-based exceptions. Pre-handler. * In common to all stack-frame sensitive handlers. * * Inputs: * (KCR0) Current [current task union] * (KCR1) Original SP * (r2)   INTEVT/EXPEVT * (r3)   appropriate return address * (r4)   Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault, 3=debug) * (r5)   Pointer to reg_save_area * (SP)   Original SP * * Available registers: * (r6) * (r18) * (t0) * */handle_exception:	/* Common 2nd level handler. */	/* First thing we need an appropriate stack pointer */	getcon	SSR, r6	shlri	r6, 30, r6	andi	r6, 1, r6	_ptar	stack_ok, t0	bne	r6, ZERO, t0		/* Original stack pointer is fine */	/* Set stack pointer for user fault */	getcon	KCR0, SP	movi	THREAD_SIZE, r6		/* Point to the end */	add	SP, r6, SPstack_ok:	/* Make some room for the BASIC frame. */	movi	-(FRAME_SIZE), r6	add	SP, r6, SP/* Could do this with no stalling if we had another spare register, but the   code below will be OK. */	ld.q	r5, SAVED_R2, r6	ld.q	r5, SAVED_R3, r18	st.q	SP, FRAME_R(2), r6	ld.q	r5, SAVED_R4, r6	st.q	SP, FRAME_R(3), r18	ld.q	r5, SAVED_R5, r18	st.q	SP, FRAME_R(4), r6	ld.q	r5, SAVED_R6, r6	st.q	SP, FRAME_R(5), r18	ld.q	r5, SAVED_R18, r18	st.q	SP, FRAME_R(6), r6	ld.q	r5, SAVED_T0, r6	st.q	SP, FRAME_R(18), r18	st.q	SP, FRAME_T(0), r6	/* Keep old SP around */	getcon	KCR1, r6	/* Save the rest of the general purpose registers */	st.q	SP, FRAME_R(0), r0	st.q	SP, FRAME_R(1), r1	st.q	SP, FRAME_R(7), r7	st.q	SP, FRAME_R(8), r8	st.q	SP, FRAME_R(9), r9	st.q	SP, FRAME_R(10), r10	st.q	SP, FRAME_R(11), r11	st.q	SP, FRAME_R(12), r12	st.q	SP, FRAME_R(13), r13	st.q	SP, FRAME_R(14), r14	/* SP is somewhere else */	st.q	SP, FRAME_R(15), r6	st.q	SP, FRAME_R(16), r16	st.q	SP, FRAME_R(17), r17	/* r18 is saved earlier. */	st.q	SP, FRAME_R(19), r19	st.q	SP, FRAME_R(20), r20	st.q	SP, FRAME_R(21), r21	st.q	SP, FRAME_R(22), r22	st.q	SP, FRAME_R(23), r23	st.q	SP, FRAME_R(24), r24	st.q	SP, FRAME_R(25), r25	st.q	SP, FRAME_R(26), r26	st.q	SP, FRAME_R(27), r27	st.q	SP, FRAME_R(28), r28	st.q	SP, FRAME_R(29), r29	st.q	SP, FRAME_R(30), r30	st.q	SP, FRAME_R(31), r31	st.q	SP, FRAME_R(32), r32	st.q	SP, FRAME_R(33), r33	st.q	SP, FRAME_R(34), r34	st.q	SP, FRAME_R(35), r35	st.q	SP, FRAME_R(36), r36	st.q	SP, FRAME_R(37), r37	st.q	SP, FRAME_R(38), r38	st.q	SP, FRAME_R(39), r39	st.q	SP, FRAME_R(40), r40	st.q	SP, FRAME_R(41), r41	st.q	SP, FRAME_R(42), r42	st.q	SP, FRAME_R(43), r43	st.q	SP, FRAME_R(44), r44	st.q	SP, FRAME_R(45), r45	st.q	SP, FRAME_R(46), r46	st.q	SP, FRAME_R(47), r47	st.q	SP, FRAME_R(48), r48	st.q	SP, FRAME_R(49), r49	st.q	SP, FRAME_R(50), r50	st.q	SP, FRAME_R(51), r51	st.q	SP, FRAME_R(52), r52	st.q	SP, FRAME_R(53), r53	st.q	SP, FRAME_R(54), r54	st.q	SP, FRAME_R(55), r55	st.q	SP, FRAME_R(56), r56	st.q	SP, FRAME_R(57), r57	st.q	SP, FRAME_R(58), r58	st.q	SP, FRAME_R(59), r59	st.q	SP, FRAME_R(60), r60	st.q	SP, FRAME_R(61), r61	st.q	SP, FRAME_R(62), r62	/*	 * Save the S* registers.	 */	getcon	SSR, r61	st.q	SP, FRAME_S(FSSR), r61	getcon	SPC, r62	st.q	SP, FRAME_S(FSPC), r62	movi	-1, r62			/* Reset syscall_nr */	st.q	SP, FRAME_S(FSYSCALL_ID), r62	/* Save the rest of the target registers */	gettr	t1, r6	st.q	SP, FRAME_T(1), r6	gettr	t2, r6	st.q	SP, FRAME_T(2), r6	gettr	t3, r6	st.q	SP, FRAME_T(3), r6	gettr	t4, r6	st.q	SP, FRAME_T(4), r6	gettr	t5, r6	st.q	SP, FRAME_T(5), r6	gettr	t6, r6	st.q	SP, FRAME_T(6), r6	gettr	t7, r6	st.q	SP, FRAME_T(7), r6/*#define POOR_MANS_STRACE 1*/	#ifdef POOR_MANS_STRACE	/* We've pushed all the registers now, so only r2-r4 hold anything	 * useful. Move them into callee save registers */	or	r2, ZERO, r28	or	r3, ZERO, r29	or	r4, ZERO, r30	/* Preserve r2 as the event code */	_loada	evt_debug, r3	ori	r3, 1, r3	ptabs	r3, t0	/* or	SP, ZERO, r5 */	getcon	TRA, r5	blink	t0, LINK	or	r28, ZERO, r2	or	r29, ZERO, r3	or	r30, ZERO, r4#endif		/* For syscall and debug race condition, get TRA now */	getcon	TRA, r5		/* We are in a safe position to turn SR.BL off, but set IMASK=0xf	 * Also set FD, to catch FPU usage in the kernel.	 *	 * benedict.gaster@superh.com 29/07/2002	 *	 * On all SH5-101 revisions it is unsafe to raise the IMASK and at the 	 * same time change BL from 1->0, as any pending interrupt of a level	 * higher than he previous value of IMASK will leak through and be 	 * taken unexpectedly.	 *	 * To avoid this we raise the IMASK and then issue another PUTCON to	 * enable interrupts.         */	getcon	SR, r6	movi	SR_IMASK | SR_FD, r7	or	r6, r7, r6	putcon	r6, SR	movi	SR_UNBLOCK_EXC, r7	and	r6, r7, r6	putcon	r6, SR		/* Now call the appropriate 3rd level handler */	or	r3, ZERO, LINK	_loada	trap_jtable, r3	shlri	r2, 3, r2	ldx.l	r2, r3, r3	shlri	r2, 2, r2	ptabs	r3, t0	or	SP, ZERO, r3	blink	t0, ZERO/* * Second level handler for VBR-based exceptions. Post-handlers. *

⌨️ 快捷键说明

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