📄 head_44x.s
字号:
rlwimi r13, r12, 3, 27, 27 /* UW = RW & USER */ rlwimi r11,r13,0,26,31 /* Insert static perms */ rlwinm r11,r11,0,20,15 /* Clear U0-U3 */ /* find the TLB index that caused the fault. It has to be here. */ tlbsx r10, 0, r10 tlbwe r11, r10, PPC44x_TLB_ATTRIB /* Write ATTRIB */ /* Done...restore registers and get out of here. */ mfspr r11, SPRN_SPRG7R mtcr r11 mfspr r13, SPRN_SPRG5R mfspr r12, SPRN_SPRG4R mfspr r11, SPRN_SPRG1 mfspr r10, SPRN_SPRG0 rfi /* Force context change */2: /* * The bailout. Restore registers to pre-exception conditions * and call the heavyweights to help us out. */ mfspr r11, SPRN_SPRG7R mtcr r11 mfspr r13, SPRN_SPRG5R mfspr r12, SPRN_SPRG4R mfspr r11, SPRN_SPRG1 mfspr r10, SPRN_SPRG0 b data_access /* Instruction Storage Interrupt */ INSTRUCTION_STORAGE_EXCEPTION /* External Input Interrupt */ EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) /* Alignment Interrupt */ ALIGNMENT_EXCEPTION /* Program Interrupt */ PROGRAM_EXCEPTION /* Floating Point Unavailable Interrupt */#ifdef CONFIG_PPC_FPU FP_UNAVAILABLE_EXCEPTION#else EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)#endif /* System Call Interrupt */ START_EXCEPTION(SystemCall) NORMAL_EXCEPTION_PROLOG EXC_XFER_EE_LITE(0x0c00, DoSyscall) /* Auxillary Processor Unavailable Interrupt */ EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE) /* Decrementer Interrupt */ DECREMENTER_EXCEPTION /* Fixed Internal Timer Interrupt */ /* TODO: Add FIT support */ EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE) /* Watchdog Timer Interrupt */ /* TODO: Add watchdog support */#ifdef CONFIG_BOOKE_WDT CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException)#else CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception)#endif /* Data TLB Error Interrupt */ START_EXCEPTION(DataTLBError) mtspr SPRN_SPRG0, r10 /* Save some working registers */ mtspr SPRN_SPRG1, r11 mtspr SPRN_SPRG4W, r12 mtspr SPRN_SPRG5W, r13 mfcr r11 mtspr SPRN_SPRG7W, r11 mfspr r10, SPRN_DEAR /* Get faulting address */ /* If we are faulting a kernel address, we have to use the * kernel page tables. */ lis r11, TASK_SIZE@h cmplw r10, r11 blt+ 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,SPRN_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, SPRN_SPRG7R mtcr r11 mfspr r13, SPRN_SPRG5R mfspr r12, SPRN_SPRG4R mfspr r11, SPRN_SPRG1 mfspr r10, SPRN_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 SPRN_SPRG0, r10 /* Save some working registers */ mtspr SPRN_SPRG1, r11 mtspr SPRN_SPRG4W, r12 mtspr SPRN_SPRG5W, r13 mfcr r11 mtspr SPRN_SPRG7W, r11 mfspr r10, SPRN_SRR0 /* Get faulting address */ /* If we are faulting a kernel address, we have to use the * kernel page tables. */ lis r11, TASK_SIZE@h cmplw r10, r11 blt+ 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,SPRN_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, SPRN_SPRG7R mtcr r11 mfspr r13, SPRN_SPRG5R mfspr r12, SPRN_SPRG4R mfspr r11, SPRN_SPRG1 mfspr r10, SPRN_SPRG0 b InstructionStorage /* Debug Interrupt */ DEBUG_EXCEPTION/* * 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, SPRN_SPRG7R mtcr r11 mfspr r13, SPRN_SPRG5R mfspr r12, SPRN_SPRG4R mfspr r11, SPRN_SPRG1 mfspr r10, SPRN_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. */#ifndef CONFIG_PPC_FPU_GLOBAL(giveup_fpu) blr#endif/* * 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 .align 12 .globl sdatasdata: .globl empty_zero_pageempty_zero_page: .space 4096/* * To support >32-bit physical addresses, we use an 8KB pgdir. */ .globl swapper_pg_dirswapper_pg_dir: .space 8192/* Reserved 4k for the critical exception stack & 4k for the machine * check stack per CPU for kernel mode exceptions */ .section .bss .align 12exception_stack_bottom: .space BOOKE_EXCEPTION_STACK_SIZE .globl exception_stack_topexception_stack_top:/* * 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. */ .globl cmd_linecmd_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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -