?? windalib.s
字號:
/* windALib.s - internal VxWorks kernel assembly library *//* Copyright 1984-1998 Wind River Systems, Inc. *//*modification history--------------------01r,03oct02,dtr Adding save/restore of spefscr for 85XX.01q,13jun02,jtp disable MMU during context restore for 4XX (SPR #78396)01p,25sep01,yvp fix SPR62760: Use _WRS_TEXT_SEG_START macro instead of .align.01o,24jul01,r_s fixed rlwinm instruction that was GNU specific01o,08may01,pch Add assembler abstractions (FUNC_EXPORT, FUNC_BEGIN, etc.)01n,apr1599,tpr fix bug intorduce by (SPR #24759)01m,25feb99,jgn fix scheduler bug (SPR #24759)01l,18aug98,tpr added PowerPC EC 603 support.01o,10aug98,pr replaced evtsched with function pointer _func_evtLogTSched01n,16apr98,pr modified evtAction into int3201m,23jan98,pr modified WV code accordingly to the changes made in eventP.h. cleanup01l,13dec97,pr started changes of WindView code for WV2.0. STILL IN PROGRESS01k,11jul96,pr cleanup windview instrumentation 01j,08jul96,pr added windview instrumentation - conditionally compiled01i,17jun96,tpr added PowerPC 860 support.01h,14feb96,tpr split PPC603 and PPC604.01g,16jan96,tpr reworked windLoadContext() to remove kernel bug (SPR #5657).01f,06jan96,tpr replace %hiadj and %lo by HIADJ and LO.01e,03feb95,caf cleanup.01d,30nov94,caf added _GREEN_TOOL support, changed to use r5 when saving errno in windLoadContext().01c,04nov94,yao added to save ctoc register r13. fixed miss type of mfmsr to mtmsr.01b,29sep94,yao fixed to branch to link register and link in vxTaskEntry. changed to restore original msr before saving context in windExit. changed to use constants defined in regsPpc.h so that the code is more portable. changed to use ave registers used above the frame base that the code would be independent of tools.01a,xxxxxx,yao written*//*DESCRIPTIONThis module contains internals to the VxWorks kernel.These routines have been coded in assembler because they are eitherspecific to this processor, or they have been optimized for performance.*/#define _ASMLANGUAGE#include "vxWorks.h"#include "asm.h"#include "private/taskLibP.h"#include "private/workQLibP.h"#include "private/eventP.h"#include "esf.h" /* globals */ FUNC_EXPORT(windExit) /* routine to exit mutual exclusion */ FUNC_EXPORT(windIntStackSet) /* interrupt stack set routine */ /* externals */ DATA_IMPORT(taskIdCurrent) /* current task idnetifier */ DATA_IMPORT(errno) /* error number */ DATA_IMPORT(intCnt) /* interrupt counter */ DATA_IMPORT(readyQHead) /* ready queue head */ DATA_IMPORT(kernelState) DATA_IMPORT(workQIsEmpty) DATA_IMPORT(vxIntStackBase) FUNC_IMPORT(exit) FUNC_IMPORT(workQDoWork)#define PORTABLE#ifdef PORTABLE FUNC_IMPORT(reschedule) /* optimized reschedule () routine */ FUNC_EXPORT(windLoadContext) /* needed by portable reschedule () */#endif /* PORTABLE */ _WRS_TEXT_SEG_START /********************************************************************************* emptyWorkQueue - empty work queue** This routine is called by windExit. Interrupts must be locked* when checking work queue. p0 contains old msr.*/emptyWorkQueue: /* carve frame base - equavalent to * STACK_ROUND_UP (FRAMEBASESZ+2*_PPC_REG_SIZE)) */ stwu sp, -(FRAMEBASESZ+_STACK_ALIGN_SIZE)(sp) mfspr p2, LR /* read lr to p2 */ stw p2, FRAMEBASESZ(sp) /* save lr */ stw p0, FRAMEBASESZ + _PPC_REG_SIZE(sp) /* save old msr */checkWorkQToDo: /* p2 = workQIsEmpty */ lis p2, HIADJ(workQIsEmpty) lwz p2, LO(workQIsEmpty)(p2) cmpwi p2, 0 /* test for work to do */ bne noWorkToDo /* work queue is empty */ lwz p0, FRAMEBASESZ + _PPC_REG_SIZE(sp) /* load old msr */ mtmsr p0 /* UNLOCK INTERRUPTS if neccessary */ isync /* SYNC */ bl FUNC(workQDoWork) /* empty the work */ mfmsr p0 /* load msr */ INT_MASK(p0, p1) /* mask ee bit */ mtmsr p1 /* LOCK INTERRUPT */ isync /* SYNC */ b checkWorkQToDonoWorkToDo:#ifdef WV_INSTRUMENTATION /* windview instrumentation - BEGIN *//* FIXME-PR This might be painful. in simsolaris I have solved it with a macro. here it probably makes more sense to do the check and then call the functions. I think I need to modify also the macro EVT_CTX_DSP in simsolaris For the moment I sort of patched it. It can be improved by collecting the parameters only once, for instance.*/ lis p6, HIADJ(evtAction) /* is any action on? */ lwz p0, LO(evtAction)(p6) rlwinm p1, p0, 0, 16, 31 cmpwi p1, 0 beq noActionInst /* if not, exit */ lis p6, HIADJ(wvEvtClass) /* is windview on? */ lwz p4, LO(wvEvtClass)(p6) lis p1, (WV_ON >> 16) ori p1, p1, WV_CLASS_1 and p6, p4, p1 lis p1, (WV_ON >> 16) ori p1, p1, WV_CLASS_1 cmpw p1, p6 bne trgCheckInst /* if not, check triggers */ lis p4, HIADJ(taskIdCurrent) lwz p1, LO(taskIdCurrent)(p4) lwz p2, WIND_TCB_PRIORITY(p1) /* get task priority */ lwz p3, WIND_TCB_PRI_NORMAL(p1) /* get task normal priority */ cmplw p2, p3 /* check for inheritance */ bge noInst1Inheritance /* if not, then save NODISPATCH */ li p0, EVENT_WIND_EXIT_NODISPATCH_PI /* else, save NODISPATCH_PI */ b Inst1InheritancenoInst1Inheritance: li p0, EVENT_WIND_EXIT_NODISPATCH /* get event id */Inst1Inheritance: 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_evtLogTSched) lwz p1, LO(_func_evtLogTSched)(p6) mtlr p1 blrl lwz p6, FRAMEBASESZ (sp) mtspr LR, p6 /* restore lr */ addi sp, sp, FRAMEBASESZ + _STACK_ALIGN_SIZE /* release stack */trgCheckInst: lis p6, HIADJ(trgEvtClass) /* are there any triggers? */ lwz p4, LO(trgEvtClass)(p6) lis p1, (TRG_ON >> 16) ori p1, p1, TRG_CLASS_1 and p4, p4, p1 lis p1, (TRG_ON >> 16) ori p1, p1, TRG_CLASS_1 cmpw p1, p4 bne noActionInst /* if none, exit */ lis p4, HIADJ(taskIdCurrent) lwz p1, LO(taskIdCurrent)(p4) lwz p4, WIND_TCB_PRIORITY(p1) /* get task priority */ lwz p5, WIND_TCB_PRI_NORMAL(p1) /* get task normal priority */ cmplw p4, p5 /* check for inheritance */ bge trgNoInst1Inheritance /* if not, then save NODISPATCH */ li p0, EVENT_WIND_EXIT_NODISPATCH_PI /* else, save NODISPATCH_PI */ b trgInst1InheritancetrgNoInst1Inheritance: li p0, EVENT_WIND_EXIT_NODISPATCH /* get event id */trgInst1Inheritance: lis p6, HIADJ(_func_trgCheck) /* check if trgCheck func */ lwz p1, LO(_func_trgCheck)(p6) /* exists */ cmpwi p1, 0 beq noActionInst /* if none, exit */ stwu sp, -(FRAMEBASESZ+ _STACK_ALIGN_SIZE)(sp) /* carve 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 */noActionInst: /* windview instrumentation - END */#endif lwz p2, FRAMEBASESZ(sp) /* load saved lr */ /* recover stack - should be * STACK_ROUND_UP (FRAMEBASESZ+2*_PPC_REG_SIZE)) */ addi sp, sp, FRAMEBASESZ+_STACK_ALIGN_SIZE /* recover frame stack */ mtspr LR, p2 /* restore lr */ mfmsr p0 /* return msr */ blr/******************************************************************************** windExit - PORTABLE VERSION of task level exit from kernel** This is the way out of kernel mutual exclusion. If a higher priority task* than the current task is ready, then we invoke the rescheduler. We* also invoke the rescheduler if any interrupts have occured which have added* work to the windWorkList. If rescheduling is necessary,* the context of the calling task is saved with the PC pointing at the* next instruction after the jsr to this routine. The sp in the tcb is* modified to ignore the return address on the stack. Thus the context saved* is as if this routine was never called.** NOMANUAL* void windExit ()*/ FUNC_LABEL(windExit) mfspr p0, SPRG1 /* load areWeNested */ /* since the cr bits changed here are volatile, we don't need to save */ cmpwi p0, 0 /* exiting interrupt code? */ beq taskCode /* exiting task code */ /* exiting interrupt code */ mfmsr p0 /* pass msr in p0 */ /* carve frame stack - should be * STACK_ROUND_UP (FRAMEBASESZ+2*_PPC_REG_SIZE)) */ stwu sp, -(FRAMEBASESZ + _STACK_ALIGN_SIZE)(sp) stw p0, FRAMEBASESZ(sp) /* save msr on the stack */ INT_MASK(p0, p1) /* mask EE bit */ mtmsr p1 /* LOCK INTERRUPTS */ isync /* SYNC */ mfspr p2, LR /* read lr to p2 */ stw p2, FRAMEBASESZ+_PPC_REG_SIZE(sp) /* save lr */ bl emptyWorkQueue /* empty work queue */ xor p0, p0, p0 /* clear return state */ /* p2 = &kernelState */ lis p2, HIADJ(kernelState) addi p2, p2, LO(kernelState) stw p0, 0(p2) /* release exclusion */ lwz p1, FRAMEBASESZ(sp) /* restore saved msr */ mtmsr p1 /* UNLOCK INTERRUPTS */ isync /* SYNC */ lwz p2, FRAMEBASESZ+_PPC_REG_SIZE(sp) /* load saved lr */ /* recover frame stack - should be * STACK_ROUND_UP (FRAMEBASESZ+2*_PPC_REG_SIZE)) */ addi sp, sp, FRAMEBASESZ + _STACK_ALIGN_SIZE mtspr LR, p2 /* restore lr */ blr
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -