head_44x.s

来自「Linux Kernel 2.6.9 for OMAP1710」· S 代码 · 共 894 行 · 第 1/2 页

S
894
字号
	EXC_XFER_EE_LITE(0x0c00, DoSyscall)	/* Auxillary Processor Unavailable Interrupt */	EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)	/* Decrementer Interrupt */	START_EXCEPTION(Decrementer)	NORMAL_EXCEPTION_PROLOG	lis     r0,TSR_DIS@h            /* Setup the DEC interrupt mask */	mtspr   SPRN_TSR,r0		/* Clear the DEC interrupt */	addi    r3,r1,STACK_FRAME_OVERHEAD	EXC_XFER_LITE(0x1000, timer_interrupt)	/* Fixed Internal Timer Interrupt */	/* TODO: Add FIT support */	EXCEPTION(0x1010, FixedIntervalTimer, UnknownException, EXC_XFER_EE)	/* Watchdog Timer Interrupt */	/* TODO: Add watchdog support */	CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException)	/* Data TLB Error Interrupt */	START_EXCEPTION(DataTLBError)	mtspr	SPRG0, r10		/* Save some working registers */	mtspr	SPRG1, r11	mtspr	SPRG4W, r12	mtspr	SPRG5W, r13	mfcr	r11	mtspr	SPRG7W, r11	mfspr	r10, SPRN_DEAR		/* Get faulting address */	/* If we are faulting a kernel address, we have to use the	 * kernel page tables.	 */	andis.	r11, r10, 0x8000	beq	3f	lis	r11, swapper_pg_dir@h	ori	r11, r11, swapper_pg_dir@l	mfspr	r12,SPRN_MMUCR	rlwinm	r12,r12,0,0,23		/* Clear TID */	b	4f	/* Get the PGD for the current thread */3:	mfspr	r11,SPRG3	lwz	r11,PGDIR(r11)	/* Load PID into MMUCR TID */	mfspr	r12,SPRN_MMUCR	mfspr   r13,SPRN_PID		/* Get PID */	rlwimi	r12,r13,0,24,31		/* Set TID */4:	mtspr	SPRN_MMUCR,r12	rlwinm 	r12, r10, 13, 19, 29	/* Compute pgdir/pmd offset */	lwzx	r11, r12, r11		/* Get pgd/pmd entry */	rlwinm.	r12, r11, 0, 0, 20	/* Extract pt base address */	beq	2f			/* Bail if no table */	rlwimi	r12, r10, 23, 20, 28	/* Compute pte address */	lwz	r11, 4(r12)		/* Get pte entry */	andi.	r13, r11, _PAGE_PRESENT	/* Is the page present? */	beq	2f			/* Bail if not present */	ori	r11, r11, _PAGE_ACCESSED	stw	r11, 4(r12)	 /* Jump to common tlb load */	b	finish_tlb_load2:	/* The bailout.  Restore registers to pre-exception conditions	 * and call the heavyweights to help us out.	 */	mfspr	r11, SPRG7R	mtcr	r11	mfspr	r13, SPRG5R	mfspr	r12, SPRG4R	mfspr	r11, SPRG1	mfspr	r10, SPRG0	b	data_access	/* Instruction TLB Error Interrupt */	/*	 * Nearly the same as above, except we get our	 * information from different registers and bailout	 * to a different point.	 */	START_EXCEPTION(InstructionTLBError)	mtspr	SPRG0, r10		/* Save some working registers */	mtspr	SPRG1, r11	mtspr	SPRG4W, r12	mtspr	SPRG5W, r13	mfcr	r11	mtspr	SPRG7W, r11	mfspr	r10, SRR0		/* Get faulting address */	/* If we are faulting a kernel address, we have to use the	 * kernel page tables.	 */	andis.	r11, r10, 0x8000	beq	3f	lis	r11, swapper_pg_dir@h	ori	r11, r11, swapper_pg_dir@l	mfspr	r12,SPRN_MMUCR	rlwinm	r12,r12,0,0,23		/* Clear TID */	b	4f	/* Get the PGD for the current thread */3:	mfspr	r11,SPRG3	lwz	r11,PGDIR(r11)	/* Load PID into MMUCR TID */	mfspr	r12,SPRN_MMUCR	mfspr   r13,SPRN_PID		/* Get PID */	rlwimi	r12,r13,0,24,31		/* Set TID */4:	mtspr	SPRN_MMUCR,r12	rlwinm	r12, r10, 13, 19, 29	/* Compute pgdir/pmd offset */	lwzx	r11, r12, r11		/* Get pgd/pmd entry */	rlwinm.	r12, r11, 0, 0, 20	/* Extract pt base address */	beq	2f			/* Bail if no table */	rlwimi	r12, r10, 23, 20, 28	/* Compute pte address */	lwz	r11, 4(r12)		/* Get pte entry */	andi.	r13, r11, _PAGE_PRESENT	/* Is the page present? */	beq	2f			/* Bail if not present */	ori	r11, r11, _PAGE_ACCESSED	stw	r11, 4(r12)	/* Jump to common TLB load point */	b	finish_tlb_load2:	/* The bailout.  Restore registers to pre-exception conditions	 * and call the heavyweights to help us out.	 */	mfspr	r11, SPRG7R	mtcr	r11	mfspr	r13, SPRG5R	mfspr	r12, SPRG4R	mfspr	r11, SPRG1	mfspr	r10, SPRG0	b	InstructionStorage/* 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/DTLB 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 handler's_ MSR (the debug trap is * a critical exception, so we are using SPRN_CSRR1 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. */	/* Debug Interrupt */	START_EXCEPTION(Debug)	CRITICAL_EXCEPTION_PROLOG	/*	 * If this is a single step or branch-taken exception in an	 * exception entry sequence, it was probably meant to apply to	 * the code where the exception occurred (since exception entry	 * doesn't turn off DE automatically).  We simulate the effect	 * of turning off DE on entry to an exception handler by turning	 * off DE in the CSRR1 value and clearing the debug status.	 */	mfspr	r10,SPRN_DBSR		/* check single-step/branch taken */	andis.	r10,r10,(DBSR_IC|DBSR_BT)@h	beq+	1f	andi.	r0,r9,MSR_PR		/* check supervisor */	beq	2f			/* branch if we need to fix it up... */	/* continue normal handling for a critical exception... */1:	mfspr	r4,SPRN_DBSR	addi	r3,r1,STACK_FRAME_OVERHEAD	EXC_XFER_TEMPLATE(DebugException, 0x2002, \		(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \		NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)	/* here it looks like we got an inappropriate debug exception. */2:	rlwinm	r9,r9,0,~MSR_DE		/* clear DE in the CSRR1 value */	mtspr	SPRN_DBSR,r10		/* clear the IC/BT debug intr status */	/* restore state and get out */	lwz	r10,_CCR(r11)	lwz	r0,GPR0(r11)	lwz	r1,GPR1(r11)	mtcrf	0x80,r10	mtspr	CSRR0,r12	mtspr	CSRR1,r9	lwz	r9,GPR9(r11)	mtspr	SPRG2,r8;		/* SPRG2 only used in criticals */	lis	r8,crit_save@ha;	lwz	r10,crit_r10@l(r8)	lwz	r11,crit_r11@l(r8)	mfspr	r8,SPRG2	rfci	b	./* * Local functions */	/*	 * Data TLB exceptions will bail out to this point	 * if they can't resolve the lightweight TLB fault.	 */data_access:	NORMAL_EXCEPTION_PROLOG	mfspr	r5,SPRN_ESR		/* Grab the ESR, save it, pass arg3 */	stw	r5,_ESR(r11)	mfspr	r4,SPRN_DEAR		/* Grab the DEAR, save it, pass arg2 */	EXC_XFER_EE_LITE(0x0300, handle_page_fault)/* * Both the instruction and data TLB miss get to this * point to load the TLB. * 	r10 - EA of fault * 	r11 - available to use *	r12 - Pointer to the 64-bit PTE *	r13 - available to use *	MMUCR - loaded with proper value when we get here *	Upon exit, we reload everything and RFI. */finish_tlb_load:	/*	 * 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.	 */	/* Load the next available TLB index */	lis	r13, tlb_44x_index@ha	lwz	r13, tlb_44x_index@l(r13)	/* Load the TLB high watermark */	lis	r11, tlb_44x_hwater@ha	lwz	r11, tlb_44x_hwater@l(r11)	/* Increment, rollover, and store TLB index */	addi	r13, r13, 1	cmpw	0, r13, r11			/* reserve entries */	ble	7f	li	r13, 07:	/* Store the next available TLB index */	lis	r11, tlb_44x_index@ha	stw	r13, tlb_44x_index@l(r11)	lwz	r11, 0(r12)			/* Get MS word of PTE */	lwz	r12, 4(r12)			/* Get LS word of PTE */	rlwimi	r11, r12, 0, 0 , 19		/* Insert RPN */	tlbwe	r11, r13, PPC44x_TLB_XLAT	/* Write XLAT */	/*	 * Create PAGEID. This is the faulting address,	 * page size, and valid flag.	 */	li	r11, PPC44x_TLB_VALID | PPC44x_TLB_4K	rlwimi	r10, r11, 0, 20, 31		/* Insert valid and page size */	tlbwe	r10, r13, PPC44x_TLB_PAGEID	/* Write PAGEID */	li	r10, PPC44x_TLB_SR@l		/* Set SR */	rlwimi	r10, r12, 0, 30, 30		/* Set SW = _PAGE_RW */	rlwimi	r10, r12, 29, 29, 29		/* SX = _PAGE_HWEXEC */	rlwimi	r10, r12, 29, 28, 28		/* UR = _PAGE_USER */	rlwimi	r11, r12, 31, 26, 26		/* (_PAGE_USER>>1)->r12 */	and	r11, r12, r11			/* HWEXEC & USER */	rlwimi	r10, r11, 0, 26, 26		/* UX = HWEXEC & USER */	rlwimi	r12, r10, 0, 26, 31		/* Insert static perms */	rlwinm	r12, r12, 0, 20, 15		/* Clear U0-U3 */	tlbwe	r12, r13, PPC44x_TLB_ATTRIB	/* Write ATTRIB */	/* Done...restore registers and get out of here.	*/	mfspr	r11, SPRG7R	mtcr	r11	mfspr	r13, SPRG5R	mfspr	r12, SPRG4R	mfspr	r11, SPRG1	mfspr	r10, SPRG0	rfi					/* Force context change *//* * Global functions *//* * extern void giveup_altivec(struct task_struct *prev) * * The 44x core does not have an AltiVec unit. */_GLOBAL(giveup_altivec)	blr/* * extern void giveup_fpu(struct task_struct *prev) * * The 44x core does not have an FPU. */_GLOBAL(giveup_fpu)	blr/* * extern void abort(void) * * At present, this routine just applies a system reset. */_GLOBAL(abort)        mfspr   r13,SPRN_DBCR0        oris    r13,r13,DBCR0_RST_SYSTEM@h        mtspr   SPRN_DBCR0,r13_GLOBAL(set_context)#ifdef CONFIG_BDI_SWITCH	/* Context switch the PTE pointer for the Abatron BDI2000.	 * The PGDIR is the second parameter.	 */	lis	r5, abatron_pteptrs@h	ori	r5, r5, abatron_pteptrs@l	stw	r4, 0x4(r5)#endif	mtspr	SPRN_PID,r3	isync			/* Force context change */	blr/* * We put a few things here that have to be page-aligned. This stuff * goes at the beginning of the data segment, which is page-aligned. */	.data_GLOBAL(sdata)_GLOBAL(empty_zero_page)	.space	4096/* * To support >32-bit physical addresses, we use an 8KB pgdir. */_GLOBAL(swapper_pg_dir)	.space	8192	.section .bss/* Stack for handling critical exceptions from kernel mode */critical_stack_bottom:	.space 4096critical_stack_top:	.previous/* Stack for handling machine check exceptions from kernel mode */mcheck_stack_bottom:	.space 4096mcheck_stack_top:	.previous/* * This area is used for temporarily saving registers during the * critical and machine check exception prologs. It must always * follow the page aligned allocations, so it starts on a page * boundary, ensuring that all crit_save areas are in a single * page. *//* crit_save */_GLOBAL(crit_save)	.space  4_GLOBAL(crit_r10)	.space	4_GLOBAL(crit_r11)	.space	4_GLOBAL(crit_sprg0)	.space	4_GLOBAL(crit_sprg1)	.space	4_GLOBAL(crit_sprg4)	.space	4_GLOBAL(crit_sprg5)	.space	4_GLOBAL(crit_sprg7)	.space	4_GLOBAL(crit_pid)	.space	4_GLOBAL(crit_srr0)	.space	4_GLOBAL(crit_srr1)	.space	4/* mcheck_save */_GLOBAL(mcheck_save)	.space  4_GLOBAL(mcheck_r10)	.space	4_GLOBAL(mcheck_r11)	.space	4_GLOBAL(mcheck_sprg0)	.space	4_GLOBAL(mcheck_sprg1)	.space	4_GLOBAL(mcheck_sprg4)	.space	4_GLOBAL(mcheck_sprg5)	.space	4_GLOBAL(mcheck_sprg7)	.space	4_GLOBAL(mcheck_pid)	.space	4_GLOBAL(mcheck_srr0)	.space	4_GLOBAL(mcheck_srr1)	.space	4_GLOBAL(mcheck_csrr0)	.space	4_GLOBAL(mcheck_csrr1)	.space	4/* * This space gets a copy of optional info passed to us by the bootstrap * which is used to pass parameters into the kernel like root=/dev/sda1, etc. */_GLOBAL(cmd_line)	.space	512/* * Room for two PTE pointers, usually the kernel and current user pointers * to their respective root page table. */abatron_pteptrs:	.space	8

⌨️ 快捷键说明

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