📄 windalib.s
字号:
instrumentDispatch3: LDR lr, L$_wvEvtClass /* is instrumentation on? */ LDR lr, [lr] AND lr, lr, #WV_CLASS_1_ON TEQS lr, #WV_CLASS_1_ON BNE trgInst3 /* branch if not */ /* * try to determine if the task is running at an inherited priority * and log a different event if so * * register usage : * r0 : eventId * r1 : taskId * r2 : task priority * r3 : scratch (for task priority normal) * * These have been used to be in the right place for the call to the * logging routine */ LDR r1, L$_taskIdCurrent LDR r1, [r1] /* r1 = taskId */ LDR r2, [r1, #WIND_TCB_PRIORITY] /* r2 = task priority */ LDR r3, [r1, #WIND_TCB_PRI_NORMAL] CMPS r3, r2 MOVHI r0, #EVENT_WIND_EXIT_DISPATCH_PI /* r0 = eventId */ MOVLS r0, #EVENT_WIND_EXIT_DISPATCH LDR r12, L$__func_evtLogTSched /* get address of fn pointer */#if (ARM_THUMB) LDR r12, [r12] /* get function address */ BL FUNC(arm_call_via_r12) /* and call it */#else MOV lr, pc /* call function */ LDR pc, [r12]#endif /* (ARM_THUMB) */trgInst3: LDR lr, L$_trgEvtClass /* is instrumentation on? */ LDR lr, [lr] AND lr, lr, #TRG_CLASS_1_ON TEQS lr, #TRG_CLASS_1_ON BNE resumeDispatch3 /* branch if not */ /* * There are 8 parameters to the trgCheck function: * r0 <- eventId * r1 <- index = TRG_CLASS1_INDEX * r2 <- obj (NULL) * r3 <- arg1 (NULL - unused) * stack <- arg2 (NULL - unused) * stack <- arg3 (NULL - unused) * stack <- arg4 (NULL - unused) * stack <- arg5 (NULL - unused) */ MOV r3, #0 /* NULL parms for stack */ MOV r2, #0 MOV r1, #0 MOV r0, #0 STMFD sp!, {r0-r3} /* push stack-based parms */ /* * try to determine if the task is running at an inherited priority * and log a different event if so */ LDR r12, L$_taskIdCurrent LDR r12, [r12] /* r12 -> TCB */ LDR r0, [r12, #WIND_TCB_PRIORITY] LDR r1, [r12, #WIND_TCB_PRI_NORMAL] CMPS r1, r0 MOVHI r0, #EVENT_WIND_EXIT_DISPATCH_PI MOVLS r0, #EVENT_WIND_EXIT_DISPATCH /* r0 <- eventId */ MOV r1, #TRG_CLASS1_INDEX /* r1 <- TRG_CLASS1_INDEX */ /* r2 <- NULL (from above) */ /* r3 <- NULL (from above) */ LDR r12,L$__func_trgCheck /* trigCheck routine */#if (ARM_THUMB) LDR r12, [r12] /* get function address */ BL FUNC(arm_call_via_r12) /* and call it */#else MOV lr, pc /* call function */ LDR pc, [r12]#endif /* (ARM_THUMB) */ ADD sp, sp, #16 /* strip 4 parameters from stack */ B resumeDispatch3 /* windview instrumentation - END */#endif /* WV_INSTRUMENTATION *//********************************************************************************* idle - spin here until there is more work to do** When the kernel is idle, we spin here continually checking for work to do.*/idle:#ifdef WV_INSTRUMENTATION /* windview instrumentation - BEGIN * enter idle state */ LDR lr, L$_evtAction /* is instrumentation on? */ LDR lr, [lr] TEQS lr, #0 BNE instrumentIdle /* branch if so */ /* instrumentation currently disabled */resumeIdle: /* windview instrumentation - END */#endif /* WV_INSTRUMENTATION */ /* unlock interrupts */ MRS r0, cpsr BIC r0, r0, #I_BIT MSR cpsr, r0 /* set idle flag for spyLib */ LDR r1, L$_kernelIsIdle MOV r0, #1 STR r0, [r1] /* now idle until there's something in the work queue */ LDR r2, L$_workQIsEmptyidleLoop: /* * r1 -> kernelIsIdle * r2 -> workQIsEmpty */ LDR r0, [r2] TEQS r0, #0 /* work queue still empty? */ BNE idleLoop /* loop if so */ /* * there is now something in the work queue * unset the idle flag and go do the work */ MOV r0, #0 STR r0, [r1] B doWork/******************************************************************************/#ifdef WV_INSTRUMENTATION /* windview instrumentation - BEGIN * enter idle state */instrumentIdle: /* lock interrupts */ MRS r0, cpsr ORR r0, r0, #I_BIT MSR cpsr, r0 /* * INTERRUPTS DISABLED */ /* Check if we need to log this event */ LDR lr, L$_wvEvtClass /* load event class */ LDR lr, [lr] AND lr, lr, #WV_CLASS_1_ON /* examine to see if action */ TEQS lr, #WV_CLASS_1_ON BNE idleCheckTrg /* jump if no action */ MOV r0, #EVENT_WIND_EXIT_IDLE /* param to log function */ LDR r12, L$__func_evtLogT0 /* get address of fn pointer */#if (ARM_THUMB) LDR r12, [r12] /* get function address */ BL FUNC(arm_call_via_r12) /* and call it */#else MOV lr, pc /* call function */ LDR pc, [r12]#endif /* (ARM_THUMB) */idleCheckTrg: LDR lr, L$_trgEvtClass /* is instrumentation on? */ LDR lr, [lr] AND lr, lr, #TRG_CLASS_1_ON TEQS lr, #TRG_CLASS_1_ON BNE resumeIdle /* branch if not */ /* * There are 8 parameters to the trgCheck function: * r0 <- eventId * r1 <- index = TRG_CLASS1_INDEX * r2 <- obj (NULL) * r3 <- arg1 (NULL - unused) * stack <- arg2 (NULL - unused) * stack <- arg3 (NULL - unused) * stack <- arg4 (NULL - unused) * stack <- arg5 (NULL - unused) */ MOV r3, #0 /* NULL parms for stack */ MOV r2, #0 MOV r1, #0 MOV r0, #0 STMFD sp!, {r0-r3} /* push stack-based parms */ MOV r0, #EVENT_WIND_EXIT_IDLE /* r0 <- eventId */ MOV r1, #TRG_CLASS1_INDEX /* r1 <- TRG_CLASS1_INDEX */ /* r2 <- NULL (from above) */ /* r3 <- NULL (from above) */ LDR r12,L$__func_trgCheck /* trigCheck routine */#if (ARM_THUMB) LDR r12, [r12] /* get function address */ BL FUNC(arm_call_via_r12) /* and call it */#else MOV lr, pc /* call function */ LDR pc, [r12]#endif /* (ARM_THUMB) */ ADD sp, sp, #16 /* strip 4 parameters from stack */ B resumeIdle /* windview instrumentation - END */#endif /* WV_INSTRUMENTATION *//********************************************************************************* doSwapHooks - execute the tasks' swap hooks*/doSwapHooks: /* * r4 -> new TCB * r5 -> old TCB * r6[31..16] = OR of swap-in and swap-out masks * * before entering loop, make sure that all values we care about * have been moved out of r0-r3 as the called routine is at liberty * to corrupt these */ LDR r7, L$_taskSwapTable /* get adrs of task switch rtn list */doSwapHooksLoop: MOVS r6, r6, LSL #1 /* check MS bit */ MOVCS r0, r5 /* if set, set args to old, new */ MOVCS r1, r4#if (ARM_THUMB) LDRCS r2, [r7] BLCS FUNC(arm_call_via_r2) /* returns in ARM state */#else MOVCS lr, pc /* ..and call routine */ LDRCS pc, [r7]#endif /* (ARM_THUMB) */ TEQS r6, #0 /* all done? */ ADDNE r7, r7, #4 /* if not, bump routine pointer */ BNE doSwapHooksLoop /* ..and go again */ /* * have now processed all bits set in the swap mask * NOTE: MC68K code reloads from taskIdCurrent here but MIPS code does * not - it should not be necessary */ LDR r7, L$_taskSwitchTable /* any global switch hooks? */ LDR r2, [r7], #4 /* get task switch routine */ TEQS r2, #0 /* present? */ BEQ dispatch /* branch if not */ /* FALL THROUGH to doSwitchHooks *//********************************************************************************* doSwitchHooks - execute the global switch hooks** r2 -> first routine in taskSwitchTable (!= 0)* r4 -> new current task* r5 -> previous task* r7 -> taskSwitchTable+4*/doSwitchHooks: MOV r0, r5 /* set args to old, new */ MOV r1, r4#if (ARM_THUMB) BL FUNC(arm_call_via_r2) /* returns in ARM state */#else MOV lr, pc /* ..and call routine */ MOV pc, r2#endif /* (ARM_THUMB) */ LDR r2, [r7], #4 /* get next routine */ TEQS r2, #0 /* end of table? */ BNE doSwitchHooks /* branch if not */ /* * NOTE: MC68K code reloads from taskIdCurrent here but MIPS code does * not - it should not be necessary */ B dispatch/********************************************************************************* doWork - empty the work queue* doWorkUnlock - unlock interrupts and empty the work queue*/doWorkUnlock: /* unlock interrupts */ MRS r0, cpsr BIC r0, r0, #I_BIT MSR cpsr, r0doWork:#if (ARM_THUMB) LDR r12, L$_workQDoWork /* empty the work queue */ BL FUNC(arm_call_via_r12) /* returns in ARM state */#else BL FUNC(workQDoWork) /* empty the work queue */#endif /* (ARM_THUMB) */ LDR r4, [r8] /* r4 -> TCB of new current task */ LDR r5, L$_readyQHead LDR r5, [r5] /* r5 -> TCB highest task */ TEQS r5, #0 /* anyone ready? */ BEQ idle /* branch if not */ TEQS r4, r5 /* current == highest? */ BEQ dispatch /* if so, despatch */ B switchTasks /* if not, do switch */#else /* PORTABLE */ /* * PORTABLE code - branch to portable reschedule * 68k and i86 architectures have a BL to reschedule here rather * than a branch - this makes no sense since reschedule does not * return (it calls windLoadContext). */ B FUNC(reschedule)/********************************************************************************* windLoadContext - load the register context from the control block** The errno and PSR of the task to be entered, (the one reschedule chose),* are loaded from its control block. Its registers are then reloaded and* it is entered using a LDM instruction.** NOMANUAL* void windLoadContext ()*/_ARM_FUNCTION_CALLED_FROM_C(windLoadContext) LDR r0, L$_taskIdCurrent LDR r0, [r0] /* r0 -> TCB */ /* restore _fpStatus from TCB */ LDR r1, [r0, #WIND_TCB_FPSTATUS] LDR r2, L$__fpStatus STR r1, [r2] /* restore errno from TCB */ LDR r1, [r0, #WIND_TCB_ERRNO] LDR r2, L$_errno STR r1, [r2] /* get task's saved status and put it in svc_spsr */ LDR r1, [r0, #WIND_TCB_CPSR] /* get status */ MSR spsr, r1 /* and put it in place */ /* load all regs and reenter task */ ADD r0, r0, #WIND_TCB_REGS /* r0 -> task regs */ LDMIA r0, {r0-r12,sp,lr,pc}^#endif /* !PORTABLE *//********************************************************************************* windIntStackSet - set the interrupt stack pointer** This routine sets the interrupt stack pointer to the specified address.* On the ARM, this is a null routine because the real work is done* by sysIntStackSplit in the BSP.** NOMANUAL* void windIntStackSet* (* char *pBotStack /@ pointer to bottom of interrupt stack @/* )*/#if (ARM_THUMB)_THUMB_FUNCTION(windIntStackSet) BX lr#else_ARM_FUNCTION(windIntStackSet) MOV pc, lr#endif /* (ARM_THUMB) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -