Ensure that the configMAX_SYSCALL_INTERRUPT_PRIORITY setting works with all possible values.

pull/4/head
Richard Barry 14 years ago
parent 9133ceb44d
commit 8fc0c27ea5

@ -204,7 +204,13 @@ 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 ) ) ); /* This clears the IPL bits, then sets them to
configMAX_SYSCALL_INTERRUPT_PRIORITY. This function should not be called
from an interrupt that has a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY so, when used correctly, the action
can only result in the IPL being unchanged or raised, and therefore never
lowered. */
_CP0_SET_STATUS( ( ( uxSavedStatusRegister & ( ~portALL_IPL_BITS ) ) ) | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) );
return uxSavedStatusRegister; return uxSavedStatusRegister;
} }

@ -195,11 +195,14 @@ vPortYieldISR:
lw s7, (s7) lw s7, (s7)
sw s5, (s7) sw s5, (s7)
/* Set the interrupt mask to the max priority that can use the API. */ /* Set the interrupt mask to the max priority that can use the API. The
yield handler will only be called at configKERNEL_INTERRUPT_PRIORITY which
is below configMAX_SYSCALL_INTERRUPT_PRIORITY - so this can only ever
raise the IPL value and never lower it. */
di di
mfc0 s7, _CP0_STATUS mfc0 s7, _CP0_STATUS
ori s7, s7, 1 ins s7, $0, 10, 6
ori s6, s7, configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 ori s6, s7, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 ) | 1
/* This mtc0 re-enables interrupts, but only above /* This mtc0 re-enables interrupts, but only above
configMAX_SYSCALL_INTERRUPT_PRIORITY. */ configMAX_SYSCALL_INTERRUPT_PRIORITY. */

@ -84,7 +84,7 @@ extern "C" {
typedef unsigned portSHORT portTickType; typedef unsigned portSHORT portTickType;
#define portMAX_DELAY ( portTickType ) 0xffff #define portMAX_DELAY ( portTickType ) 0xffff
#else #else
typedef unsigned portLONG portTickType; typedef unsigned long portTickType;
#define portMAX_DELAY ( portTickType ) 0xffffffff #define portMAX_DELAY ( portTickType ) 0xffffffff
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -96,28 +96,34 @@ extern "C" {
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */
#define portIPL_SHIFT ( 10 ) #define portIPL_SHIFT ( 10UL )
#define portALL_IPL_BITS ( 0x3f << portIPL_SHIFT ) #define portALL_IPL_BITS ( 0x3fUL << portIPL_SHIFT )
#define portSW0_BIT ( 0x01 << 8 ) #define portSW0_BIT ( 0x01 << 8 )
#define portDISABLE_INTERRUPTS() \ /* This clears the IPL bits, then sets them to
{ \ configMAX_SYSCALL_INTERRUPT_PRIORITY. This function should not be called
unsigned portLONG ulStatus; \ from an interrupt, so therefore will not be called with an IPL setting
\ above configMAX_SYSCALL_INTERRUPT_PRIORITY. Therefore, when used correctly, the
/* Mask interrupts at and below the kernel interrupt priority. */ \ instructions in this macro can only result in the IPL being raised, and
ulStatus = _CP0_GET_STATUS(); \ therefore never lowered. */
ulStatus |= ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ); \ #define portDISABLE_INTERRUPTS() \
_CP0_SET_STATUS( ulStatus ); \ { \
unsigned long ulStatus; \
\
/* Mask interrupts at and below the kernel interrupt priority. */ \
ulStatus = _CP0_GET_STATUS(); \
ulStatus &= ~portALL_IPL_BITS; \
_CP0_SET_STATUS( ( ulStatus | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) ); \
} }
#define portENABLE_INTERRUPTS() \ #define portENABLE_INTERRUPTS() \
{ \ { \
unsigned portLONG ulStatus; \ unsigned long ulStatus; \
\ \
/* Unmask all interrupts. */ \ /* Unmask all interrupts. */ \
ulStatus = _CP0_GET_STATUS(); \ ulStatus = _CP0_GET_STATUS(); \
ulStatus &= ~portALL_IPL_BITS; \ ulStatus &= ~portALL_IPL_BITS; \
_CP0_SET_STATUS( ulStatus ); \ _CP0_SET_STATUS( ulStatus ); \
} }
@ -138,7 +144,7 @@ extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE );
#define portYIELD() \ #define portYIELD() \
{ \ { \
unsigned portLONG ulStatus; \ unsigned long ulStatus; \
\ \
/* Trigger software interrupt. */ \ /* Trigger software interrupt. */ \
ulStatus = _CP0_GET_CAUSE(); \ ulStatus = _CP0_GET_CAUSE(); \

Loading…
Cancel
Save