]> git.sur5r.net Git - freertos/commitdiff
Update to allow nesting.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 6 May 2008 11:51:13 +0000 (11:51 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 6 May 2008 11:51:13 +0000 (11:51 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@337 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/portable/MPLAB/PIC32MX/ISR_Support.h
Source/portable/MPLAB/PIC32MX/port.c
Source/portable/MPLAB/PIC32MX/port_asm.S
Source/portable/MPLAB/PIC32MX/portmacro.h

index 208d7b80ee7aa53bdebe5c5e87d08922db1a6570..757b1ba4ee18ffee1963bae6f5116ea8e823c994 100644 (file)
 \r
 #include "FreeRTOSConfig.h"\r
 \r
-#define portCONTEXT_SIZE 136\r
-#define portEXL_AND_IE_BITS    0x03\r
-\r
+#define portCONTEXT_SIZE 132\r
 #define portEPC_STACK_LOCATION 124\r
 #define portSTATUS_STACK_LOCATION 128\r
-#define portCAUSE_STACK_LOCATION 132\r
 \r
 /******************************************************************/   \r
 .macro portSAVE_CONTEXT\r
        original values in case of interrupt nesting. */\r
        mfc0            k0, _CP0_CAUSE\r
        addiu           sp,     sp, -portCONTEXT_SIZE\r
-       sw                      k0, portCAUSE_STACK_LOCATION(sp)\r
        mfc0            k1, _CP0_STATUS\r
 \r
        /* Also save s6 and s5 so we can use them during this interrupt.  Any\r
        nesting interrupts should maintain the values of these registers\r
-       accross the ISR. */\r
+       across the ISR. */\r
        sw                      s6, 44(sp)\r
        sw                      s5, 40(sp)\r
        sw                      k1, portSTATUS_STACK_LOCATION(sp)\r
 \r
-       /* Enable interrupts above the current priority.  SysCall interrupts\r
-       enable priorities above configKERNEL_INTERRUPT_PRIORITY, so first \r
-       check if the interrupt was a system call (32). */\r
-       add                     s6, zero, k0\r
-       and                     s6, s6, 32\r
-       beq                     s6, zero, .+20 /* Not a system call, mask up to the current interrupt priority. */\r
-       nop\r
-       addiu           k0, zero, configKERNEL_INTERRUPT_PRIORITY /* Was a system call, mask only to kernel priority. */\r
-       beq                     zero, zero, .+12\r
-       nop\r
+       /* Enable interrupts above the current priority. */\r
        srl                     k0, k0, 0xa\r
        ins             k1, k0, 10, 6\r
        ins                     k1, zero, 1, 4\r
@@ -97,7 +84,7 @@
 \r
        /* If the nesting count is 0 then swap to the the system stack, otherwise\r
        the system stack is already being used. */\r
-       bne                     s6, zero, .+16\r
+       bne                     s6, zero, .+20\r
        nop\r
 \r
        /* Swap to the system stack. */\r
        addiu           s6, s6, 1\r
        sw                      s6, 0(k0)\r
 \r
-       /* s6 holds the EPC value, we may want this during the context switch. */\r
+       /* s6 holds the EPC value, this is saved after interrupts are re-enabled. */\r
        mfc0            s6, _CP0_EPC\r
 \r
        /* Re-enable interrupts. */\r
        mtc0            k1, _CP0_STATUS\r
 \r
        /* Save the context into the space just created.  s6 is saved again\r
-       here as it now contains the EPC value. */\r
+       here as it now contains the EPC value.  No other s registers need be\r
+       saved. */\r
        sw                      ra,     120(s5)\r
        sw                      s8, 116(s5)\r
        sw                      t9, 112(s5)\r
        sw                      a0, 60(s5)\r
        sw                      v1, 56(s5)\r
        sw                      v0, 52(s5)\r
-       sw                      s7, 48(s5)\r
        sw                      s6, portEPC_STACK_LOCATION(s5)\r
-       /* s5 and s6 has already been saved. */\r
-       sw                      s4,     36(s5)\r
-       sw                      s3, 32(s5)\r
-       sw                      s2, 28(s5)\r
-       sw                      s1, 24(s5)\r
-       sw                      s0, 20(s5)\r
        sw                      $1, 16(s5)\r
 \r
-       /* s7 is used as a scratch register. */\r
-       mfhi            s7\r
-       sw                      s7, 12(s5)\r
-       mflo            s7\r
-       sw                      s7, 8(s5)\r
+       /* s6 is used as a scratch register. */\r
+       mfhi            s6\r
+       sw                      s6, 12(s5)\r
+       mflo            s6\r
+       sw                      s6, 8(s5)\r
 \r
        /* Each task maintains its own nesting count. */\r
-       la                      s7, uxCriticalNesting\r
-       lw                      s7, (s7)\r
-       sw                      s7, 4(s5)\r
-\r
-       /* Update the TCB stack pointer value if the nesting count is 1. */\r
-       la                      s7, uxInterruptNesting\r
-       lw                      s7, (s7)\r
-       addiu           s7, s7, -1\r
-       bne                     s7, zero, .+24 /* Dont save the stack pointer to the task or swap stacks. */\r
+       la                      s6, uxCriticalNesting\r
+       lw                      s6, (s6)\r
+       sw                      s6, 4(s5)\r
+\r
+       /* Update the task stack pointer value if nesting is zero. */\r
+       la                      s6, uxInterruptNesting\r
+       lw                      s6, (s6)\r
+       addiu           s6, s6, -1\r
+       bne                     s6, zero, .+20\r
        nop\r
 \r
-       /* Save the stack pointer to the task. */\r
-       la                      s7, pxCurrentTCB\r
-       lw                      s7, (s7)\r
-       sw                      s5, (s7)\r
+       /* Save the stack pointer. */\r
+       la                      s6, uxSavedTaskStackPointer\r
+       sw                      s5, (s6)\r
 \r
        .endm\r
        \r
 \r
        /* Restore the stack pointer from the TCB.  This is only done if the\r
        nesting count is 1. */\r
-       la                      s7, uxInterruptNesting\r
-       lw                      s7, (s7)\r
-       addiu           s7, s7, -1\r
-       bne                     s7, zero, .+24 /* Dont load the stack pointer. */\r
+       la                      s6, uxInterruptNesting\r
+       lw                      s6, (s6)\r
+       addiu           s6, s6, -1\r
+       bne                     s6, zero, .+20\r
        nop\r
-       la                      s0, pxCurrentTCB\r
-       lw                      s0, (s0)\r
-       lw                      s5, (s0)\r
+       la                      s6, uxSavedTaskStackPointer\r
+       lw                      s5, (s6)\r
        \r
-       /* Restore the context, the first item of which is the critical nesting\r
-       depth. */\r
-       la                      s0, uxCriticalNesting\r
-       lw                      s1, 4(s5)\r
-       sw                      s1, (s0)\r
-\r
-       /* Restore the rest of the context. */\r
-       lw                      s0, 8(s5)\r
-       mtlo            s0\r
-       lw                      s0, 12(s5)\r
-       mthi            s0\r
+       /* Restore the context. */\r
+       lw                      s6, 8(s5)\r
+       mtlo            s6\r
+       lw                      s6, 12(s5)\r
+       mthi            s6\r
        lw                      $1, 16(s5)\r
-       lw                      s0, 20(s5)\r
-       lw                      s1, 24(s5)\r
-       lw                      s2, 28(s5)\r
-       lw                      s3, 32(s5)\r
-       lw                      s4, 36(s5)\r
-       /* s5 is loaded later. */\r
+       /* s6 is loaded as it was used as a scratch register and therefore saved\r
+       as part of the interrupt context. */\r
        lw                      s6, 44(s5)\r
-       lw                      s7, 48(s5)\r
        lw                      v0, 52(s5)\r
        lw                      v1, 56(s5)\r
        lw                      a0, 60(s5)\r
        addiu           k1, k1, -1\r
        sw                      k1, 0(k0)\r
 \r
-       lw                      k1, portSTATUS_STACK_LOCATION(s5)\r
-       lw                      k0, portEPC_STACK_LOCATION(s5)\r
+       /* Restore the critical nesting count. */\r
+       la                      k0, uxCriticalNesting\r
+       lw                      k1, 4(s5)\r
+       sw                      k1, (k0)\r
+\r
+       /* If the critical nesting is not zero then set status as if within\r
+       a critical section. */\r
+       lw                      k0, portSTATUS_STACK_LOCATION(s5)\r
+       lw                      k1, portEPC_STACK_LOCATION(s5)\r
 \r
        /* Leave the stack how we found it.  First load sp from s5, then restore\r
        s5 from the stack. */\r
        lw                      s5, 40(sp)\r
        addiu           sp,     sp,     portCONTEXT_SIZE\r
 \r
-       mtc0            k1, _CP0_STATUS\r
+       mtc0            k0, _CP0_STATUS\r
        ehb\r
-       mtc0            k0, _CP0_EPC\r
+       mtc0            k1, _CP0_EPC\r
        eret \r
        nop\r
 \r
index 01bcf4a0d80eeeaebcc1c2caeaef49b990613a01..8ab29fc681e1bf27b85bc2ef592fbe39e535faa5 100644 (file)
@@ -51,9 +51,6 @@
  * Implementation of functions defined in portable.h for the PIC32MX port.\r
   *----------------------------------------------------------*/\r
 \r
-/* Library includes. */\r
-#include <string.h>\r
-\r
 /* Scheduler include files. */\r
 #include "FreeRTOS.h"\r
 #include "task.h"\r
 /* Bits within various registers. */\r
 #define portIE_BIT                                     ( 0x00000001 )\r
 #define portEXL_BIT                                    ( 0x00000002 )\r
+#define portSW0_ENABLE                         ( 0x00000100 )\r
 #define portIPL_SHIFT                          ( 10 )\r
-#define portALL_IPL_BITS                       ( 0x1f << portIPL_SHIFT )\r
+#define portALL_IPL_BITS                       ( 0x3f << portIPL_SHIFT )\r
 \r
 /* The EXL bit is set to ensure interrupts do not occur while the context of\r
 the first task is being restored. */\r
-#define portINITIAL_SR                         ( portIE_BIT | portEXL_BIT )\r
+#define portINITIAL_SR                         ( portIE_BIT | portEXL_BIT | portSW0_ENABLE )\r
 \r
 /* Records the nesting depth of calls to portENTER_CRITICAL(). */\r
 unsigned portBASE_TYPE uxCriticalNesting = 0x55555555;\r
@@ -78,6 +76,13 @@ unsigned portBASE_TYPE uxCriticalNesting = 0x55555555;
 decremented to 0 when the first task starts. */\r
 volatile unsigned portBASE_TYPE uxInterruptNesting = 0x01;\r
 \r
+/* Used to store the original interrupt mask when the mask level is temporarily\r
+raised during an ISR. */\r
+volatile unsigned portBASE_TYPE uxSavedStatusRegister = 0;\r
+\r
+/* Stores the task stack pointer when a switch is made to use the system stack. */\r
+unsigned portBASE_TYPE uxSavedTaskStackPointer = 0;\r
+\r
 /* The stack used by interrupt service routines that cause a context switch. */\r
 portSTACK_TYPE xISRStack[ configISR_STACK_SIZE ] = { 0 };\r
 \r
@@ -88,11 +93,10 @@ const portBASE_TYPE * const xISRStackTop = &( xISRStack[ configISR_STACK_SIZE -
 /* Place the prototype here to ensure the interrupt vector is correctly installed. */\r
 extern void __attribute__( (interrupt(ipl1), vector(_TIMER_1_VECTOR))) vT1InterruptHandler( void );\r
 \r
-/* \r
- * General exception handler that will be called for all general exceptions\r
- * other than SYS.  This should be overridden by a user provided handler.\r
+/*\r
+ * The software interrupt handler that performs the yield.\r
  */\r
-void vApplicationGeneralExceptionHandler( unsigned portLONG ulCause, unsigned portLONG ulStatus ) __attribute__((weak));\r
+void __attribute__( (interrupt(ipl1), vector(_CORE_SOFTWARE_0_VECTOR))) vPortYieldISR( void );\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
@@ -156,7 +160,7 @@ unsigned portLONG ulStatus;
 \r
        /* Mask interrupts at and below the kernel interrupt priority. */\r
        ulStatus = _CP0_GET_STATUS();\r
-       ulStatus |= ( configKERNEL_INTERRUPT_PRIORITY << portIPL_SHIFT );\r
+       ulStatus |= ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT );\r
        _CP0_SET_STATUS( ulStatus );\r
 \r
        /* Once interrupts are disabled we can access the nesting count directly. */\r
@@ -186,14 +190,18 @@ unsigned portLONG ulStatus;
 portBASE_TYPE xPortStartScheduler( void )\r
 {\r
 extern void vPortStartFirstTask( void );\r
+extern void *pxCurrentTCB;\r
 \r
-       memset( xISRStack, 0x5a, configISR_STACK_SIZE * sizeof( portSTACK_TYPE ) );\r
+       /* Setup the software interrupt. */\r
+       mConfigIntCoreSW0( CSW_INT_ON | CSW_INT_PRIOR_1 | CSW_INT_SUB_PRIOR_0 );\r
 \r
        /* Setup the timer to generate the tick.  Interrupts will have been \r
        disabled by the time we get here. */\r
        prvSetupTimerInterrupt();\r
 \r
-       /* Kick off the highest priority task that has been created so far. */\r
+       /* Kick off the highest priority task that has been created so far. \r
+       Its stack location is loaded into uxSavedTaskStackPointer. */\r
+       uxSavedTaskStackPointer = *( unsigned portBASE_TYPE * ) pxCurrentTCB;\r
        vPortStartFirstTask();\r
 \r
        /* Should never get here as the tasks will now be executing. */\r
@@ -201,12 +209,49 @@ extern void vPortStartFirstTask( void );
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vApplicationGeneralExceptionHandler( unsigned portLONG ulCause, unsigned portLONG ulStatus )\r
+void vPortYield( void )\r
+{\r
+unsigned portLONG ulStatus;\r
+\r
+       SetCoreSW0();\r
+\r
+       /* Unmask all interrupts. */\r
+       ulStatus = _CP0_GET_STATUS();\r
+       ulStatus &= ~portALL_IPL_BITS;\r
+       _CP0_SET_STATUS( ulStatus );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortIncrementTick( void )\r
+{\r
+       vPortSetInterruptMaskFromISR();\r
+               vTaskIncrementTick();\r
+       vPortClearInterruptMaskFromISR();\r
+       \r
+       /* If we are using the preemptive scheduler then we might want to select\r
+       a different task to execute. */\r
+       #if configUSE_PREEMPTION == 1\r
+               SetCoreSW0();\r
+       #endif /* configUSE_PREEMPTION */\r
+\r
+       /* Clear timer 0 interrupt. */\r
+       mT1ClearIntFlag();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortSetInterruptMaskFromISR( void )\r
+{\r
+       asm volatile ( "di" );\r
+       uxSavedStatusRegister = _CP0_GET_STATUS() | 0x01;\r
+       _CP0_SET_STATUS( ( uxSavedStatusRegister | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortClearInterruptMaskFromISR( void )\r
 {\r
-       /* This function is declared weak and should be overridden by the users\r
-       application. */\r
-       while( 1 );\r
+       _CP0_SET_STATUS( uxSavedStatusRegister );\r
 }\r
+/*-----------------------------------------------------------*/\r
 \r
 \r
 \r
index 8aed3ac91e1d07b60d5ef9af3cd3035bdb00dfff..a1b26f8f87a3c8fdc69d711566a8e51b4c96b3a1 100644 (file)
        .extern pxCurrentTCB\r
        .extern uxCriticalNesting\r
        .extern vTaskSwitchContext\r
-       .extern vTaskIncrementTick\r
-       .extern vApplicationGeneralExceptionHandler\r
+       .extern vPortIncrementTick\r
        .extern xISRStackTop\r
        \r
        .global vPortStartFirstTask\r
-       .global _general_exception_context\r
+       .global vPortYieldISR\r
        .global vT1InterruptHandler\r
 \r
 \r
@@ -79,21 +78,9 @@ vT1InterruptHandler:
 \r
        portSAVE_CONTEXT\r
 \r
-       jal             vTaskIncrementTick\r
+       jal             vPortIncrementTick\r
        nop\r
 \r
-       /* If we are using the preemptive scheduler then we might want to select\r
-       a different task to execute. */\r
-       #if configUSE_PREEMPTION == 1\r
-               jal             vTaskSwitchContext\r
-               nop\r
-       #endif /* configUSE_PREEMPTION */\r
-\r
-       /* Clear timer 0 interrupt. */\r
-       la                      s1, IFS0CLR\r
-       addiu       s0,zero,_IFS0_T1IF_MASK\r
-       sw                      s0, 0(s1)\r
-\r
        portRESTORE_CONTEXT\r
 \r
        .end vT1InterruptHandler\r
@@ -113,58 +100,214 @@ vPortStartFirstTask:
 \r
        .end xPortStartScheduler\r
 \r
+\r
+\r
 /*******************************************************************/\r
 \r
        .section        .FreeRTOS, "ax", @progbits\r
        .set            noreorder\r
        .set            noat\r
-       .ent            _general_exception_context\r
+       .ent            vPortYieldISR\r
+\r
+vPortYieldISR:\r
+\r
+       /* Make room for the context. First save the current status so we can \r
+       manipulate it, and the cause and EPC registers so we capture their \r
+       original values in case of interrupt nesting. */\r
+       mfc0            k0, _CP0_CAUSE\r
+       addiu           sp,     sp, -portCONTEXT_SIZE\r
+       mfc0            k1, _CP0_STATUS\r
+\r
+       /* Also save s6 and s5 so we can use them during this interrupt.  Any\r
+       nesting interrupts should maintain the values of these registers\r
+       accross the ISR. */\r
+       sw                      s6, 44(sp)\r
+       sw                      s5, 40(sp)\r
+       sw                      k1, portSTATUS_STACK_LOCATION(sp)\r
+\r
+       /* Enable interrupts above the current priority. */\r
+       srl                     k0, k0, 0xa\r
+       ins             k1, k0, 10, 6\r
+       ins                     k1, zero, 1, 4\r
+\r
+       /* s5 is used as the frame pointer. */\r
+       add                     s5, zero, sp\r
+\r
+       /* Swap to the system stack.  This is not conditional on the nesting\r
+       count as this interrupt is always the lowest priority and therefore\r
+       the nesting is always 0. */\r
+       la                      sp, xISRStackTop\r
+       lw                      sp, (sp)\r
+\r
+       /* Increment and save the nesting count in case this gets preempted. */\r
+       la                      k0, uxInterruptNesting\r
+       lw                      s6, (k0)\r
+       addiu           s6, s6, 1\r
+       sw                      s6, 0(k0)\r
+\r
+       /* s6 holds the EPC value, this is saved with the rest of the context\r
+       after interrupts are enabled. */\r
+       mfc0            s6, _CP0_EPC\r
+\r
+       /* Re-enable interrupts. */\r
+       mtc0            k1, _CP0_STATUS\r
+\r
+       /* Save the context into the space just created.  s6 is saved again\r
+       here as it now contains the EPC value. */\r
+       sw                      ra,     120(s5)\r
+       sw                      s8, 116(s5)\r
+       sw                      t9, 112(s5)\r
+       sw                      t8,     108(s5)\r
+       sw                      t7,     104(s5)\r
+       sw                      t6, 100(s5)\r
+       sw                      t5, 96(s5)\r
+       sw                      t4, 92(s5)\r
+       sw                      t3, 88(s5)\r
+       sw                      t2, 84(s5)\r
+       sw                      t1, 80(s5)\r
+       sw                      t0, 76(s5)\r
+       sw                      a3, 72(s5)\r
+       sw                      a2, 68(s5)\r
+       sw                      a1, 64(s5)\r
+       sw                      a0, 60(s5)\r
+       sw                      v1, 56(s5)\r
+       sw                      v0, 52(s5)\r
+       sw                      s7, 48(s5)\r
+       sw                      s6, portEPC_STACK_LOCATION(s5)\r
+       /* s5 and s6 has already been saved. */\r
+       sw                      s4,     36(s5)\r
+       sw                      s3, 32(s5)\r
+       sw                      s2, 28(s5)\r
+       sw                      s1, 24(s5)\r
+       sw                      s0, 20(s5)\r
+       sw                      $1, 16(s5)\r
+\r
+       /* s7 is used as a scratch register as this should always be saved across\r
+       nesting interrupts. */\r
+       mfhi            s7\r
+       sw                      s7, 12(s5)\r
+       mflo            s7\r
+       sw                      s7, 8(s5)\r
+\r
+       /* Each task maintains its own nesting count. */\r
+       la                      s7, uxCriticalNesting\r
+       lw                      s7, (s7)\r
+       sw                      s7, 4(s5)\r
+\r
+       /* Save the stack pointer to the task. */\r
+       la                      s7, pxCurrentTCB\r
+       lw                      s7, (s7)\r
+       sw                      s5, (s7)\r
+\r
+       /* Set the interrupt mask to the max priority that can use the API. */\r
+       di\r
+       mfc0            s7, _CP0_STATUS\r
+       ori                     s7, s7, 1\r
+       ori                     s6, s7, configMAX_SYSCALL_INTERRUPT_PRIORITY << 10\r
 \r
-_general_exception_context:\r
+       /* This mtc0 re-enables interrupts, but only above \r
+       configMAX_SYSCALL_INTERRUPT_PRIORITY. */\r
+       mtc0            s6, _CP0_STATUS\r
 \r
-       /* Save the context of the current task. */\r
-       portSAVE_CONTEXT\r
+       /* Clear the software interrupt in the core. */\r
+       mfc0            s6, _CP0_CAUSE\r
+       addiu       s4,zero,-257\r
+       and                     s6, s6, s4\r
+       mtc0            s6, _CP0_CAUSE\r
 \r
-       /* Was this handler caused by a syscall?  The original Cause\r
-       value was saved to the stack as it could change as interrupts\r
-       nest.  Use of k registers must be protected from use by nesting\r
-       interrupts. */\r
-       lw                      s7, portCAUSE_STACK_LOCATION(s5)\r
-       andi            s7, s7, portEXC_CODE_MASK\r
-       addi            s7, s7, -( _EXCCODE_SYS << 2 )\r
+       /* Clear the interrupt in the interrupt controller. */\r
+       la                      s6, IFS0CLR\r
+       addiu           s4, zero, 2\r
+       sw                      s4, (s6)\r
 \r
-       /* Yes - call the SYSCALL handler to select a new task to execute. */\r
-       beq         s7, zero, SyscallHandler\r
+       jal                     vTaskSwitchContext\r
        nop\r
 \r
-       /* No - call the application handler to handle all other types of \r
-       exception.  Pass the status and cause to the application provided \r
-       handler.  Interrupts are disabled during the execution of the user\r
-       defined handler. */\r
+       /* Clear the interrupt mask again.  The saved status value is still in s7. */\r
+       mtc0            s7, _CP0_STATUS\r
+\r
+       /* Restore the stack pointer from the TCB. */\r
+       la                      s0, pxCurrentTCB\r
+       lw                      s0, (s0)\r
+       lw                      s5, (s0)\r
+\r
+       /* Restore the rest of the context. */\r
+       lw                      s0, 8(s5)\r
+       mtlo            s0\r
+       lw                      s0, 12(s5)\r
+       mthi            s0\r
+       lw                      $1, 16(s5)\r
+       lw                      s0, 20(s5)\r
+       lw                      s1, 24(s5)\r
+       lw                      s2, 28(s5)\r
+       lw                      s3, 32(s5)\r
+       lw                      s4, 36(s5)\r
+       /* s5 is loaded later. */\r
+       lw                      s6, 44(s5)\r
+       lw                      s7, 48(s5)\r
+       lw                      v0, 52(s5)\r
+       lw                      v1, 56(s5)\r
+       lw                      a0, 60(s5)\r
+       lw                      a1, 64(s5)\r
+       lw                      a2, 68(s5)\r
+       lw                      a3, 72(s5)\r
+       lw                      t0, 76(s5)\r
+       lw                      t1, 80(s5)\r
+       lw                      t2, 84(s5)\r
+       lw                      t3, 88(s5)\r
+       lw                      t4, 92(s5)\r
+       lw                      t5, 96(s5)\r
+       lw                      t6, 100(s5)\r
+       lw                      t7, 104(s5)\r
+       lw                      t8, 108(s5)\r
+       lw                      t9, 112(s5)\r
+       lw                      s8, 116(s5)\r
+       lw                      ra, 120(s5)\r
+\r
+       /* Protect access to the k registers, and others. */\r
        di\r
-       lw                      a1, portSTATUS_STACK_LOCATION(s5)\r
-       lw                      a0, portCAUSE_STACK_LOCATION(s5)\r
-       jal                     vApplicationGeneralExceptionHandler\r
+\r
+       /* Decrement the nesting count. */\r
+       la                      k0, uxInterruptNesting\r
+       lw                      k1, (k0)\r
+       addiu           k1, k1, -1\r
+       sw                      k1, 0(k0)\r
+\r
+       /* Switch back to use the real stack pointer. */\r
+       add                     sp, zero, s5\r
+\r
+       /* Restore the critical nesting depth. */\r
+       la                      s5, uxCriticalNesting\r
+       lw                      k0, 4(sp)\r
+       sw                      k0, (s5)\r
+\r
+       /* If the critical nesting is not zero and a yield is not pended\r
+       then set status as if within a critical section. */\r
+       lw                      s5, portSTATUS_STACK_LOCATION(sp)\r
+       beq                     k0, zero, .+28\r
        nop\r
-       ei\r
-       beq             zero, zero, FinishExceptionHandler\r
+       mfc0            k1, _CP0_CAUSE\r
+       andi            k1, k1, 256\r
+       bne                     k1, zero, .+12\r
        nop\r
+       or                      s5, s5, (configMAX_SYSCALL_INTERRUPT_PRIORITY<<10)\r
 \r
-SyscallHandler:\r
+       lw                      k0, portEPC_STACK_LOCATION(sp)\r
 \r
-       /* Adjust the return that was placed onto the stack to be the \r
-       address of the instruction following the syscall.  s6 already\r
-       contains the EPC value. */\r
-       addi            s6, 4\r
-       sw                      s6, portEPC_STACK_LOCATION(s5)\r
+       mtc0            s5, _CP0_STATUS\r
+       ehb     \r
 \r
-       jal                     vTaskSwitchContext\r
-       nop\r
+       /* Restore the real s5 value. */\r
+       lw                      s5, 40(sp)\r
 \r
-FinishExceptionHandler:\r
-       portRESTORE_CONTEXT\r
+       /* Remove stack frame. */\r
+       addiu           sp,     sp,     portCONTEXT_SIZE\r
+\r
+       mtc0            k0, _CP0_EPC\r
+       eret \r
+       nop\r
 \r
-       .end            _general_exception_context\r
+       .end            vPortYieldISR\r
 \r
 \r
 \r
index 0629d7be737662503a972954f1a88d15ea6b0c33..1c22d5104b9b468f78dd01483d653a886dd8bed9 100644 (file)
@@ -99,11 +99,17 @@ extern void vPortEnterCritical( void );
 extern void vPortExitCritical( void );\r
 #define portENTER_CRITICAL()           vPortEnterCritical()\r
 #define portEXIT_CRITICAL()                    vPortExitCritical()\r
+\r
+extern void vPortSetInterruptMaskFromISR();\r
+extern void vPortClearInterruptMaskFromISR();\r
+#define portSET_INTERRUPT_MASK_FROM_ISR() vPortSetInterruptMaskFromISR()\r
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR() vPortClearInterruptMaskFromISR()\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* Task utilities. */\r
-#define portYIELD() asm volatile (     "ehb \r\n"      \\r
-                                                                       "SYSCALL \r\n" )\r
+extern void vPortYield( void );\r
+#define portYIELD()    vPortYield()\r
 \r
 #define portNOP()                              asm volatile (  "nop" )\r
 \r
@@ -114,7 +120,7 @@ extern void vPortExitCritical( void );
 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
 /*-----------------------------------------------------------*/\r
 \r
-#define portEND_SWITCHING_ISR( vSwitchRequired ) if( vSwitchRequired ) vTaskSwitchContext()\r
+#define portEND_SWITCHING_ISR( vSwitchRequired ) if( vSwitchRequired ) SetCoreSW0()\r
 \r
 #ifdef __cplusplus\r
 }\r