📄 head.s
字号:
.= 0x7000 .globl fwnmi_data_areafwnmi_data_area:/* * Vectors for the FWNMI option. Share common code. */ . = 0x8000 .globl SystemReset_FWNMISystemReset_FWNMI: EXCEPTION_PROLOG_PSERIES(0x100, SystemReset_common) .globl MachineCheck_FWNMIMachineCheck_FWNMI: EXCEPTION_PROLOG_PSERIES(0x200, MachineCheck_common)/*** 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(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 beq .do_stab_bolted cmpi 0,r22,0xb 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: li r5,0x300 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 beq .do_slb_bolted cmpi 0,r22,0xb 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,0x480 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,0 /* */ 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 .globl PerformanceMonitor_commonPerformanceMonitor_common: EXCEPTION_PROLOG_COMMON bl .PerformanceMonitorException b fast_exception_return _GLOBAL(PerformanceMonitorException) mfspr r7,SPRG3 lbz r8,PACAPROFMODE(r7) cmpi 0,r8,PMC_STATE_PROFILE_KERN beq 5f cmpi 0,r8,PMC_STATE_TRACE_KERN beq 6f cmpi 0,r8,PMC_STATE_TRACE_USER beq 9f blr /* PMC Profile Kernel */5: mfspr r9,SIAR srdi r8,r9,60 cmpi 0,r8,0xc beq 3f li r9,0xc sldi r9,r9,603: ld r8,PACAPROFSTEXT(r7) /* _stext */ subf r9,r8,r9 /* offset into kernel */ lwz r8,PACAPROFSHIFT(r7) srd r9,r9,r8 lwz r8,PACAPROFLEN(r7) /* length of profile table (-1) */ srdi r8,r8,2 cmpd r9,r8 /* off end? */ ble 1f mr r9,r8 /* force into last entry */ srdi r9,r9,21: sldi r9,r9,2 /* convert to offset into buffer */ ld r8,PACAPROFBUFFER(r7) /* profile buffer */ add r8,r8,r92: lwarx r9,0,r8 /* atomically increment */ addi r9,r9,1 stwcx. r9,0,r8 bne- 2b addi r10,r7,PACAPMC1 addi r7,r7,PACAPMCC1 b 7f /* PMC Trace Kernel */6: LOADADDR(r11, perfmon_base) addi r8,r11,32 ld r12,24(r11) subi r12,r12,18: ldarx r10,0,r8 addi r9,r10,16 and r9,r9,r12 stdcx. r9,0,r8 bne- 8b ld r9,16(r11) /* profile buffer */ add r8,r9,r10 mfspr r9,SIAR std r9,0(r8) mfspr r9,SDAR std r9,8(r8) addi r10,r7,PACAPMC1 addi r7,r7,PACAPMCC1 b 7f /* PMC Trace User */9: LOADADDR(r11, perfmon_base)#if 0 addi r8,r11,32 ld r12,24(r11) subi r12,r12,18: ldarx r10,0,r8 addi r9,r10,16 and r9,r9,r12 stdcx. r9,0,r8 bne- 8b ld r9,16(r11) /* profile buffer */ add r8,r9,r10 mfspr r9,SIAR std r9,0(r8) mfspr r9,SDAR std r9,8(r8) addi r10,r13,THREAD+THREAD_PMC1 addi r7,r13,THREAD+THREAD_PMCC1#endif /* Accumulate counter values for kernel traces */7: ld r9,0(r7) mfspr r8,PMC1 add r9,r9,r8 std r9,0(r7) ld r9,8(r7) mfspr r8,PMC2 add r9,r9,r8 std r9,8(r7) ld r9,16(r7) mfspr r8,PMC3 add r9,r9,r8 std r9,16(r7) ld r9,24(r7) mfspr r8,PMC4 add r9,r9,r8 std r9,24(r7) ld r9,32(r7) mfspr r8,PMC5 add r9,r9,r8 std r9,32(r7) ld r9,40(r7) mfspr r8,PMC6 add r9,r9,r8 std r9,40(r7) ld r9,48(r7) mfspr r8,PMC7 add r9,r9,r8 std r9,48(r7) ld r9,56(r7) mfspr r8,PMC8 add r9,r9,r8 std r9,56(r7) /* Reset all counters for kernel traces */ lwz r9,0(r10) mtspr PMC1,r9 lwz r9,4(r10) mtspr PMC2,r9 lwz r9,8(r10) mtspr PMC3,r9 lwz r9,12(r10) mtspr PMC4,r9 lwz r9,16(r10) mtspr PMC5,r9 lwz r9,20(r10) mtspr PMC6,r9 lwz r9,24(r10) mtspr PMC7,r9 lwz r9,28(r10) mtspr PMC8,r9 lwz r9,32(r10) mtspr MMCR0,r9 lwz r9,36(r10) mtspr MMCR1,r9 lwz r9,40(r10) mtspr MMCRA,r9 blr_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 * r5 contains the trap number * * 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) stw r23,EX_CCR(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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -