mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Update to use the kernel critical nesting.
This commit is contained in:
parent
f3eb5028a3
commit
66fc3b8092
|
@ -131,11 +131,6 @@
|
||||||
mflo s6
|
mflo s6
|
||||||
sw s6, 8(s5)
|
sw s6, 8(s5)
|
||||||
|
|
||||||
/* Each task maintains its own nesting count. */
|
|
||||||
la s6, uxCriticalNesting
|
|
||||||
lw s6, (s6)
|
|
||||||
sw s6, 4(s5)
|
|
||||||
|
|
||||||
/* Update the task stack pointer value if nesting is zero. */
|
/* Update the task stack pointer value if nesting is zero. */
|
||||||
la s6, uxInterruptNesting
|
la s6, uxInterruptNesting
|
||||||
lw s6, (s6)
|
lw s6, (s6)
|
||||||
|
@ -199,13 +194,6 @@
|
||||||
addiu k1, k1, -1
|
addiu k1, k1, -1
|
||||||
sw k1, 0(k0)
|
sw k1, 0(k0)
|
||||||
|
|
||||||
/* Restore the critical nesting count. */
|
|
||||||
la k0, uxCriticalNesting
|
|
||||||
lw k1, 4(s5)
|
|
||||||
sw k1, (k0)
|
|
||||||
|
|
||||||
/* If the critical nesting is not zero then set status as if within
|
|
||||||
a critical section. */
|
|
||||||
lw k0, portSTATUS_STACK_LOCATION(s5)
|
lw k0, portSTATUS_STACK_LOCATION(s5)
|
||||||
lw k1, portEPC_STACK_LOCATION(s5)
|
lw k1, portEPC_STACK_LOCATION(s5)
|
||||||
|
|
||||||
|
|
|
@ -62,24 +62,15 @@
|
||||||
#define portIE_BIT ( 0x00000001 )
|
#define portIE_BIT ( 0x00000001 )
|
||||||
#define portEXL_BIT ( 0x00000002 )
|
#define portEXL_BIT ( 0x00000002 )
|
||||||
#define portSW0_ENABLE ( 0x00000100 )
|
#define portSW0_ENABLE ( 0x00000100 )
|
||||||
#define portIPL_SHIFT ( 10 )
|
|
||||||
#define portALL_IPL_BITS ( 0x3f << portIPL_SHIFT )
|
|
||||||
|
|
||||||
/* The EXL bit is set to ensure interrupts do not occur while the context of
|
/* The EXL bit is set to ensure interrupts do not occur while the context of
|
||||||
the first task is being restored. */
|
the first task is being restored. */
|
||||||
#define portINITIAL_SR ( portIE_BIT | portEXL_BIT | portSW0_ENABLE )
|
#define portINITIAL_SR ( portIE_BIT | portEXL_BIT | portSW0_ENABLE )
|
||||||
|
|
||||||
/* Records the nesting depth of calls to portENTER_CRITICAL(). */
|
|
||||||
unsigned portBASE_TYPE uxCriticalNesting = 0x55555555;
|
|
||||||
|
|
||||||
/* Records the interrupt nesting depth. This starts at one as it will be
|
/* Records the interrupt nesting depth. This starts at one as it will be
|
||||||
decremented to 0 when the first task starts. */
|
decremented to 0 when the first task starts. */
|
||||||
volatile unsigned portBASE_TYPE uxInterruptNesting = 0x01;
|
volatile unsigned portBASE_TYPE uxInterruptNesting = 0x01;
|
||||||
|
|
||||||
/* Used to store the original interrupt mask when the mask level is temporarily
|
|
||||||
raised during an ISR. */
|
|
||||||
volatile unsigned portBASE_TYPE uxSavedStatusRegister = 0;
|
|
||||||
|
|
||||||
/* Stores the task stack pointer when a switch is made to use the system stack. */
|
/* Stores the task stack pointer when a switch is made to use the system stack. */
|
||||||
unsigned portBASE_TYPE uxSavedTaskStackPointer = 0;
|
unsigned portBASE_TYPE uxSavedTaskStackPointer = 0;
|
||||||
|
|
||||||
|
@ -126,7 +117,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
|
||||||
*pxTopOfStack = (portSTACK_TYPE) pvParameters; /* Parameters to pass in */
|
*pxTopOfStack = (portSTACK_TYPE) pvParameters; /* Parameters to pass in */
|
||||||
pxTopOfStack -= 14;
|
pxTopOfStack -= 14;
|
||||||
|
|
||||||
*pxTopOfStack = (portSTACK_TYPE) 0x00000000; /* critical nesting level */
|
*pxTopOfStack = (portSTACK_TYPE) 0x00000000; /* critical nesting level - no longer used. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -154,39 +145,6 @@ void vPortEndScheduler(void)
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortEnterCritical(void)
|
|
||||||
{
|
|
||||||
unsigned portLONG ulStatus;
|
|
||||||
|
|
||||||
/* Mask interrupts at and below the kernel interrupt priority. */
|
|
||||||
ulStatus = _CP0_GET_STATUS();
|
|
||||||
ulStatus |= ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT );
|
|
||||||
_CP0_SET_STATUS( ulStatus );
|
|
||||||
|
|
||||||
/* Once interrupts are disabled we can access the nesting count directly. */
|
|
||||||
uxCriticalNesting++;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortExitCritical(void)
|
|
||||||
{
|
|
||||||
unsigned portLONG ulStatus;
|
|
||||||
|
|
||||||
/* If we are in a critical section then we can access the nesting count
|
|
||||||
directly. */
|
|
||||||
uxCriticalNesting--;
|
|
||||||
|
|
||||||
/* Has the nesting unwound? */
|
|
||||||
if( uxCriticalNesting == 0 )
|
|
||||||
{
|
|
||||||
/* Unmask all interrupts. */
|
|
||||||
ulStatus = _CP0_GET_STATUS();
|
|
||||||
ulStatus &= ~portALL_IPL_BITS;
|
|
||||||
_CP0_SET_STATUS( ulStatus );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
portBASE_TYPE xPortStartScheduler( void )
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void vPortStartFirstTask( void );
|
extern void vPortStartFirstTask( void );
|
||||||
|
@ -224,9 +182,11 @@ unsigned portLONG ulStatus;
|
||||||
|
|
||||||
void vPortIncrementTick( void )
|
void vPortIncrementTick( void )
|
||||||
{
|
{
|
||||||
vPortSetInterruptMaskFromISR();
|
unsigned portBASE_TYPE uxSavedStatus;
|
||||||
|
|
||||||
|
uxSavedStatus = uxPortSetInterruptMaskFromISR();
|
||||||
vTaskIncrementTick();
|
vTaskIncrementTick();
|
||||||
vPortClearInterruptMaskFromISR();
|
vPortClearInterruptMaskFromISR( uxSavedStatus );
|
||||||
|
|
||||||
/* If we are using the preemptive scheduler then we might want to select
|
/* If we are using the preemptive scheduler then we might want to select
|
||||||
a different task to execute. */
|
a different task to execute. */
|
||||||
|
@ -239,15 +199,19 @@ void vPortIncrementTick( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortSetInterruptMaskFromISR( void )
|
unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR( void )
|
||||||
{
|
{
|
||||||
|
unsigned portBASE_TYPE uxSavedStatusRegister;
|
||||||
|
|
||||||
asm volatile ( "di" );
|
asm volatile ( "di" );
|
||||||
uxSavedStatusRegister = _CP0_GET_STATUS() | 0x01;
|
uxSavedStatusRegister = _CP0_GET_STATUS() | 0x01;
|
||||||
_CP0_SET_STATUS( ( uxSavedStatusRegister | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) );
|
_CP0_SET_STATUS( ( uxSavedStatusRegister | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) );
|
||||||
|
|
||||||
|
return uxSavedStatusRegister;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortClearInterruptMaskFromISR( void )
|
void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE uxSavedStatusRegister )
|
||||||
{
|
{
|
||||||
_CP0_SET_STATUS( uxSavedStatusRegister );
|
_CP0_SET_STATUS( uxSavedStatusRegister );
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,6 @@
|
||||||
.set noreorder
|
.set noreorder
|
||||||
|
|
||||||
.extern pxCurrentTCB
|
.extern pxCurrentTCB
|
||||||
.extern uxCriticalNesting
|
|
||||||
.extern vTaskSwitchContext
|
.extern vTaskSwitchContext
|
||||||
.extern vPortIncrementTick
|
.extern vPortIncrementTick
|
||||||
.extern xISRStackTop
|
.extern xISRStackTop
|
||||||
|
@ -189,11 +188,6 @@ vPortYieldISR:
|
||||||
mflo s7
|
mflo s7
|
||||||
sw s7, 8(s5)
|
sw s7, 8(s5)
|
||||||
|
|
||||||
/* Each task maintains its own nesting count. */
|
|
||||||
la s7, uxCriticalNesting
|
|
||||||
lw s7, (s7)
|
|
||||||
sw s7, 4(s5)
|
|
||||||
|
|
||||||
/* Save the stack pointer to the task. */
|
/* Save the stack pointer to the task. */
|
||||||
la s7, pxCurrentTCB
|
la s7, pxCurrentTCB
|
||||||
lw s7, (s7)
|
lw s7, (s7)
|
||||||
|
@ -276,33 +270,19 @@ vPortYieldISR:
|
||||||
/* Switch back to use the real stack pointer. */
|
/* Switch back to use the real stack pointer. */
|
||||||
add sp, zero, s5
|
add sp, zero, s5
|
||||||
|
|
||||||
/* Restore the critical nesting depth. */
|
/* Restore the real s5 value. */
|
||||||
la s5, uxCriticalNesting
|
lw s5, 40(sp)
|
||||||
lw k0, 4(sp)
|
|
||||||
sw k0, (s5)
|
|
||||||
|
|
||||||
/* If the critical nesting is not zero and a yield is not pended
|
/* If the critical nesting is not zero and a yield is not pended
|
||||||
then set status as if within a critical section. */
|
then set status as if within a critical section. */
|
||||||
lw s5, portSTATUS_STACK_LOCATION(sp)
|
lw k1, portSTATUS_STACK_LOCATION(sp)
|
||||||
beq k0, zero, .+28
|
|
||||||
nop
|
|
||||||
mfc0 k1, _CP0_CAUSE
|
|
||||||
andi k1, k1, 256
|
|
||||||
bne k1, zero, .+12
|
|
||||||
nop
|
|
||||||
or s5, s5, (configMAX_SYSCALL_INTERRUPT_PRIORITY<<10)
|
|
||||||
|
|
||||||
lw k0, portEPC_STACK_LOCATION(sp)
|
lw k0, portEPC_STACK_LOCATION(sp)
|
||||||
|
|
||||||
mtc0 s5, _CP0_STATUS
|
|
||||||
ehb
|
|
||||||
|
|
||||||
/* Restore the real s5 value. */
|
|
||||||
lw s5, 40(sp)
|
|
||||||
|
|
||||||
/* Remove stack frame. */
|
/* Remove stack frame. */
|
||||||
addiu sp, sp, portCONTEXT_SIZE
|
addiu sp, sp, portCONTEXT_SIZE
|
||||||
|
|
||||||
|
mtc0 k1, _CP0_STATUS
|
||||||
|
ehb
|
||||||
mtc0 k0, _CP0_EPC
|
mtc0 k0, _CP0_EPC
|
||||||
eret
|
eret
|
||||||
nop
|
nop
|
||||||
|
|
|
@ -92,18 +92,40 @@ extern "C" {
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
#define portDISABLE_INTERRUPTS() INTDisableInterrupts()
|
#define portIPL_SHIFT ( 10 )
|
||||||
#define portENABLE_INTERRUPTS() INTEnableInterrupts()
|
#define portALL_IPL_BITS ( 0x3f << portIPL_SHIFT )
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
#define portDISABLE_INTERRUPTS() \
|
||||||
extern void vPortExitCritical( void );
|
{ \
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
unsigned portLONG ulStatus; \
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
\
|
||||||
|
/* Mask interrupts at and below the kernel interrupt priority. */ \
|
||||||
|
ulStatus = _CP0_GET_STATUS(); \
|
||||||
|
ulStatus |= ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ); \
|
||||||
|
_CP0_SET_STATUS( ulStatus ); \
|
||||||
|
}
|
||||||
|
|
||||||
extern void vPortSetInterruptMaskFromISR();
|
#define portENABLE_INTERRUPTS() \
|
||||||
extern void vPortClearInterruptMaskFromISR();
|
{ \
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() vPortSetInterruptMaskFromISR()
|
unsigned portLONG ulStatus; \
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR() vPortClearInterruptMaskFromISR()
|
\
|
||||||
|
/* Unmask all interrupts. */ \
|
||||||
|
ulStatus = _CP0_GET_STATUS(); \
|
||||||
|
ulStatus &= ~portALL_IPL_BITS; \
|
||||||
|
_CP0_SET_STATUS( ulStatus ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern void vTaskEnterCritical( void );
|
||||||
|
extern void vTaskExitCritical( void );
|
||||||
|
#define portCRITICAL_NESTING_IN_TCB 1
|
||||||
|
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||||
|
|
||||||
|
extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR();
|
||||||
|
extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE );
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMaskFromISR()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) vPortClearInterruptMaskFromISR( uxSavedStatusRegister )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue