📄 intalib.s
字号:
* The LR value is offset from the vector address by the size of the * bla and other instructions preceding it in excConnectCode (or in * excExtConnectCode if excExtendedVectors is in effect). For the * "normal" interrupts handled here, the difference varies depending * on whether the processor also implements "critical" exceptions. * * In either case, the offset amounts to 4 * (ENT_OFF + 1) for "short" * vectors or 4 * EXT_ISR_OFF for extended vectors; however these symbols * are defined in excArchLib.c and the definitions are not accessible here. */ lis p6, HIADJ(excExtendedVectors) lwz p6, LO(excExtendedVectors)(p6) /* get excExtendedVectors */ cmpwi p6, 0 /* if 0, short vectors */ beq shortVec li p6, 20 /* 4 * (EXT_ISR_OFF - (ENT_OFF + 1)) */shortVec:#ifdef _EXC_OFF_CRTL addi p6, p6, 28 /* 4 * (ENT_OFF + 1) */#else /* _EXC_OFF_CRTL */ addi p6, p6, 12 /* 4 * (ENT_OFF + 1) */#endif /* _EXC_OFF_CRTL */ sub p0, p0, p6 stw p0, _PPC_ESF_VEC_OFF(sp) /* store to ESF */#if (defined (_EXC_OFF_DECR) || defined (_EXC_OFF_PIT))#if (defined (_EXC_OFF_DECR)) cmpwi p0, _EXC_OFF_DECR#else /* _EXC_OFF_DECR */ cmpwi p0, _EXC_NEW_OFF_PIT#endif /* _EXC_OFF_DECR */ bne noActionIntEnt /* wvEvtClass&(WV_CLASS_1|WV_ON) == (WV_CLASS1|WV_ON) */ lis p6, HIADJ(wvEvtClass) /* is windview on? */ lwz p4, LO(wvEvtClass)(p6) lis p0, HI(WV_CLASS_1_ON) ori p0, p0, LO(WV_CLASS_1_ON) and p6, p4, p0 cmpw p6, p0 bne trgCheckIntEnt /* if not, go to trigger */ lis p6, HIADJ(_func_evtLogT0) /* check if logging func */ lwz p0, LO(_func_evtLogT0)(p6) /* exists */ cmpwi p0, 0 beq trgCheckIntEnt /* if NULL, go to trigger */ stwu sp, -(FRAMEBASESZ+ _STACK_ALIGN_SIZE)(sp) /* carve stack frame */ mfspr p6, LR /* read lr to p6 */ stw p6, FRAMEBASESZ (sp) /* save lr */ /* Make an event id, and generate event */ mtlr p0 /* call through the funcptr */ li p0, PPC_DECR_INT_ID blrl lwz p6, FRAMEBASESZ (sp) mtspr LR, p6 /* restore lr */ addi sp, sp, FRAMEBASESZ + _STACK_ALIGN_SIZE /* release stack */trgCheckIntEnt: lis p6, HIADJ(trgEvtClass) /* are there any triggers? */ lwz p4, LO(trgEvtClass)(p6) lis p1, HI(TRG_CLASS_1_ON) ori p1, p1, LO(TRG_CLASS_1_ON) and p4, p4, p1 cmpw p1, p4 bne noActionIntEnt /* if none, exit */ lis p6, HIADJ(_func_trgCheck) /* check if trgCheck func */ lwz p1, LO(_func_trgCheck)(p6) /* exists, leave it in p1 */ cmpwi p1, 0 beq noActionIntEnt /* if none, exit */ stwu sp, -(FRAMEBASESZ+ _STACK_ALIGN_SIZE)(sp) /* carve stack frame */ mflr p6 /* read lr to p6 */ stw p6, FRAMEBASESZ (sp) /* save lr */ mtlr p1 li p0, PPC_DECR_INT_ID li p1, 0 li p2, 0 li p3, 0 li p4, 0 li p5, 0 li p6, 0 li p7, 0 blrl /* check for triggers */ lwz p6, FRAMEBASESZ (sp) mtspr LR, p6 /* restore lr */ addi sp, sp, FRAMEBASESZ + _STACK_ALIGN_SIZE /* release stack */#endif /* (defined (_EXC_OFF_DECR) || defined (_EXC_OFF_PIT)) */ ba noActionIntEnt#endif /* WV_INSTRUMENTATION */FUNC_END(intEnt)/********************************************************************************* intExit - exit an interrupt service routine** Check the kernel ready queue to determine if rescheduling is necessary. If* no higher priority task has been readied, and no kernel work has been queued,* then we return to the interrupted task.** If rescheduling is necessary, the context of the interrupted task is saved in* its associated TCB with the PC, MSR in SRR0, SRR1.* This routine must be branched to when exiting an interrupt service routine.* This normally happens automatically, from the stub built by excIntConnect (2).** This routine can NEVER be called from C.** INTERNAL* This routine must preserve all registers up until the context is saved,* so any registers that are used to check the queues must first be saved on* the stack.** At the call to reschedule the value of taskIdCurrent must be in p0.** SEE ALSO: excIntConnect(2)* void intExit ()*/FUNC_BEGIN(intExit) mfmsr p0 /* read msr to p0 */#ifdef _PPC_MSR_RI RI_MASK (p0, p0) /* mask RI bit */#endif /* _PPC_MSR_RI */ INT_MASK(p0, p0) /* clear EE and RI bit */ mtmsr p0 /* DISABLE INTERRUPT */ isync /* synchronize */#ifdef WV_INSTRUMENTATION /* windview instrumentation - BEGIN * log event if work has been done in the interrupt handler. *//* this is the idea: if workQIsEmpty EVT_CTX_0(EVENT_INT_EXIT) else EVT_CTX_0(EVENT_INT_EXIT_K)*/ lis p6, HIADJ(evtAction) /* is WindView on? */ lwz p0, LO(evtAction)(p6) cmpwi p0, 0 beq noActionIntExit /* if not, exit */ lis p6, HIADJ(wvEvtClass) /* is windview on? */ lwz p4, LO(wvEvtClass)(p6) lis p1, HI(WV_CLASS_1_ON) ori p1, p1, LO(WV_CLASS_1_ON) and p6, p4, p1 cmpw p1, p6 bne trgCheckIntExit /* if not, go to trigger */ lis p3, HIADJ(workQIsEmpty) /* is work queue empty? */ lwz p2, LO(workQIsEmpty)(p3) cmpwi p2, 0 beq intExitNoK li p0, EVENT_INT_EXIT_K b intExitContintExitNoK: li p0, EVENT_INT_EXIT /* get event id */intExitCont: stwu sp, -(FRAMEBASESZ+_STACK_ALIGN_SIZE)(sp) /* stack frame * / mfspr p6, LR /* read lr to p6 */ stw p6, FRAMEBASESZ (sp) /* save lr */ lis p6, HIADJ(_func_evtLogT0) lwz p1, LO(_func_evtLogT0)(p6) mtlr p1 blrl lwz p6, FRAMEBASESZ (sp) mtspr LR, p6 /* restore lr */ addi sp, sp, FRAMEBASESZ + _STACK_ALIGN_SIZE /* release stack */trgCheckIntExit: lis p6, HIADJ(trgEvtClass) /* are there any triggers? */ lwz p4, LO(trgEvtClass)(p6) lis p1, HI(TRG_CLASS_1_ON) ori p1, p1, LO(TRG_CLASS_1_ON) and p4, p4, p1 cmpw p1, p4 bne noActionIntExit /* if none, exit */ lis p3, HIADJ(workQIsEmpty) /* is work queue empty? */ lwz p2, LO(workQIsEmpty)(p3) cmpwi p2, 0 beq trgIntExitNoK li p0, EVENT_INT_EXIT_K b trgIntExitConttrgIntExitNoK: li p0, EVENT_INT_EXIT /* get event id */trgIntExitCont: lis p6, HIADJ(_func_trgCheck) /* check if trgCheck func */ lwz p1, LO(_func_trgCheck)(p6) /* exists */ cmpwi p1, 0 beq noActionIntExit /* if none, exit */ stwu sp, -(FRAMEBASESZ+_STACK_ALIGN_SIZE)(sp) /* stack frame * / mfspr p6, LR /* read lr to p6 */ stw p6, FRAMEBASESZ (sp) /* save lr */ mtlr p1 li p1, 0 /* CLASS1_INDEX */ li p2, 0 li p3, 0 li p4, 0 li p5, 0 li p6, 0 li p7, 0 blrl /* check for triggers */ lwz p6, FRAMEBASESZ (sp) mtspr LR, p6 /* restore lr */ addi sp, sp, FRAMEBASESZ + _STACK_ALIGN_SIZE /* release stack */noActionIntExit:/* windview instrumentation - END */#endif /* WV_INSTRUMENTATION */ lwz r0, _PPC_ESF_R0(sp) /* restore general register 0 */ lwz r2, _PPC_ESF_R2(sp) /* restore general register 2 */ lwz p4, _PPC_ESF_P4(sp) /* restore general reg 7 */ lwz p5, _PPC_ESF_P5(sp) /* restore general reg 8 */ lwz p6, _PPC_ESF_P6(sp) /* restore general reg 9 */ lwz p7, _PPC_ESF_P7(sp) /* restore general reg 10 */ lwz r11, _PPC_ESF_R11(sp) /* restore general reg 11 */ lwz r12, _PPC_ESF_R12(sp) /* restore general reg 12 */ lwz r13, _PPC_ESF_R13(sp) /* restore general reg 13 */ lwz p0, _PPC_ESF_XER(sp) /* load the saved XER to P0 */ mtspr XER, p0 /* restore XER */ lwz p0, _PPC_ESF_CTR(sp) /* load the saved CTR to P0 */ mtspr CTR, p0 /* restore CTR */#if (CPU==PPC601) lwz p0, _PPC_ESF_MQ(sp) /* load the saved MQ to P0 */ mtspr MQ, p0 /* restore MQ */#endif /* (CPU==PPC601) */#if (CPU==PPC85XX) lwz p0, _PPC_ESF_SPEFSCR(sp) /* load the saved MQ to P0 */ mtspr SPEFSCR, p0 /* restore MQ */#endif /* (CPU==PPC85XX) */ lis p0, HIADJ(errno) lwz p3, _PPC_ESF_ERRNO(sp) /* load errno value */ stw p3, LO(errno)(p0) /* restore errno value */ lwz p0, _PPC_ESF_LR(sp) /* load the saved LR to P0 */ mtspr LR, p0 /* restore LR */ lis p1, HIADJ(intCnt) lwz p2, LO(intCnt)(p1) /* load intCnt value to P2 */ addi p2, p2, -1 /* decrement intCnt value */ stw p2, LO(intCnt)(p1) /* save new intCnt value */ mfspr p0, SPRG1 /* load nesting count to P0 */ addi p0, p0, -1 /* decrement nesting count */ mtspr SPRG1, p0 /* update nesting count */ /* * we don't rely on the global variable <intCnt> because * windTickAnnounce() modifies it to fake an ISR context. */ cmpwi p0, 0 /* SPRG1 says nested int? */ bne intRte /* yes, just return */ lis p2, HIADJ(kernelState) lwz p0, LO(kernelState)(p2) /* load kernelState to P0 */ cmpwi p0, 0 /* if kernelState == TRUE */ bne intRte /* just clean up and return */ lis p0, HIADJ(taskIdCurrent) lwz p0, LO(taskIdCurrent)(p0) /* load taskIdCurrent to P0 */ lis p1, HIADJ(readyQHead) lwz p1, LO(readyQHead)(p1) /* load readyQHead to P1 */ cmpw p0, p1 /* comp to highest ready task */ beq intRte /* return from interrput */ lwz p1, WIND_TCB_LOCK_CNT(p0) /* load p1 with task lock cnt */ cmpwi p1, 0 /* if task preemption allowed */ beq saveIntContext /* then save task context */ lwz p1, WIND_TCB_STATUS(p0) /* set p2 to task's status */ cmpwi p1, 0 /* if task ready to run */ bne saveIntContext /* if no, save context */intRte: lwz p1, _PPC_ESF_P1(sp) /* restore p1 */ lwz p2, _PPC_ESF_P2(sp) /* restore p2 */ lwz p3, _PPC_ESF_P3(sp) /* restore general reg 6 */ lwz p0, _PPC_ESF_CR(sp) mtcrf 255,p0 /* restore CR */#ifdef _WRS_TLB_MISS_CLASS_SW /* * Turn off MMU to keep SW TLB Miss handler from corrupting * SRR0, SRR1. */ lwz p0, _PPC_ESF_PC(sp) /* load PC to P0 and save */ mtspr SPRG0,p0 /* it temporarily in SPRG0 */ lwz p0, _PPC_ESF_MSR(sp) /* load MSR to P0 and save */ mtspr SPRG3, p0 /* it temporarily in SPRG3 */ lwz p0, _PPC_ESF_P0(sp) /* restore P0 and save */ mtspr SPRG2,p0 /* it temporarily in SPRG2 */ lwz sp, 0(sp) /* restore the SP(R1) */ /* turn off the MMU before */ /* to restore the SRR0/SRR1 */ mfmsr p0 /* read msr */ rlwinm p0,p0,0,28,25 /* disable Instr/Data trans */ mtmsr p0 /* set msr */ isync /* synchronization */ mfspr p0, SPRG0 /* load SRR0 to p0 */ mtspr SRR0, p0 /* restore SRR0 (PC) */ mfspr p0, SPRG3 /* load SRR1 to p0 */ mtspr SRR1, p0 /* restore SRR1 (MSR) */ mfspr p0, SPRG2 /* restore P0 from SPRG2 */#else /* !_WRS_TLB_MISS_CLASS_SW */ /* * both MMU-less and MMU with miss handler in HW use this code */ lwz p0, _PPC_ESF_PC(sp) /* load PC to P0 and */ mtspr SRR0, p0 /* restore SRR0 (PC) */ lwz p0, _PPC_ESF_MSR(sp) /* load MSR to P0 and */ mtspr SRR1, p0 /* restore SRR1 (MSR) */ lwz p0, _PPC_ESF_P0(sp) /* restore p0 */ lwz sp, 0(sp) /* pop up stack */#endif /* _WRS_TLB_MISS_CLASS_SW */ rfi /* return to previus context *//* rescheduling is necessary. p0 contains taskIdCurrent. * interrupts are still locked out */saveIntContext: /* * when we arrive to this point * p0 = taskIdCurrent * p2 = kernelState MSB address * p3 = errno */ li p1, 1 stw p1, LO(kernelState)(p2) /* kernelState = TRUE */ stw p3, WIND_TCB_ERRNO(p0) /* save errno */ lwz p1, _PPC_ESF_PC(sp) /* load PC to P1 */ stw p1, WIND_TCB_PC(p0) /* store PC in tcb */ lwz p1, _PPC_ESF_MSR(sp) /* read MSR to P1 */ stw p1, WIND_TCB_MSR(p0) /* store msr in tcb */ lwz p1, _PPC_ESF_LR(sp) /* load LR to P1 */ stw p1, WIND_TCB_LR(p0) /* store LR to tcb */ stw r0, WIND_TCB_R0(p0) /* store R0 to tcb */ stw r2, WIND_TCB_R2(p0) /* store R2 to tcb */ lwz p1, _PPC_ESF_P0(sp) /* load saved P0 */ stw p1, WIND_TCB_P0(p0) /* store P0 in tcb */ lwz p1, _PPC_ESF_P1(sp) /* load saved P1 */ stw p1, WIND_TCB_P1(p0) /* store P1 to tcb */ lwz p1, _PPC_ESF_P2(sp) /* load saved P2 */ stw p1, WIND_TCB_P2(p0) /* store P2 to tcb */ lwz p1, _PPC_ESF_P3(sp) /* load saved P3 */ stw p1, WIND_TCB_P3(p0) /* store P3 to tcb */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -