📄 os_cpu_a.s
字号:
OS_NULL_NON_CRITICAL .org _vectorbase + 0x0100 /* Offset 0x0100 -> Critical Input Exception */CRITICAL_INPUT_ISR: OS_CPU_ISR_CRITICAL .org _vectorbase + 0x0200 /* Offset 0x0200 -> Machine Check Exception */MACHINE_CHECK_ISR: OS_NULL_CRITICAL .org _vectorbase + 0x0300 /* Offset 0x0300 -> Data Storage Exception */DATA_STORAGE_ISR: OS_NULL_NON_CRITICAL .org _vectorbase + 0x0400 /* Offset 0x0400 -> Instruction Storage Exception */INSTRUCTION_STORAGE_ISR: OS_NULL_NON_CRITICAL .org _vectorbase + 0x0500 /* Offset 0x0500 -> External Input Exception */EXTERNAL_ISR: OS_CPU_ISR_NON_CRITICAL .org _vectorbase + 0x0600 /* Offset 0x0600 -> Alignment Exception */ALIGNMENT_ISR: OS_NULL_NON_CRITICAL .org _vectorbase + 0x0700 /* Offset 0x0700 -> Program Exception */PROGRAM_ISR: OS_NULL_NON_CRITICAL .org _vectorbase + 0x0800 /* Offset 0x0800 -> FPU Unavailable Exception */FPU_UNAVAILABLE_ISR: OS_NULL_NON_CRITICAL .org _vectorbase + 0x0C00 /* Offset 0x0C00 -> System Call Exception */SYSTEM_CALL_ISR: OSCtxSw .org _vectorbase + 0x0F20 /* Offset 0x0F20 -> APU Unavailable Exception */APU_UNAVAILABLE_ISR: OS_NULL_NON_CRITICAL .org _vectorbase + 0x1000 /* Offset 0x1000 -> Programmable-Interval Timer Exception */PROGRAMMABLE_INTERVAL_TIMER_ISR: b OS_PIT_ISR .org _vectorbase + 0x1010 /* Offset 0x1010 -> Fixed-Interval Timer Exception */FIXED_INTERVAL_TIMER_ISR: OS_NULL_NON_CRITICAL .org _vectorbase + 0x1020 /* Offset 0x1020 -> Watchdog Timer Exception */WATCHDOG_TIMER_ISR: OS_NULL_CRITICAL .org _vectorbase + 0x1100 /* Offset 0x1100 -> Data TLB Miss Exception */DATA_TLB_MISS_ISR: OS_NULL_NON_CRITICAL .org _vectorbase + 0x1200 /* Offset 0x1200 -> Instruction TLB Miss Exception */INSTRUCTION_TLB_MISS_ISR: OS_NULL_NON_CRITICAL .org _vectorbase + 0x1300 /* Offset 0x1300 -> Excess code from other entries */OS_PIT_ISR: OSTickISR .org _vectorbase + 0x2000 /* Offset 0x2000 -> Debug Exceptions */DEBUG_ISR: OS_NULL_CRITICAL .section ".text"/*********************************************************************************************************** OSIntCtxSw()** Description: Performs the Context Switch from an ISR. ** OSIntCtxSw() implements the following pseudo-code:** OSTaskSwHook();* OSPrioCur = OSPrioHighRdy;* OSTCBCur = OSTCBHighRdy;* SP = OSTCBHighRdy->OSTCBStkPtr;* if (Context saved by Critical ISR) {* Restore MSR and PC to SRR3 and SRR2, respectively;* Restore all other registers;* Execute the return-from-critical-interrupt instruction;* } else {* Restore MSR and PC to SRR1 and SRR0, respectively;* Restore all other registers;* Execute the return-from-interrupt instruction;* }** Upon entry, the registers of the task being suspended have already been saved onto that * task's stack and the SP for the task has been saved in its OS_TCB by the ISR.** The stack frame of the task to resume is assumed to look 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 Interrupt type * + 0x24 GPR0* + 0x28 GPR2* + 0x2C GPR3* + 0x30 GPR4* |* |* \ /* V* + 0x9C GPR31 (HIGH MEMORY)** Note(s) : 1) If the task frame was saved by a critical ISR, the stack entry at offset 0x20 will be * set to 1.* If the task frame was saved by a non-critical ISR, the stack entry at offset 0x20 will * be set to 0.**********************************************************************************************************/OSIntCtxSw: 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 *//*********************************************************************************************************** OSStartHighRdy()** Description: Starts the highest priority task that is available to run. OSStartHighRdy() MUST:** a) Call OSTaskSwHook()* b) Set OSRunning to TRUE* c) Switch to the highest priority task.** The stack frame of the task to resume is assumed to look 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 Interrupt type (initialized to 0x00000000)* + 0x24 GPR0* + 0x28 GPR2* + 0x2C GPR3* + 0x30 GPR4* |* |* \ /* V * + 0x9C GPR31 (HIGH MEMORY)** Note(s) : 1) The MSR entry in the stack is initialized so that interrupts will be enabled when the* task begins to run. In order to allow the interrupts to be properly serviced, * OSStartHighRdy() initializes the Exception-Vector Prefix Register (EVPR) so that it * contains the address of the interrupt-handler table defined above. **********************************************************************************************************/OSStartHighRdy: lis 0, OSTaskSwHook@h /* Call OSTaskSwHook() */ ori 0, 0, OSTaskSwHook@l mtlr 0 blrl li 0, 1 /* Indicate that the OS is running */ lis 4, OSRunning@h ori 4, 4, OSRunning@l stb 0, 0(4) lis 4, OSTCBHighRdy@h /* Load the first task's stack pointer */ ori 4, 4, OSTCBHighRdy@l lwz 5, 0(4) lwz 1, 0(5) lis 0, _vectorbase@h /* Initialize the EVPR */ mtevpr 0 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 /* Start the task *//*********************************************************************************************************** DISABLE INTERRUPTS* OS_CPU_SR OS_CPU_SR_Save(void);** Description : Sets the MSR, disabling interrupts, and returns the previous MSR contents. This allows * the machine state to be restored at a subsequent time.** Arguments : None** Returns : Current MSR contents in GPR3** Note(s) : 1) The variable in the calling routine that will hold the return value MUST be declared * volatile for proper operation. There is no guarantee that the proper register will * be scheduled for the subsequent 'OS_CPU_SR_Save()' function call if the variable is * not declared volatile.**********************************************************************************************************/OS_CPU_SR_Save: addis 4, 0, 0xFFFD ori 4, 4, 0x7FFF mfmsr 3 and 4, 4, 3 /* Clear bits 14 and 16, corresponding to... */ mtmsr 4 /* ...critical and non-critical interrupts */ blr/*********************************************************************************************************** ENABLE INTERRUPTS* void OS_CPU_SR_Restore(OS_CPU_SR sr);** Description : Sets the MSR, possibly enabling interrupts, using the value passed in GPR3. ** Arguments : Saved MSR contents in GPR3** Returns : None** Note(s) : 1) The argument from the calling routine MUST be declared volatile for proper operation. * There is no guarantee that the proper register will be scheduled for the call to * OS_CPU_SR_Restore() if the variable is not declared 'volatile'.**********************************************************************************************************/OS_CPU_SR_Restore: mtmsr 3 /* Restore the saved MSR */ blr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -