head_4xx.s

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

S
1,123
字号
/* 0x0500 - External Interrupt Exception*/	START_EXCEPTION(0x0500, HardwareInterrupt)	STND_EXCEPTION_PROLOG	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r7,STND_EXC	li	r20,MSR_KERNEL	li	r4,0	bl	transfer_to_handler_GLOBAL(do_IRQ_intercept)	.long	do_IRQ	.long	ret_from_intercept/* 0x0600 - Alignment Exception*/	START_EXCEPTION(0x0600, Alignment)	STND_EXCEPTION_PROLOG	mfspr	r4,SPRN_DEAR		/* Grab the DEAR and save it */	stw	r4,_DEAR(r21)	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r7,STND_EXC	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* Copy EE bit from the saved MSR */	FINISH_EXCEPTION(AlignmentException)/* 0x0700 - Program Exception*/	START_EXCEPTION(0x0700,	ProgramCheck)	STND_EXCEPTION_PROLOG	mfspr	r4,SPRN_ESR		/* Grab the ESR, save it */	stw	r4,_ESR(r21)	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r7,STND_EXC	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* Copy EE bit from the saved MSR */	FINISH_EXCEPTION(ProgramCheckException)/* I'm stealing this unused vector location to build a standard exception * frame for Data TLB Access errors.  The other Data TLB exceptions will bail * out to this point if they can't resolve the lightweight TLB fault. */	START_EXCEPTION(0x0800,	DataAccess)	STND_EXCEPTION_PROLOG	mfspr	r5,SPRN_ESR		/* Grab the ESR, save it, pass arg3 */	stw	r5,_ESR(r21)	mfspr	r4,SPRN_DEAR		/* Grab the DEAR, save it, pass arg2 */	stw	r4,_DEAR(r21)	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r7,STND_EXC	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* Copy EE bit from the saved MSR */	FINISH_EXCEPTION(do_page_fault)	/* do_page_fault(regs, ESR, DEAR) */	STND_EXCEPTION(0x0900,	Trap_09,		UnknownException)	STND_EXCEPTION(0x0A00,	Trap_0A,		UnknownException)	STND_EXCEPTION(0x0B00,	Trap_0B,		UnknownException)/* 0x0C00 - System Call Exception*/	START_EXCEPTION(0x0C00,	SystemCall)	STND_EXCEPTION_PROLOG	stw	r3,ORIG_GPR3(r21)	li	r7,STND_EXC	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* Copy EE bit from the saved MSR */	FINISH_EXCEPTION(DoSyscall)	STND_EXCEPTION(0x0D00,	Trap_0D,		UnknownException)	STND_EXCEPTION(0x0E00,	Trap_0E,		UnknownException)	STND_EXCEPTION(0x0F00,	Trap_0F,		UnknownException)/* 0x1000 - Programmable Interval Timer (PIT) Exception*/	START_EXCEPTION(0x1000,	Decrementer)	STND_EXCEPTION_PROLOG	lis	r0,TSR_PIS@h		/* Set-up the PIT exception mask */	mtspr	SPRN_TSR,r0		/* Clear the PIT exception */	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r7,STND_EXC	li	r20,MSR_KERNEL	bl	transfer_to_handler_GLOBAL(timer_interrupt_intercept)	.long	timer_interrupt	.long	ret_from_intercept#if 0/* NOTE: * FIT and WDT handlers are not implemented yet. *//* 0x1010 - Fixed Interval Timer (FIT) Exception*/	STND_EXCEPTION(0x1010,	FITException,		UnknownException)/* 0x1020 - Watchdog Timer (WDT) Exception*/	CRIT_EXCEPTION(0x1020,	WDTException,		UnknownException)#endif/* 0x1100 - Data TLB Miss Exception * As the name implies, translation is not in the MMU, so search the * page tables and fix it.  The only purpose of this function is to * load TLB entries from the page table if they exist. */	START_EXCEPTION(0x1100,	DTLBMiss)	mtspr	SPRG0, r20		/* Save some working registers */	mtspr	SPRG1, r21#ifdef CONFIG_403GCX	stw     r22, 0(r0)	stw     r23, 4(r0)	mfcr    r21	mfspr   r22, SPRN_PID	stw     r21, 8(r0)	stw     r22, 12(r0)#else	mtspr	SPRG4, r22	mtspr	SPRG5, r23	mfcr	r21	mfspr	r22, SPRN_PID	mtspr	SPRG7, r21	mtspr	SPRG6, r22#endif	mfspr	r20, SPRN_DEAR		/* Get faulting address */	/* If we are faulting a kernel address, we have to use the	 * kernel page tables.	 */	andis.	r21, r20, 0x8000	beq	3f	lis	r21, swapper_pg_dir@h	ori	r21, r21, swapper_pg_dir@l	li	r23, 0	mtspr	SPRN_PID, r23		/* TLB will have 0 TID */	b	4f	/* Get the PGD for the current thread.	 */3:	mfspr	r21,SPRG3	lwz	r21,PGDIR(r21)4:	tophys(r21, r21)	rlwimi	r21, r20, 12, 20, 29	/* Create L1 (pgdir/pmd) address */	lwz	r21, 0(r21)		/* Get L1 entry */	rlwinm.	r22, r21, 0, 0, 19	/* Extract L2 (pte) base address */	beq	2f			/* Bail if no table */	tophys(r22, r22)	rlwimi	r22, r20, 22, 20, 29	/* Compute PTE address */	lwz	r21, 0(r22)		/* Get Linux PTE */	andi.	r23, r21, _PAGE_PRESENT	beq	2f	ori	r21, r21, _PAGE_ACCESSED	stw	r21, 0(r22)	/* Most of the Linux PTE is ready to load into the TLB LO.	 * We set ZSEL, where only the LS-bit determines user access.	 * We set execute, because we don't have the granularity to	 * properly set this at the page level (Linux problem).	 * If shared is set, we cause a zero PID->TID load.	 * Many of these bits are software only.  Bits we don't set	 * here we (properly should) assume have the appropriate value.	 */	li	r22, 0x0ce2	andc	r21, r21, r22		/* Make sure 20, 21 are zero */	b	finish_tlb_load2:	/* The bailout.  Restore registers to pre-exception conditions	 * and call the heavyweights to help us out.	 */#ifdef CONFIG_403GCX	lwz     r22, 12(r0)	lwz     r21, 8(r0)	mtspr   SPRN_PID, r22	mtcr    r21	lwz     r23, 4(r0)	lwz     r22, 0(r0)#else	mfspr	r22, SPRG6	mfspr	r21, SPRG7	mtspr	SPRN_PID, r22	mtcr	r21	mfspr	r23, SPRG5	mfspr	r22, SPRG4#endif	mfspr	r21, SPRG1	mfspr	r20, SPRG0	b	DataAccess/* 0x1200 - Instruction TLB Miss Exception * Nearly the same as above, except we get our information from different * registers and bailout to a different point. */	START_EXCEPTION(0x1200,	ITLBMiss)	mtspr	SPRG0, r20		/* Save some working registers */	mtspr	SPRG1, r21#ifdef CONFIG_403GCX	stw     r22, 0(r0)	stw     r23, 4(r0)	mfcr    r21	mfspr   r22, SPRN_PID	stw     r21, 8(r0)	stw     r22, 12(r0)#else	mtspr	SPRG4, r22	mtspr	SPRG5, r23	mfcr	r21	mfspr	r22, SPRN_PID	mtspr	SPRG7, r21	mtspr	SPRG6, r22#endif	mfspr	r20, SRR0		/* Get faulting address */	/* If we are faulting a kernel address, we have to use the	 * kernel page tables.	 */	andis.	r21, r20, 0x8000	beq	3f	lis	r21, swapper_pg_dir@h	ori	r21, r21, swapper_pg_dir@l	li	r23, 0	mtspr	SPRN_PID, r23		/* TLB will have 0 TID */	b	4f	/* Get the PGD for the current thread.	 */3:	mfspr	r21,SPRG3	lwz	r21,PGDIR(r21)4:	tophys(r21, r21)	rlwimi	r21, r20, 12, 20, 29	/* Create L1 (pgdir/pmd) address */	lwz	r21, 0(r21)		/* Get L1 entry */	rlwinm.	r22, r21, 0, 0, 19	/* Extract L2 (pte) base address */	beq	2f			/* Bail if no table */	tophys(r22, r22)	rlwimi	r22, r20, 22, 20, 29	/* Compute PTE address */	lwz	r21, 0(r22)		/* Get Linux PTE */	andi.	r23, r21, _PAGE_PRESENT	beq	2f	ori	r21, r21, _PAGE_ACCESSED	stw	r21, 0(r22)	/* Most of the Linux PTE is ready to load into the TLB LO.	 * We set ZSEL, where only the LS-bit determines user access.	 * We set execute, because we don't have the granularity to	 * properly set this at the page level (Linux problem).	 * If shared is set, we cause a zero PID->TID load.	 * Many of these bits are software only.  Bits we don't set	 * here we (properly should) assume have the appropriate value.	 */	li	r22, 0x0ce2	andc	r21, r21, r22		/* Make sure 20, 21 are zero */	b	finish_tlb_load2:	/* The bailout.  Restore registers to pre-exception conditions	 * and call the heavyweights to help us out.	 */#ifdef CONFIG_403GCX	lwz     r22, 12(r0)	lwz     r21, 8(r0)	mtspr   SPRN_PID, r22	mtcr    r21	lwz     r23, 4(r0)	lwz     r22, 0(r0)#else	mfspr	r22, SPRG6	mfspr	r21, SPRG7	mtspr	SPRN_PID, r22	mtcr	r21	mfspr	r23, SPRG5	mfspr	r22, SPRG4#endif	mfspr	r21, SPRG1	mfspr	r20, SPRG0	b	InstructionAccess	STND_EXCEPTION(0x1300,	Trap_13,		UnknownException)	STND_EXCEPTION(0x1400,	Trap_14,		UnknownException)	STND_EXCEPTION(0x1500,	Trap_15,		UnknownException)	STND_EXCEPTION(0x1600,	Trap_16,		UnknownException)#ifdef CONFIG_IBM405_ERR51	/* 405GP errata 51 */	START_EXCEPTION(0x1700, Trap_17)	b DTLBMiss#else	STND_EXCEPTION(0x1700,	Trap_17,		UnknownException)#endif	STND_EXCEPTION(0x1800,	Trap_18,		UnknownException)	STND_EXCEPTION(0x1900,	Trap_19,		UnknownException)	STND_EXCEPTION(0x1A00,	Trap_1A,		UnknownException)	STND_EXCEPTION(0x1B00,	Trap_1B,		UnknownException)	STND_EXCEPTION(0x1C00,	Trap_1C,		UnknownException)	STND_EXCEPTION(0x1D00,	Trap_1D,		UnknownException)	STND_EXCEPTION(0x1E00,	Trap_1E,		UnknownException)	STND_EXCEPTION(0x1F00,	Trap_1F,		UnknownException)/* 0x2000 - Debug Exception*/	START_EXCEPTION(0x2000, DebugTrap)	b	check_single_step_in_exceptionret_to_debug_exception:	CRIT_EXCEPTION_PROLOG	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r7,CRIT_EXC;        li      r20,MSR_KERNEL	FINISH_EXCEPTION(DebugException)/* Make sure the final interrupt handler has not spilled past the * end of its allotted space. */        .=0x2100/* Check for a single step debug exception while in an exception * handler before state has been saved.  This is to catch the case * where an instruction that we are trying to single step causes * an exception (eg ITLB miss) and thus the first instruction of * the exception handler generates a single step debug exception. * * If we get a debug trap on the first instruction of an exception handler, * we reset the MSR_DE in the _exception handlers_ MSR (the debug trap is * a critical exception, so we are using SPRN_SRR3 to manipulate the MSR). * The exception handler was handling a non-critical interrupt, so it will * save (and later restore) the MSR via SPRN_SRR1, which will still have * the MSR_DE bit set. */check_single_step_in_exception:	/* This first instruction was already executed by the exception	 * handler and must be the first instruction of every exception	 * handler.	 */	mtspr	SPRN_SPRG0,r20		/* Save some working registers... */	mtspr	SPRN_SPRG1,r21	mfcr	r20			/* ..and the cr because we change it */	mfspr   r21,SPRN_SRR3		/* MSR at the time of fault */	andi.   r21,r21,MSR_PR	bne+    2f			/* trapped from problem state */	mfspr   r21,SPRN_SRR2		/* Faulting instruction address */	cmplwi  r21,0x2100	bgt+    2f			/* address above exception vectors */	lis     r21,DBSR_IC@h           /* Remove the trap status */	mtspr   SPRN_DBSR,r21	mfspr	r21,SPRN_SRR3	rlwinm	r21,r21,0,23,21		/* clear MSR_DE */	mtspr	SPRN_SRR3, r21		/* restore MSR at rcfi without DE */	mtcrf   0xff,r20                /* restore registers */	mfspr   r21,SPRN_SPRG1	mfspr   r20,SPRN_SPRG0	sync	rfci                            /* return to the exception handler  */	b	.			/* prevent prefetch past rfci */2:	mtcrf   0xff,r20                /* restore registers */	mfspr   r21,SPRN_SPRG1	mfspr   r20,SPRN_SPRG0	b       ret_to_debug_exception

⌨️ 快捷键说明

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