📄 os_cpu_a.s
字号:
lwz 0, STK_OFFSET_R0(1) /* Restore General-Purpose Register 0 */ addi 1, 1, STK_CTX_SIZE /* Adjust the stack pointer */ rfi /* Return to the interrupted task */ .endm/*********************************************************************************************************** OSCtxSw** Description: Performs a Context switch from a task. This function is ALWAYS called with interrupts * DISABLED.** OSCtxSw() implements the following pseudo-code:** Save CPU registers;* OSTCBCur->OSTCBStkPtr = SP;* OSTaskSwHook();* OSPrioCur = OSPrioHighRdy;* OSTCBCur = OSTCBHighRdy;* SP = OSTCBHighRdy->OSTCBStkPtr;* Restore CPU registers* Execute the return-from-interrupt instruction;* ** The stack frame of the task to suspend will look as follows when OSCtxSw() is done:** OSTCBHighRdy->OSTCBStkPtr + 0x00 Back chain (LOW Memory)* + 0x04 New Link Register* + 0x08 Machine-State Register* + 0x0C Return Address* + 0x10 Link Register* + 0x14 Count Register* + 0x18 Fixed-Point Exception Register* + 0x1C Condition Register* + 0x20 User SPR General-Purpose Register 0 * + 0x24 GPR0* + 0x28 GPR2* + 0x2C GPR3* + 0x30 GPR4* |* |* \ /* V* + 0x9C GPR31 (HIGH MEMORY)** The stack frame of the task to resume looks as follows:* * OSTCBHighRdy->OSTCBStkPtr + 0x00 Back chain (LOW Memory)* + 0x04 New Link Register* + 0x08 Machine-State Register* + 0x0C Return Address* + 0x10 Link Register* + 0x14 Count Register* + 0x18 Fixed-Point Exception Register* + 0x1C Condition Register* + 0x20 User SPR General-Purpose Register 0 * + 0x24 GPR0* + 0x28 GPR2* + 0x2C GPR3* + 0x30 GPR4* |* |* \ /* V * + 0x9C GPR31 (HIGH MEMORY)***********************************************************************************************************/ MACRO0(OSCtxSw) /* ******* SAVE CURRENT TASK'S CONTEXT ******* */ stwu 1,-STK_CTX_SIZE(1) /* Adjust the stack pointer */ stw 0, STK_OFFSET_R0(1) /* Save General-Purpose Register 0 */ stmw 2, STK_OFFSET_R2R31(1) /* Save General-Purpose Registers 2-31 */ mflr 0 stw 0, STK_OFFSET_LR(1) /* Save the Link Register */ mfctr 0 stw 0, STK_OFFSET_CTR(1) /* Save the Count Register */ mfxer 0 stw 0, STK_OFFSET_XER(1) /* Save the Fixed-Point Exception Register */ mfcr 0 stw 0, STK_OFFSET_CR(1) /* Save the Condition Register */ mfspr 0, 0x100 stw 0, STK_OFFSET_USPRG0(1) /* Save User SPR General-Purpose Register 0 */ mfsrr1 0 stw 0, STK_OFFSET_MSR(1) /* Save the Machine-State Register */ mfsrr0 0 stw 0, STK_OFFSET_PC(1) /* Save the return address */ lis 4, OSTCBCur@h /* Save the current task's stack pointer */ ori 4, 4, OSTCBCur@l lwz 5, 0(4) stw 1, 0(5) lis 0, OSTaskSwHook@h /* Call OSTaskSwHook() */ ori 0, 0, OSTaskSwHook@l mtlr 0 blrl lis 4, OSPrioHighRdy@h /* Update the current priority */ ori 4, 4, OSPrioHighRdy@l lbz 5, 0(4) lis 6, OSPrioCur@h ori 6, 6, OSPrioCur@l stb 5, 0(6) lis 4, OSTCBHighRdy@h /* Update the current TCB */ ori 4, 4, OSTCBHighRdy@l lwz 5, 0(4) lis 6, OSTCBCur@h ori 6, 6, OSTCBCur@l stw 5, 0(6) lwz 1, 0(5) /* Load the new task's stack pointer */ /* ******** RESTORE NEW TASK'S CONTEXT ******* */ lwz 0, STK_OFFSET_MSR(1) /* Restore the Machine-State Register to SRR1 */ mtsrr1 0 lwz 0, STK_OFFSET_PC(1) /* Restore the return address to SRR0 */ mtsrr0 0 lwz 0, STK_OFFSET_USPRG0(1) /* Restore User SPR General-Purpose Register 0 */ mtspr 0x100, 0 lwz 0, STK_OFFSET_CR(1) /* Restore the Condition Register */ mtcr 0 lwz 0, STK_OFFSET_XER(1) /* Restore the Fixed-Point Exception Register */ mtxer 0 lwz 0, STK_OFFSET_CTR(1) /* Restore the Count Register */ mtctr 0 lwz 0, STK_OFFSET_LR(1) /* Restore the Link Register */ mtlr 0 lmw 2, STK_OFFSET_R2R31(1) /* Restore General-Purpose Registers 2-31 */ lwz 0, STK_OFFSET_R0(1) /* Restore General-Purpose Register 0 */ addi 1, 1, STK_CTX_SIZE /* Adjust the stack pointer */ rfi /* Return to the interrupted task */ .endm/*********************************************************************************************************** OSTickISR** Description: This macro is used to process uC/OS-II tick interrupts, which are produced by the * programmable interval timer. This code saves the current task's context before calling * OSTimeTick(), uC/OS-II's CPU-independent routine for processing these interrupts. * * The interrupted task's context is saved onto its stack as follows:** OSTCBHighRdy->OSTCBStkPtr + 0x00 Back chain (LOW Memory)* + 0x04 New Link Register* + 0x08 Machine-State Register* + 0x0C Return Address* + 0x10 Link Register* + 0x14 Count Register* + 0x18 Fixed-Point Exception Register* + 0x1C Condition Register* + 0x20 User SPR General-Purpose Register* + 0x24 GPR0* + 0x28 GPR2* + 0x2C GPR3* + 0x30 GPR4* |* |* \ /* V* + 0x9C GPR31 (HIGH MEMORY)***********************************************************************************************************/ MACRO0(OSTickISR) /* ******* SAVE CURRENT TASK'S CONTEXT ******* */ stwu 1, -STK_CTX_SIZE(1) /* Adjust the stack pointer */ stw 0, STK_OFFSET_R0(1) /* Save General-Purpose Register 0 */ stmw 2, STK_OFFSET_R2R31(1) /* Save General-Purpose Registers 2-31 */ mflr 0 stw 0, STK_OFFSET_LR(1) /* Save the Link Register */ mfctr 0 stw 0, STK_OFFSET_CTR(1) /* Save the Count Register */ mfxer 0 stw 0, STK_OFFSET_XER(1) /* Save the Fixed-Point Exception Register */ mfcr 0 stw 0, STK_OFFSET_CR(1) /* Save the Condition Register */ mfspr 0, 0x100 stw 0, STK_OFFSET_USPRG0(1) /* Save User SPR General-Purpose Register 0 */ mfsrr1 0 stw 0, STK_OFFSET_MSR(1) /* Save the Machine-State Register */ mfsrr0 0 stw 0, STK_OFFSET_PC(1) /* Save the return address */ lis 4, OSIntNesting@h /* See if OSIntNesting == 0 */ ori 4, 4, OSIntNesting@l lbz 5, 0(4) addic. 5, 5, 0 bc 0x04, 0x02, TICK_INC_NESTING lis 6, OSTCBCur@h /* Save the current task's stack pointer */ ori 6, 6, OSTCBCur@l lwz 7, 0(6) stw 1, 0(7)TICK_INC_NESTING: addi 5, 5, 1 /* Increment OSIntNesting */ stb 5, 0(4) lis 0, 0x0800 /* Clear the PIT interrupt */ mttsr 0 lis 0, OSTimeTick@h /* Call OSTimeTick() */ ori 0, 0, OSTimeTick@l mtlr 0 blrl lis 0, OSIntExit@h /* Call OSIntExit() */ ori 0, 0, OSIntExit@l mtlr 0 blrl /* **** RESTORE INTERRUPTED TASK'S CONTEXT *** */ lwz 0, STK_OFFSET_MSR(1) /* Restore the Machine-State Register to SRR1 */ mtsrr1 0 lwz 0, STK_OFFSET_PC(1) /* Restore the return address to SRR0 */ mtsrr0 0 lwz 0, STK_OFFSET_USPRG0(1) /* Restore User SPR General-Purpose Register 0 */ mtspr 0x100, 0 lwz 0, STK_OFFSET_CR(1) /* Restore the Condition Register */ mtcr 0 lwz 0, STK_OFFSET_XER(1) /* Restore the Fixed-Point Exception Register */ mtxer 0 lwz 0, STK_OFFSET_CTR(1) /* Restore the Count Register */ mtctr 0 lwz 0, STK_OFFSET_LR(1) /* Restore the Link Register */ mtlr 0 lmw 2, STK_OFFSET_R2R31(1) /* Restore General-Purpose Registers 2-31 */ lwz 0, STK_OFFSET_R0(1) /* Restore General-Purpose Register 0 */ addi 1, 1, STK_CTX_SIZE /* Adjust the stack pointer */ rfi /* Return to the interrupted task */ .endm/*********************************************************************************************************** OS_NULL_NON_CRITICAL** Description : This exception handler simply returns to the interrupted code.**********************************************************************************************************/ MACRO0(OS_NULL_NON_CRITICAL) rfi .endm/*********************************************************************************************************** OS_NULL_CRITICAL** Description : This exception handler simply returns to the interrupted code.**********************************************************************************************************/ MACRO0(OS_NULL_CRITICAL) rfci .endm/*********************************************************************************************************** PowerPC405 Interrupt-Handler Table** This is the interrupt-handler table used by the PowerPC to appropriately invoke handlers for various * types of interrupts. The interrupts are the results of exceptions, each of which corresponds to an * offset into this table. When the interrupt associated with a given expection occurs, the PowerPC adds * the offset for that exception to this table's base address, which is stored in the Exception-Vector * Prefix Register (EVPR) by OSStartHighRdy(). The code at the resulting address should represent the * handler for the exception.** The table entries for the critical input exception (offset 0x0100) and the external input exception * (offset 0x0500) span 256 (0x100) bytes each, which is enough room to accomodate uC/OS-II's handlers * for those interrupts, OS_CPU_ISR_CRITICAL() and OS_CPU_ISR_NON_CRITICAL(), respectively. The entry * for the programmable-interval timer exception, however, only covers 16 bytes, so OSTickISR(), * uC/OS-II's handler for timer exceptions, must be placed at another location. Since the entries at * offsets 0x1300 and 0x1400 don't correspond to any exceptions, OSTickISR() is placed there, and a * branch to that location is inserted at offset 0x1000, the actual offset corresponding to the * programmable-interval timer exception. ** All table entries that are not currently used by uC/OS-II contain null routines that simply return* from the interrupt without performing any actions. These routines can be replaced if an application* requires support for additional types of exceptions.**********************************************************************************************************/_vectorbase:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -