head_44x.s

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

S
1,120
字号
	SAVE_GPR(7, r21);		/* Save r7 on the stack		   */#define	STND_EXCEPTION_PROLOG						     \	COMMON_PROLOG;							     \	mfspr	r22,SPRN_SRR0;		/* Faulting instruction address	   */\	lis	r20,MSR_WE@h;						     \	mfspr	r23,SPRN_SRR1;		/* MSR at the time of fault	   */\	andc	r23,r23,r20;		/* disable processor wait state    */\	COMMON_EPILOG;#define CRIT_EXCEPTION_PROLOG	                                             \	COMMON_PROLOG;	                                                     \	mfspr   r22,SPRN_CSRR0;         /* Faulting instruction address    */\	lis     r20,MSR_WE@h;                                                \	mfspr   r23,SPRN_CSRR1;         /* MSR at the time of fault        */\	andc    r23,r23,r20;            /* disable processor wait state    */\	COMMON_EPILOG;#define START_EXCEPTION(label) \        .align 5;              \label:#define FINISH_EXCEPTION(n, func)					     \	bl	transfer_to_handler;					     \	.long	func;							     \	.long	ret_from_except;					     \	.long	n#define STND_EXCEPTION(n, label, func)					     \	START_EXCEPTION(label)						     \	STND_EXCEPTION_PROLOG;						     \	addi	r3,r1,STACK_FRAME_OVERHEAD;				     \	li	r7,STND_EXC;						     \	li	r20,MSR_KERNEL;						     \	FINISH_EXCEPTION(n, func)#define	CRIT_EXCEPTION(n, label, func)					     \	START_EXCEPTION(label)						     \	CRIT_EXCEPTION_PROLOG;						     \	addi	r3,r1,STACK_FRAME_OVERHEAD;				     \	li	r7,CRIT_EXC;						     \	li	r20,MSR_KERNEL;						     \	FINISH_EXCEPTION(n, func)interrupt_base:	/* Critical Input Interrupt */	CRIT_EXCEPTION(0x100, CriticalInput,UnknownException);	/* Machine Check Interrupt */	/* TODO: provide bus error register status */	START_EXCEPTION(MachineCheck)	COMMON_PROLOG;	mfspr   r22,__SPRN_MCSRR0       /* Faulting instruction address    */	lis     r20,MSR_WE@h	mfspr   r23,__SPRN_MCSRR1       /* MSR at the time of fault        */	andc    r23,r23,r20             /* disable processor wait state    */	COMMON_EPILOG;#ifdef CONFIG_440A	lis	r20,MCSR_MCS@h	mfspr	r4,SPRN_MCSR		/* We may want to access original					   MCSR as arg2 in the future. --ebs */	mtspr	SPRN_MCSR,r20		/* Clear Machine Check Summary field */#endif		mfspr	r5,SPRN_ESR		/* Grab the ESR, save it */	stw	r5,_ESR(r21)	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r7,MCHK_EXC	li	r20,MSR_KERNEL	FINISH_EXCEPTION(0x200, MachineCheckException)	/* Data Storage Interrupt */	START_EXCEPTION(DataStorage)	mtspr	SPRG0, r20		/* Save some working registers */	mtspr	SPRG1, r21	mtspr	SPRG4W, r22	mtspr	SPRG5W, r23	mtspr	SPRG6W, r24	mfcr	r21	mtspr	SPRG7W, r21	/*	 * Check if it was a store fault, if not then bail	 * because a user tried to access a kernel or	 * read-protected page.  Otherwise, get the	 * offending address and handle it.	 */	mfspr	r20, SPRN_ESR	andis.	r20, r20, ESR_DST@h	beq	2f	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	mfspr   r22,SPRN_MMUCR          /* Set TID to 0 */	li      r23,PPC44x_MMUCR_TID@l	andc    r22,r22,r23	mtspr   SPRN_MMUCR,r22	b	4f	/* Get the PGD for the current thread */3:	mfspr	r21,SPRG3	lwz	r21,PGDIR(r21)	/* Load MMUCR with our PID and STS=<current TS> */	mfspr	r22,SPRN_MMUCR			/* Get MMUCR */	lis     r23,PPC44x_MMUCR_STS@h	ori     r23,r23,PPC44x_MMUCR_TID@l      /* Create mask */	andc    r22,r22,r23                     /* Clear out TID/STS bits */	mfspr   r23,SPRN_PID                    /* Get PID */	or      r22,r22,r23			/* Set TID bits */	mfspr	r24,SPRN_SRR1			/* Get SRR1 */	andi.	r24,r24,MSR_IS@l		/* TS=1? */	beq	4f				/* If not, leave STS=0 */	oris	r22,r22,PPC44x_MMUCR_STS@h	/* Set STS=1 */	mtspr   SPRN_MMUCR,r224:	rlwinm  r22, r20, 13, 19, 29    /* Compute pgdir/pmd offset */	lwzx    r21, r22, r21           /* Get pgd/pmd entry */	rlwinm. r22, r21, 0, 0, 20      /* Extract pt base address */	beq     2f                      /* Bail if no table */	rlwimi  r22, r20, 23, 20, 28    /* Compute pte address */	lwz     r21, 4(r22)             /* Get pte entry */		andi.	r23, r21, _PAGE_RW	/* Is it writeable? */	beq	2f			/* Bail if not */	/* Update 'changed'.	*/	ori	r21, r21, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE	stw	r21, 4(r22)		/* Update Linux page table */	/* FIXME: Staticly setting some permissions */	li	r23, 0x003f		/* Set UX,UW,UR,SX,SW,SR */	andi.	r21,r21,0xffff		/* Clear MS 16 bits */	/* FIXME: Force attributes */	ori	r21,r21, 0x0100		/* Set G */	/* FIXME: Already set in PTE */	rlwimi	r21,r23,0,26,31		/* Insert static perms */	lis	r23,0xffff	ori	r23,r23,0x0fff			/* Set U0-U3 mask */	and	r21,r21,r23			/* Clear U0-U3 */	/* find the TLB index that caused the fault.  It has to be here. */	tlbsx	r24, 0, r20	tlbwe	r21, r24, PPC44x_TLB_ATTRIB		/* Write ATTRIB */	/* Done...restore registers and get out of here.	*/	mfspr	r21, SPRG7R	mtcr	r21	mfspr	r24, SPRG6R	mfspr	r23, SPRG5R	mfspr	r22, SPRG4R	mfspr	r21, SPRG1	mfspr	r20, SPRG0	rfi			/* Force context change */2:	/*	 * The bailout.  Restore registers to pre-exception conditions	 * and call the heavyweights to help us out.	 */	mfspr	r21, SPRG7R	mtcr	r21	mfspr	r24, SPRG6R	mfspr	r23, SPRG5R	mfspr	r22, SPRG4R	mfspr	r21, SPRG1	mfspr	r20, SPRG0	b	data_access	/* Instruction Storage Interrupt */	START_EXCEPTION(InstructionStorage)	STND_EXCEPTION_PROLOG	mfspr	r5,SPRN_ESR		/* Grab the ESR, save it */	stw	r5,_ESR(r21)	mr      r4,r22                  /* Pass SRR0 as arg2 */	li      r5,0                    /* Pass zero as arg3 */	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(0x400, do_page_fault)/* do_page_fault(regs, SRR0, SRR1) */	/* External Input Interrupt */	START_EXCEPTION(ExternalInput)	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	.long	0x500	/* Alignment Interrupt */	START_EXCEPTION(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(0x600, AlignmentException)	/* Program Interrupt */	START_EXCEPTION(Program)	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(0x700, ProgramCheckException)	/* Floating Point Unavailable Interrupt */	STND_EXCEPTION(0x2010, FloatingPointUnavailable,UnknownException);	/* System Call Interrupt */	START_EXCEPTION(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(0xc00, DoSyscall)	/* Auxillary Processor Unavailable */	STND_EXCEPTION(0x2020, AuxillaryProcessorUnavailable,UnknownException);	/* Decrementer Interrupt */	START_EXCEPTION(Decrementer)	STND_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	li      r7,STND_EXC	li      r20,MSR_KERNEL	bl      transfer_to_handler_GLOBAL(timer_interrupt_intercept)	.long   timer_interrupt	.long   ret_from_intercept	.long	0x1000	/* Fixed Internal Timer Interrupt */	/* TODO: Add FIT support */	STND_EXCEPTION(0x1010, FixedIntervalTimer,UnknownException);	/* Watchdog Timer Interrupt */	/* TODO: Add watchdog support */	CRIT_EXCEPTION(0x1020, WatchdogTimer,UnknownException);	/* Data TLB Error Interrupt */	START_EXCEPTION(DataTLBError)	mtspr	SPRG0, r20		/* Save some working registers */	mtspr	SPRG1, r21	mtspr	SPRG4W, r22	mtspr	SPRG5W, r23	mtspr	SPRG6W, r24	mfcr	r21	mtspr	SPRG7W, r21	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	mfspr	r22,SPRN_MMUCR		/* Set TID to 0 */	li	r23,PPC44x_MMUCR_TID@l	andc	r22,r22,r23	mtspr	SPRN_MMUCR,r22	b	4f	/* Get the PGD for the current thread */3:	mfspr	r21,SPRG3	lwz	r21,PGDIR(r21)	/* Load PID into MMUCR TID */	li      r23,PPC44x_MMUCR_TID@l       	 /* Create mask */	andc    r22,r22,r23                      /* Clear out TID/STS bits */	mfspr   r23,SPRN_PID                     /* Get PID */	or      r22,r22,r23	mtspr	SPRN_MMUCR,r224:	rlwinm 	r22, r20, 13, 19, 29	/* Compute pgdir/pmd offset */	lwzx	r21, r22, r21		/* Get pgd/pmd entry */	rlwinm.	r22, r21, 0, 0, 20	/* Extract pt base address */	beq	2f			/* Bail if no table */	rlwimi	r22, r20, 23, 20, 28	/* Compute pte address */	lwz	r21, 4(r22)		/* Get pte entry */	andi.	r23, r21, _PAGE_PRESENT	/* Is the page present? */	beq	2f			/* Bail if not present */	ori	r21, r21, _PAGE_ACCESSED	stw	r21, 4(r22)	 /* 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	r21, SPRG7R	mtcr	r21	mfspr	r24, SPRG6R	mfspr	r23, SPRG5R	mfspr	r22, SPRG4R	mfspr	r21, SPRG1	mfspr	r20, 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, r20		/* Save some working registers */	mtspr	SPRG1, r21	mtspr	SPRG4W, r22	mtspr	SPRG5W, r23	mtspr	SPRG6W, r24	mfcr	r21	mtspr	SPRG7W, r21	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	mfspr	r22,SPRN_MMUCR		/* Set TID to 0 */	li	r23,PPC44x_MMUCR_TID@l	andc	r22,r22,r23	mtspr	SPRN_MMUCR,r22	b	4f	/* Get the PGD for the current thread */3:	mfspr	r21,SPRG3	lwz	r21,PGDIR(r21)

⌨️ 快捷键说明

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