📄 os_cpu_a.s
字号:
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
*
* (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
* All Rights Reserved
*
* File : OS_CPU_A.S
* By : Jean J. Labrosse
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MIPS Port
*
* Target : MIPS (Includes 4Kc)
* Ported by : Michael Anburaj
* URL : http://geocities.com/michaelanburaj/ Email : michaelanburaj@hotmail.com
*
*********************************************************************************************************
*/
#include "sysdefs.h"
#include "mips.h"
#include "frmwrk.h" /* for _EXC_STKSIZE */
/* ********************************************************************* */
/* Global definitions */
/* ********************************************************************* */
/* File local definitions */
.set noat
.set noreorder
// pop task's at, v0-v1,a0-a3,t0-t9,s0-s7,fp,ra, & pc
#define RESTORE_REG_RET() \
lw ra,0(sp); \
lw fp,4(sp); \
lw t9,8(sp); \
lw t8,12(sp); \
lw s7,16(sp); \
lw s6,20(sp); \
lw s5,24(sp); \
lw s4,28(sp); \
lw s3,32(sp); \
lw s2,36(sp); \
lw s1,40(sp); \
lw s0,44(sp); \
lw t7,48(sp); \
lw t6,52(sp); \
lw t5,56(sp); \
lw t4,60(sp); \
lw t3,64(sp); \
lw t2,68(sp); \
lw t1,72(sp); \
lw t0,76(sp); \
lw a3,80(sp); \
lw a2,84(sp); \
lw a1,88(sp); \
lw a0,92(sp); \
lw v1,96(sp); \
lw v0,100(sp); \
lw AT,104(sp); \
lw k0,108(sp); \
MTC0(k0,C0_STATUS); \
lw k0,112(sp); \
addu sp,116; \
jr k0; \
nop
// pop task's at, v0-v1,a0-a3,t0-t9,s0-s7,fp,ra, & pc
#define RESTORE_REG_ERET() \
lw ra,0(sp); \
lw fp,4(sp); \
lw t9,8(sp); \
lw t8,12(sp); \
lw s7,16(sp); \
lw s6,20(sp); \
lw s5,24(sp); \
lw s4,28(sp); \
lw s3,32(sp); \
lw s2,36(sp); \
lw s1,40(sp); \
lw s0,44(sp); \
lw t7,48(sp); \
lw t6,52(sp); \
lw t5,56(sp); \
lw t4,60(sp); \
lw t3,64(sp); \
lw t2,68(sp); \
lw t1,72(sp); \
lw t0,76(sp); \
lw a3,80(sp); \
lw a2,84(sp); \
lw a1,88(sp); \
lw a0,92(sp); \
lw v1,96(sp); \
lw v0,100(sp); \
lw AT,104(sp); \
lw k0,108(sp); \
MTC0(k0,C0_STATUS); \
lw k0,112(sp); \
MTC0(k0,C0_EPC); \
addu sp,116; \
eret; \
nop
// push task's at, v0-v1,a0-a3,t0-t9,s0-s7,fp,ra, & pc
#define STORE_REG_RET(Retaddr) \
subu sp,116; \
sw ra,0(sp); \
sw fp,4(sp); \
sw t9,8(sp); \
sw t8,12(sp); \
sw s7,16(sp); \
sw s6,20(sp); \
sw s5,24(sp); \
sw s4,28(sp); \
sw s3,32(sp); \
sw s2,36(sp); \
sw s1,40(sp); \
sw s0,44(sp); \
sw t7,48(sp); \
sw t6,52(sp); \
sw t5,56(sp); \
sw t4,60(sp); \
sw t3,64(sp); \
sw t2,68(sp); \
sw t1,72(sp); \
sw t0,76(sp); \
sw a3,80(sp); \
sw a2,84(sp); \
sw a1,88(sp); \
sw a0,92(sp); \
sw v1,96(sp); \
sw v0,100(sp); \
sw AT,104(sp); \
MFC0(t0,C0_STATUS); \
sw t0,108(sp); \
sw Retaddr,112(sp)
/* ********************************************************************* */
/* Local functions */
/* ********************************************************************* */
/* Global functions */
/*
**********************************************************************************************************
* START MULTITASKING
* void OSStartHighRdy(void)
*
* Note : OSStartHighRdy() MUST:
* a) Call OSTaskSwHook() then,
* b) Set OSRunning to TRUE,
* c) Switch to the highest priority task.
**********************************************************************************************************
*/
LEAF(OSStartHighRdy)
jal OSTaskSwHook /* Call user defined task switch hook */
nop
la t0,OSRunning /* Indicate that multitasking has started */
li t1,1
sb t1,0(t0) /* OSRunning is a boolean */
la t0,OSTCBHighRdy /* Get highest priority task TCB address */
lw t0,0(t0) /* get stack pointer */
lw sp,0(t0) /* switch to the new stack */
RESTORE_REG_RET() /* pop new task's at, v0-v1,a0-a3,t0-t9,s0-s7,fp,ra, & pc */
END(OSStartHighRdy)
/*
**********************************************************************************************************
* PERFORM A CONTEXT SWITCH (From task level)
* void OSCtxSw(void)
*
* Note(s): Upon entry,
* OSTCBCur points to the OS_TCB of the task to suspend
* OSTCBHighRdy points to the OS_TCB of the task to resume
*
**********************************************************************************************************
*/
LEAF(OSCtxSw)
/* Special optimised code below: */
STORE_REG_RET(ra) /* push task's at, v0-v1,a0-a3,t0-t9,s0-s7,fp,ra, & pc */
/* OSPrioCur = OSPrioHighRdy */
la s0,OSPrioCur
la s1,OSPrioHighRdy
lb s2,0(s1)
sb s2,0(s0)
/* Get current task TCB address */
la s0,OSTCBCur
lw s1,0(s0)
sw sp,0(s1) /* store sp in preempted tasks's TCB */
jal OSTaskSwHook /* call Task Switch Hook */
nop
/* Get highest priority task TCB address */
la s1,OSTCBHighRdy
lw s1,0(s1)
lw sp,0(s1) /* get new task's stack pointer */
/* OSTCBCur = OSTCBHighRdy */
sw s1,0(s0) /* set new current task TCB address */
/* TBI */RESTORE_REG_ERET() /* pop new task's at, v0-v1,a0-a3,t0-t9,s0-s7,fp,ra, & pc */
END(OSCtxSw)
/*
**********************************************************************************************************
* PERFORM A CONTEXT SWITCH (From an ISR)
* void OSIntCtxSw(void)
*
* Note(s): This function only flags a context switch to the ISR Handler
*
**********************************************************************************************************
*/
LEAF(OSIntCtxSw)
/* OSIntCtxSwFlag = True */
la t0,OSIntCtxSwFlag
li t1,1
sw t1,0(t0)
jr ra
nop
END(OSIntCtxSw)
/*
**********************************************************************************************************
* UCOS_INTHandler
*
* This handles all the INTs
*
**********************************************************************************************************
*/
BSS
/* 32 bit align */
ALIGN(2)
exc_stack_low:
.space _EXC_STKSIZE
exc_stack_hi:
ALIGN(4) /* 16 bytes align */
exc_context:
.space 8
LEAF(UCOS_INTHandler)
MFC0(k0,C0_EPC)
STORE_REG_RET(k0)
la k1, exc_context
MFC0(t0, C0_STATUS)
sw t0,0(k1)
MFC0(t0, C0_CAUSE)
sw t0,4(k1)
move k0,sp
/* call low level exception handler */
/* Set up sp and gp to YAMON value */
la gp, _gp
la sp,exc_stack_hi
jal OSIntEnter /* It is imperative that k1 survives */
nop
jal C_INTHandler
move a0,k1
jal OSIntExit
nop
la t0,OSIntCtxSwFlag
lw t1,0(t0)
beq t1,1,_IntCtxSw
nop
move sp,k0
RESTORE_REG_ERET()
_IntCtxSw:
/* beq zero,zero,_IntCtxSw
nop*/
sw zero,0(t0)
/* OSPrioCur = OSPrioHighRdy */
la t0,OSPrioCur
la t1,OSPrioHighRdy
lb t1,0(t1)
sb t1,0(t0)
/* Get current task TCB address */
la t0,OSTCBCur
lw t1,0(t0)
sw k0,0(t1) /* store sp in preempted tasks's TCB */
jal OSTaskSwHook /* call Task Switch Hook */
nop
/* Get highest priority task TCB address */
la t2,OSTCBHighRdy
lw t2,0(t2)
lw sp,0(t2) /* get new task's stack pointer
/* OSTCBCur = OSTCBHighRdy */
sw t2,0(t0) /* set new current task TCB address */
RESTORE_REG_ERET()
END(UCOS_INTHandler)
/*
**********************************************************************************************************
* CRITICAL SECTION METHOD 3 FUNCTIONS
*
* Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
* would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
* disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to
* disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
* into the CPU's status register.
*
* OS_CPU_SR OSCPUSaveSR()
* Arguments : none
*
* Returns : OS_CPU_SR
*
* OSCPURestoreSR(OS_CPU_SR cpu_sr)
* Arguments : OS_CPU_SR
*
* Returns : none
*
* Note(s) : These functions are used in general like this,
*
* void Task (void *data)
* {
* #if OS_CRITICAL_METHOD == 3 // Allocate storage for CPU status register
* OS_CPU_SR cpu_sr;
* #endif
* :
* :
* OS_ENTER_CRITICAL(); // cpu_sr = OSCPUSaveSR();
* :
* :
* OS_EXIT_CRITICAL(); // OSCPURestoreSR(cpu_sr);
* :
* :
* }
**********************************************************************************************************
*/
LEAF(OSCPUSaveSR)
MFC0(v0,C0_STATUS)
and v1,v0,0xfffffffe
MTC0(v1,C0_STATUS)
jr ra
nop
END(OSCPUSaveSR)
LEAF(OSCPURestoreSR)
MTC0(a0,C0_STATUS)
jr ra
nop
END(OSCPURestoreSR)
/*
*********************************************************************************************
* CP0_wGetSR
*
* Description: Reads CP0-status.
*
* Arguments : none.
*
* Return : CP0-status.
*
* Note(s) :
*********************************************************************************************
*/
LEAF(CP0_wGetSR)
MFC0(v0,C0_STATUS)
jr ra
nop
END(CP0_wGetSR)
/*
*********************************************************************************************
* CP0_vEnableIM
*
* Description: Enable specific interrupt: set IM[x] bit in CP0-status.
*
* Arguments : Interrupt number:
* C0_STATUS_IM_SW0, C0_STATUS_IM_SW1, C0_STATUS_IM_HW0 - C0_STATUS_IM_HW5
*
* Return : none.
*
* Note(s) :
*********************************************************************************************
*/
LEAF(CP0_vEnableIM)
MFC0( v0, C0_STATUS)
li t0, 1
addiu a0, C0_STATUS_IM_SHF
sllv t0, t0, a0
or v0, t0
MTC0( v0, C0_STATUS)
j ra
nop
END(CP0_vEnableIM)
/* ********************************************************************* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -