\r
#define portINITIAL_SYSCON ( (unsigned portBASE_TYPE) 0x00000000 ) /* MPU Disable. */\r
\r
+/* This macro should be used when the MPU is being used. */\r
#define portSELECT_PROGRAM_STATUS_WORD( xRunPrivileged ) ( ( xRunPrivileged ) ? portINITIAL_PRIVILEGED_PROGRAM_STATUS_WORD : portINITIAL_UNPRIVILEGED_PROGRAM_STATUS_WORD )\r
\r
/* CSA manipulation macros. */\r
\r
/* Upper Context. */\r
pxUpperCSA[ 2 ] = (unsigned portBASE_TYPE)pxTopOfStack; /* A10; Stack Return aka Stack Pointer */\r
- pxUpperCSA[ 1 ] = portSELECT_PROGRAM_STATUS_WORD( pdTRUE ); /* PSW */\r
+ pxUpperCSA[ 1 ] = portSYSTEM_PROGRAM_STATUS_WORD; /* PSW */\r
\r
/* Clear the CSA. */\r
memset( pxLowerCSA, 0, 16 * sizeof( unsigned portBASE_TYPE ) );\r
void vPortReclaimCSA( unsigned portBASE_TYPE *pxTCB )\r
{\r
unsigned portBASE_TYPE pxHeadCSA, pxTailCSA, pxFreeCSA;\r
+unsigned portBASE_TYPE *pulNextCSA;\r
\r
- /* The first element in a TCB is the Last Used CSA.\r
- * These simply need to be free'd to add them back to\r
- * the global pool of CSAs.\r
- */\r
-\r
- /* Lookup the first element from the TCB. */\r
+ /* A pointer to the first CSA in the list of CSAs consumed by the task is\r
+ stored in the first element of the tasks TCB structure (where the stack\r
+ pointer would be on a traditional stack based architecture). */\r
pxHeadCSA = ( *pxTCB ) & portCSA_FCX_MASK;\r
\r
- /* If there is something to reclaim. */\r
- if ( 0UL != ( pxHeadCSA & portCSA_FCX_MASK ) )\r
+ /* Mask off everything in the CSA link field other than the address. If\r
+ the address is NULL, then the CSA is not linking anywhere and there is\r
+ nothing to do. */\r
+ pxTailCSA = pxHeadCSA;\r
+\r
+ /* Convert the link value to contain just a raw address and store this\r
+ in a local variable. */\r
+ pulNextCSA = portCSA_TO_ADDRESS( pxTailCSA );\r
+\r
+ /* Iterate over the CSAs that were consumed as part of the task. The\r
+ first field in the CSA is the pointer to then next CSA. Mask off\r
+ everything in the pointer to the next CSA, other than the link address.\r
+ If this is NULL, then the CSA currently being pointed to is the last in\r
+ the chain. */\r
+ while( 0UL != ( pulNextCSA[ 0 ] & portCSA_FCX_MASK ) )\r
{\r
- /* Iterate over the CSAs that were consumed as part of the task. */\r
- pxTailCSA = pxHeadCSA;\r
- while ( 0UL != ( portCSA_TO_ADDRESS( pxTailCSA )[ 0 ] & portCSA_FCX_MASK ) )\r
- {\r
- /* Clear any extra bits from the link words. */\r
- portCSA_TO_ADDRESS( pxTailCSA )[ 0 ] = pxTailCSA & portCSA_FCX_MASK;\r
+ /* Clear all bits of the pointer to the next in the chain, other\r
+ than the address bits themselves. */\r
+ pulNextCSA[ 0 ] = pulNextCSA[ 0 ] & portCSA_FCX_MASK;\r
\r
- /* Iterate to the next CSA. */\r
- pxTailCSA = portCSA_TO_ADDRESS( pxTailCSA )[ 0 ];\r
- }\r
+ /* Move the pointer to point to the next CSA in the list. */\r
+ pxTailCSA = pulNextCSA[ 0 ];\r
\r
- /* pxHeadCSA points to the first in the chain\r
- * pxNextCSA points to the Head or the last in the chain.\r
- */\r
+ /* Update the local pointer to the CSA. */\r
+ pulNextCSA = portCSA_TO_ADDRESS( pxTailCSA );\r
+ }\r
\r
- portENTER_CRITICAL();\r
- {\r
- /* Look up the current free CSA. */\r
- _dsync();\r
- pxFreeCSA = _mfcr( $FCX );\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* Look up the current free CSA head. */\r
+ _dsync();\r
+ pxFreeCSA = _mfcr( $FCX );\r
\r
- /* Join the current Free onto the Tail of what is being reclaimed. */\r
- portCSA_TO_ADDRESS( pxTailCSA )[ 0 ] = pxFreeCSA;\r
+ /* Join the current Free onto the Tail of what is being reclaimed. */\r
+ portCSA_TO_ADDRESS( pxTailCSA )[ 0 ] = pxFreeCSA;\r
\r
- /* Move the head of the reclaimed into the Free. */\r
- _dsync();\r
- _mtcr( $FCX, pxHeadCSA );\r
- /* ISync to commit the change to the FCX. */\r
- _isync();\r
- }\r
- portEXIT_CRITICAL();\r
+ /* Move the head of the reclaimed into the Free. */\r
+ _dsync();\r
+ _mtcr( $FCX, pxHeadCSA );\r
+\r
+ /* ISync to commit the change to the FCX. */\r
+ _isync();\r
}\r
+ taskEXIT_CRITICAL();\r
}\r
/*-----------------------------------------------------------*/\r
\r