📄 head.s
字号:
li r4,0 /* "yield timed" */ li r5,-1 /* "yield forever" */#endif /* CONFIG_SMP */ li r0,-1 /* r0=-1 indicates a Hypervisor call */ sc /* Invoke the hypervisor via a system call */ mfspr r25,SPRG3 /* Put r25 back ???? */ b 1b /* If SMP not configured, secondaries * loop forever */ .globl HardwareInterrupt_Iseries_maskedHardwareInterrupt_Iseries_masked: b maskable_exception_exit .globl Decrementer_Iseries_maskedDecrementer_Iseries_masked: li r22,1 stb r22,PACALPPACA+LPPACADECRINT(r20) lwz r22,PACADEFAULTDECR(r20) mtspr DEC,r22maskable_exception_exit: mtcrf 0xff,r23 /* Restore regs and free exception frame */ ld r22,EX_SRR0(r21) ld r23,EX_SRR1(r21) mtspr SRR0,r22 mtspr SRR1,r23 ld r22,EX_R22(r21) ld r23,EX_R23(r21) mfspr r21,SPRG1 mfspr r20,SPRG2 rfid/*** Common interrupt handlers ***/ STD_EXCEPTION_COMMON( 0x100, SystemReset, .SystemResetException ) STD_EXCEPTION_COMMON( 0x200, MachineCheck, .MachineCheckException ) STD_EXCEPTION_COMMON( 0x900, Decrementer, .timer_interrupt ) STD_EXCEPTION_COMMON( 0xa00, Trap_0a, .UnknownException ) STD_EXCEPTION_COMMON( 0xb00, Trap_0b, .UnknownException ) STD_EXCEPTION_COMMON( 0xd00, SingleStep, .SingleStepException ) STD_EXCEPTION_COMMON( 0xe00, Trap_0e, .UnknownException ) STD_EXCEPTION_COMMON( 0xf00, PerformanceMonitor, .PerformanceMonitorException ) STD_EXCEPTION_COMMON(0x1300, InstructionBreakpoint, .InstructionBreakpointException )/* * Return from an exception which is handled without calling * save_remaining_regs. The caller is assumed to have done * EXCEPTION_PROLOG_COMMON. */fast_exception_return: ld r3,_CCR(r1) ld r4,_LINK(r1) ld r5,_CTR(r1) ld r6,_XER(r1) mtcr r3 mtlr r4 mtctr r5 mtspr XER,r6 REST_GPR(0, r1) REST_8GPRS(2, r1) REST_4GPRS(10, r1) mtspr SRR1,r23 mtspr SRR0,r22 REST_4GPRS(20, r1) ld r1,GPR1(r1) rfid/* * Here r20 points to the PACA, r21 to the exception frame, * r23 contains the saved CR. * r20 - r23, SRR0 and SRR1 are saved in the exception frame. */ .globl DataAccess_commonDataAccess_common: mfspr r22,DAR srdi r22,r22,60 cmpi 0,r22,0xc /* Segment fault on a bolted segment. Go off and map that segment. */ beq .do_stab_boltedstab_bolted_user_return: EXCEPTION_PROLOG_COMMON ld r3,_DSISR(r1) andis. r0,r3,0xa450 /* weird error? */ bne 1f /* if not, try to put a PTE */ andis. r0,r3,0x0020 /* Is it a page table fault? */ rlwinm r4,r3,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */ ld r3,_DAR(r1) /* into the hash table */ beq 2f /* If so handle it */ li r4,0x300 /* Trap number */ bl .do_stab_SI b 1f2: bl .do_hash_page_DSI /* Try to handle as hpte fault */1: ld r4,_DAR(r1) ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD#ifdef DO_SOFT_DISABLE ld r20,SOFTE(r1) /* Copy saved SOFTE bit */#else rldicl r20,r23,49,63 /* copy EE bit from saved MSR */#endif li r6,0x300 bl .save_remaining_regs bl .do_page_fault b .ret_from_except .globl DataAccessSLB_commonDataAccessSLB_common: mfspr r22,DAR srdi r22,r22,60 cmpi 0,r22,0xc /* Segment fault on a bolted segment. Go off and map that segment. */ beq .do_slb_bolted EXCEPTION_PROLOG_COMMON ld r3,_DAR(r1) li r4,0x380 /* Exception vector */ bl .ste_allocate or. r3,r3,r3 /* Check return code */ beq fast_exception_return /* Return if we succeeded */ addi r3,r1,STACK_FRAME_OVERHEAD#ifdef DO_SOFT_DISABLE ld r20,SOFTE(r1)#else rldicl r20,r23,49,63 /* copy EE bit from saved MSR */#endif li r6,0x380 bl .save_remaining_regs bl .do_page_fault b .ret_from_except .globl InstructionAccess_commonInstructionAccess_common: EXCEPTION_PROLOG_COMMON andis. r0,r23,0x0020 /* no ste found? */ beq 2f mr r3,r22 /* SRR0 at interrupt */ li r4,0x400 /* Trap number */ bl .do_stab_SI b 1f2: andis. r0,r23,0x4000 /* no pte found? */ beq 1f /* if so, try to put a PTE */ mr r3,r22 /* into the hash table */ bl .do_hash_page_ISI /* Try to handle as hpte fault */1: mr r4,r22 mr r5,r23 addi r3,r1,STACK_FRAME_OVERHEAD#ifdef DO_SOFT_DISABLE ld r20,SOFTE(r1)#else rldicl r20,r23,49,63 /* copy EE bit from saved MSR */#endif li r6,0x400 bl .save_remaining_regs bl .do_page_fault b .ret_from_except .globl InstructionAccessSLB_commonInstructionAccessSLB_common: EXCEPTION_PROLOG_COMMON mr r3,r22 /* SRR0 = NIA */ li r4,0x480 /* Exception vector */ bl .ste_allocate or. r3,r3,r3 /* Check return code */ beq fast_exception_return /* Return if we succeeded */ addi r3,r1,STACK_FRAME_OVERHEAD#ifdef DO_SOFT_DISABLE ld r20,SOFTE(r1)#else rldicl r20,r23,49,63 /* copy EE bit from saved MSR */#endif li r6,0x380 bl .save_remaining_regs bl .do_page_fault b .ret_from_except .globl HardwareInterrupt_commonHardwareInterrupt_common: EXCEPTION_PROLOG_COMMONHardwareInterrupt_entry: addi r3,r1,STACK_FRAME_OVERHEAD li r20,0 li r6,0x500 bl .save_remaining_regs /* Determine if need to run do_irq on a hardware interrupt stack */ /* The first invocation of do_irq will occur on the kernel */ /* stack in the current stack */ /* All other invocations of do_irq will run on the hardware */ /* interrupt stack associated with the PACA of the current */ /* processor. */ /* */ /* The call to do_irq will preserve the value of r14 - r31 */ /* */ mfspr r20,SPRG3 /* get Paca */ lbz r21,PACAHRDWINTCOUNT(r20) /* get hardware interrupt cnt */ cmpi 0,r21,1 /* */ addi r21,r21,1 /* incr hardware interrupt cnt*/ stb r21,PACAHRDWINTCOUNT(r20) /* */ bne 2f /* */ mr r14,r1 /* preserve current r1 */ ld r1,PACAHRDWINTSTACK(r20) /* */ std r14,0(r1) /* set the back chain */ bl .do_IRQ lbz r22,PACAHRDWINTCOUNT(r20) /* get hardware interrupt cnt */ cmp 0,r22,r21 /* debug test */ bne 3f subi r21,r21,1 stb r21,PACAHRDWINTCOUNT(r20) /* */ mr r1,r14 /* */ b .ret_from_except2: bl .do_IRQ lbz r22,PACAHRDWINTCOUNT(r20) /* get hardware interrupt cnt */ cmp 0,r22,r21 /* debug test */ bne 3f /* */ subi r21,r21,1 /* decr hardware interrupt cnt*/ stb r21,PACAHRDWINTCOUNT(r20) /* */ b .ret_from_except3: /* error - counts out of sync */#ifdef CONFIG_XMON bl .xmon#endif4: b 4b .globl Alignment_commonAlignment_common: EXCEPTION_PROLOG_COMMON addi r3,r1,STACK_FRAME_OVERHEAD#ifdef DO_SOFT_DISABLE ld r20,SOFTE(r1)#else rldicl r20,r23,49,63 /* copy EE bit from saved MSR */#endif li r6,0x600 bl .save_remaining_regs bl .AlignmentException b .ret_from_except .globl ProgramCheck_commonProgramCheck_common: EXCEPTION_PROLOG_COMMON addi r3,r1,STACK_FRAME_OVERHEAD#ifdef DO_SOFT_DISABLE ld r20,SOFTE(r1)#else rldicl r20,r23,49,63 /* copy EE bit from saved MSR */#endif li r6,0x700 bl .save_remaining_regs bl .ProgramCheckException b .ret_from_except .globl FPUnavailable_commonFPUnavailable_common: EXCEPTION_PROLOG_COMMON bne .load_up_fpu /* if from user, just load it up */ li r20,0 li r6,0x800 bl .save_remaining_regs /* if from kernel, take a trap */ bl .KernelFP b .ret_from_except .globl SystemCall_commonSystemCall_common: EXCEPTION_PROLOG_COMMON#ifdef CONFIG_PPC_ISERIES cmpi 0,r0,0x5555 /* Special syscall to handle pending */ bne+ 1f /* interrupts */ andi. r6,r23,MSR_PR /* Only allowed from kernel */ beq+ HardwareInterrupt_entry1:#endif std r3,ORIG_GPR3(r1)#ifdef DO_SOFT_DISABLE ld r20,SOFTE(r1)#else rldicl r20,r23,49,63 /* copy EE bit from saved MSR */#endif li r6,0xC00 bl .save_remaining_regs bl .DoSyscall b .ret_from_except_GLOBAL(do_hash_page_ISI) li r4,0_GLOBAL(do_hash_page_DSI) rlwimi r4,r23,32-13,30,30 /* Insert MSR_PR as _PAGE_USER */ ori r4,r4,1 /* add _PAGE_PRESENT */ mflr r21 /* Save LR in r21 */#ifdef DO_SOFT_DISABLE /* * We hard enable here (but first soft disable) so that the hash_page * code can spin on the hash_table_lock with problem on a shared * processor. */ li r0,0 stb r0,PACAPROCENABLED(r20) /* Soft Disabled */ mfmsr r0 ori r0,r0,MSR_EE+MSR_RI mtmsrd r0 /* Hard Enable, RI on */#endif /* * r3 contains the faulting address * r4 contains the required access permissions * * at return r3 = 0 for success */ bl .hash_page /* build HPTE if possible */#ifdef DO_SOFT_DISABLE /* * Now go back to hard disabled. */ mfmsr r0 li r4,0 ori r4,r4,MSR_EE+MSR_RI andc r0,r0,r4 mtmsrd r0 /* Hard Disable, RI off */ ld r0,SOFTE(r1) cmpdi 0,r0,0 /* See if we will soft enable in */ /* save_remaining_regs */ beq 5f CHECKANYINT(r4,r5) bne- HardwareInterrupt_entry /* Convert this DSI into an External */ /* to process interrupts which occurred */ /* during hash_page */5: stb r0,PACAPROCENABLED(r20) /* Restore soft enable/disable status */#endif or. r3,r3,r3 /* Check return code */ beq fast_exception_return /* Return from exception on success */ mtlr r21 /* restore LR */ blr /* Return to DSI or ISI on failure *//* * r20 points to the PACA, r21 to the exception frame, * r23 contains the saved CR. * r20 - r23, SRR0 and SRR1 are saved in the exception frame. * We assume we aren't going to take any exceptions during this procedure. */_GLOBAL(do_stab_bolted) std r23,EX_DAR(r21) /* save CR in exc. frame */ mfspr r22,DSISR andis. r22,r22,0x0020 bne+ 2f ld r22,8(r21) /* get SRR1 */ andi. r22,r22,MSR_PR /* check if from user */ bne+ stab_bolted_user_return /* from user, send the error on up */ li r3,0#ifdef CONFIG_XMON bl .xmon#endif1: b 1b2: /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */ mfspr r21,DAR rldicl r20,r21,36,32 /* Permits a full 32b of ESID */ rldicr r20,r20,15,48 rldicl r21,r21,4,60 or r20,r20,r21 li r21,9 /* VSID_RANDOMIZER */ sldi r21,r21,32 oris r21,r21,58231 ori r21,r21,39831 mulld r20,r20,r21 clrldi r20,r20,28 /* r20 = vsid */ mfsprg r21,3 ld r21,PACASTABVIRT(r21) /* Hash to the primary group */ mfspr r22,DAR rldicl r22,r22,36,59 rldicr r22,r22,7,56 or r21,r21,r22 /* r21 = first ste of the group */ /* Search the primary group for a free entry */ li r22,01: ld r23,0(r21) /* Test valid bit of the current ste */ rldicl r23,r23,57,63 cmpwi r23,0 bne 2f ld r23,8(r21) /* Get the current vsid part of the ste */ rldimi r23,r20,12,0 /* Insert the new vsid value */ std r23,8(r21) /* Put new entry back into the stab */ eieio /* Order vsid update */ ld r23,0(r21) /* Get the esid part of the ste */ mfspr r20,DAR /* Get the new esid */ rldicl r20,r20,36,28 /* Permits a full 36b of ESID */ rldimi r23,r20,28,0 /* Insert the new esid value */ ori r23,r23,144 /* Turn on valid and kp */ std r23,0(r21) /* Put new entry back into the stab */ sync /* Order the update */ b 3f2: addi r22,r22,1 addi r21,r21,16 cmpldi r22,7 ble 1b /* Stick for only searching the primary group for now. */ /* At least for now, we use a very simple random castout scheme */ /* Use the TB as a random number ; OR in 1 to avoid entry 0 */ mftb r22 andi. r22,r22,7 ori r22,r22,1 sldi r22,r22,4 /* r21 currently points to and ste one past the group of interest */ /* make it point to the randomly selected entry */ subi r21,r21,128 or r21,r21,r22 /* r21 is the entry to invalidate */ isync /* mark the entry invalid */ ld r23,0(r21) li r22,-129 and r23,r23,r22 std r23,0(r21) sync ld r23,8(r21) rldimi r23,r20,12,0 std r23,8(r21) eieio ld r23,0(r21) /* Get the esid part of the ste */ mr r22,r23 mfspr r20,DAR /* Get the new esid */ rldicl r20,r20,36,28 /* Permits a full 32b of ESID */ rldimi r23,r20,28,0 /* Insert the new esid value */ ori r23,r23,144 /* Turn on valid and kp */ std r23,0(r21) /* Put new entry back into the stab */ rldicl r22,r22,36,28 rldicr r22,r22,28,35
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -