📄 os_cpu_a.s
字号:
/*********************************************************************************************************** uC/OS-II* The Real-Time Kernel** (c) Copyright 2007, Micrium, Inc., Weston, FL* All Rights Reserved** PowerPC405** GNU C/C++ Compiler** Filename: os_cpu_a.s**********************************************************************************************************/ .file "os_cpu_a.S" .section ".vectors","ax"#define MACRO0(name) .macro name #define MACRO1(name, param1) .macro name param1#define MACRO2(name, param1, param2) .macro name param1 param2#define CONCAT(left,right) left##right #define PARAM(param) param /*********************************************************************************************************** PUBLIC FUNCTIONS**********************************************************************************************************/ .global OSStartHighRdy .global OSIntCtxSw .global OS_CPU_SR_Save .global OS_CPU_SR_Restore/*********************************************************************************************************** EXTERNAL FUNCTIONS**********************************************************************************************************/ .extern OSIntEnter .extern OSIntExit .extern BSP_CriticalIntHandler .extern BSP_NonCriticalIntHandler .extern OSTaskSwHook/*********************************************************************************************************** EXTERNAL VARIABLES**********************************************************************************************************/ .extern OSRunning .extern OSIntNesting .extern OSTCBCur .extern OSTCBHighRdy .extern OSPrioCur .extern OSPrioHighRdy/*********************************************************************************************************** CONSTANTS USED TO ACCESS TASK CONTEXT STACK**********************************************************************************************************/ .set STK_OFFSET_BC, 0 .set STK_OFFSET_NEW_LR, STK_OFFSET_BC + 4 .set STK_OFFSET_MSR, STK_OFFSET_NEW_LR + 4 .set STK_OFFSET_PC, STK_OFFSET_MSR + 4 .set STK_OFFSET_LR, STK_OFFSET_PC + 4 .set STK_OFFSET_CTR, STK_OFFSET_LR + 4 .set STK_OFFSET_XER, STK_OFFSET_CTR + 4 .set STK_OFFSET_CR, STK_OFFSET_XER + 4 .set STK_OFFSET_USPRG0, STK_OFFSET_CR + 4 .set STK_OFFSET_R0, STK_OFFSET_USPRG0 + 4 .set STK_OFFSET_R2R31, STK_OFFSET_R0 + 4 .set STK_CTX_SIZE, STK_OFFSET_R2R31 + ( ( 31 - 2 ) + 1 ) * 4/*********************************************************************************************************** OS_CPU_ISR_CRITICAL** Description: This macro is placed at offset 0x0100 in the interrupt-handler table, so it is executed* whenever critical interrupts are enabled and the external critical interrupt signal is * asserted. The macro's code saves the current task's context before calling * BSP_CriticalIntHandler(), which provides further, application-specific processing of the * interrupt. ** Critical interrupts are disabled while this routine executes. However, critical interupts* are not disabled when non-critical interrupts occur. Therefore, this routine checks the * return address saved in SSR2 to determine if one of the non-critical ISRs residing in the* interrupt-handler table was interrupted. If the return address indeed corresponds to one* of these ISRs, OSIntNesting is not manipulated and the scheduler is not invoked. These* precautions are necessary when a non-critical ISR is interrupted because the interrupt* may have occurred before that ISR incremented OSIntNesting, which could result in the * ensuing critical ISR prematurely invoking the scheduler. Whether or not a non-critical * ISR was interrupted, though, context is saved and the interrupt is serviced by * BSP_CriticalIntHandler(). * * 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 0* + 0x24 GPR0* + 0x28 GPR2* + 0x2C GPR3* + 0x30 GPR4* |* |* \ /* V* + 0x9C GPR31 (HIGH MEMORY)***********************************************************************************************************/ MACRO0(OS_CPU_ISR_CRITICAL) /* ******* 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 */ mfsrr3 0 stw 0, STK_OFFSET_MSR(1) /* Save the Machine-State Register */ mfsrr2 0 stw 0, STK_OFFSET_PC(1) /* Save the return address */ /* See if a non-critical ISR was interrupted */ mfevpr 4 subf 5, 4, 0 /* Subtract the EVPR from the return address */ cmpli 1, 0, 5, DEBUG_ISR@l /* Compare the result to the last offset */ lis 0, BSP_CriticalIntHandler@h /* Load the address of BSP_CriticalIntHandler */ ori 0, 0, BSP_CriticalIntHandler@l mtlr 0 bc 0x05, 0x04, CRITICAL_CHECK_NESTING /* Branch if the return address is not in... */ /* ...the interrupt-handler table */ blrl b CRITICAL_RESTORE_CTX CRITICAL_CHECK_NESTING: lis 4, OSIntNesting@h /* See if OSIntNesting == 0 */ ori 4, 4, OSIntNesting@l lwz 5, 0(4) addic. 5, 5, 0 bc 0x04, 0x02, CRITICAL_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)CRITICAL_INC_NESTING: addi 5, 5, 1 /* Increment OSIntNesting */ stb 5, 0(4) blrl /* Call the interrupt controller's handler */ lis 0, OSIntExit@h /* Call OSIntExit() */ ori 0, 0, OSIntExit@l mtlr 0 blrl /* *** RESTORE INTERRUPTED TASK'S CONTEXT **** */CRITICAL_RESTORE_CTX: lwz 0, STK_OFFSET_MSR(1) /* Restore the Machine-State Register to SRR3 */ mtsrr3 0 lwz 0, STK_OFFSET_PC(1) /* Restore the Machine-State Register to SRR2 */ mtsrr2 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 */ rfci /* Return to the interrupted task */ .endm/*********************************************************************************************************** OS_CPU_ISR_NON_CRITICAL** Description: This macro is placed at offset 0x0500 in the interrupt-handler table, so it is executed* whenever the external non-critical interrupt signal is asserted. This code saves the * current task's context before calling BSP_NonCriticalIntHandler(), which provides further, * application-specific processing of the interrupt.* * 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 0* + 0x24 GPR0* + 0x28 GPR2* + 0x2C GPR3* + 0x30 GPR4* |* |* \ /* V* + 0x9C GPR31 (HIGH MEMORY)***********************************************************************************************************/ MACRO0(OS_CPU_ISR_NON_CRITICAL) /* ******* 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 lwz 5, 0(4) addic. 5, 5, 0 bc 0x04, 0x02, NON_CRITICAL_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)NON_CRITICAL_INC_NESTING: addi 5, 5, 1 /* Increment OSIntNesting */ stb 5, 0(4) lis 0, BSP_NonCriticalIntHandler@h /* Call the interrupt controller's handler */ ori 0, 0, BSP_NonCriticalIntHandler@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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -