]> git.sur5r.net Git - freertos/commitdiff
Comment ready for release.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 6 Mar 2008 20:55:49 +0000 (20:55 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 6 Mar 2008 20:55:49 +0000 (20:55 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@237 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/portable/GCC/PPC405_Xilinx/port.c
Source/portable/GCC/PPC405_Xilinx/portasm.s
Source/portable/GCC/PPC405_Xilinx/portmacro.h

index b97444b3c4e1727653ab7d6f9b88267ce97d16a9..d6f0d41f8033667071b27fcfdd52f8316993d094 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.\r
+       FreeRTOS.org V4.7.2 - Copyright (C) 2003-2008 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
 #include "xintc.h"\r
 #include "xintc_i.h"\r
 \r
-/* Standard includes. */\r
-#include <string.h>\r
-\r
 /*-----------------------------------------------------------*/\r
 \r
-#define portCRITICAL_INTERRUPT_ENABLE  ( 0UL << 17UL )\r
+/* Definitions to set the initial MSR of each task. */\r
+#define portCRITICAL_INTERRUPT_ENABLE  ( 1UL << 17UL )\r
 #define portEXTERNAL_INTERRUPT_ENABLE  ( 1UL << 15UL )\r
-#define portMACHINE_CHECK_ENABLE               ( 0UL << 12UL )\r
+#define portMACHINE_CHECK_ENABLE               ( 1UL << 12UL )\r
 #define portINITIAL_MSR                ( portCRITICAL_INTERRUPT_ENABLE | portEXTERNAL_INTERRUPT_ENABLE | portMACHINE_CHECK_ENABLE )\r
 \r
+/*-----------------------------------------------------------*/\r
+\r
 /*\r
+ * Setup the system timer to generate the tick interrupt.\r
  */\r
 static void prvSetupTimerInterrupt( void );\r
+\r
+/*\r
+ * The handler for the tick interrupt - defined in portasm.s.\r
+ */\r
 extern void vPortTickISR( void );\r
+\r
+/*\r
+ * The handler for the yield function - defined in portasm.s.\r
+ */\r
 extern void vPortYield( void );\r
+\r
+/*\r
+ * Function to start the scheduler running by starting the highest\r
+ * priority task that has thus far been created.\r
+ */\r
 extern void vPortStartFirstTask( void );\r
 \r
+/*-----------------------------------------------------------*/\r
+\r
+/* Structure used to hold the state of the interrupt controller. */\r
 static XIntc xInterruptController;\r
 \r
+/*-----------------------------------------------------------*/\r
+\r
 /* \r
- * Initialise the stack of a task to look exactly as if a call to \r
- * portSAVE_CONTEXT had been made.\r
+ * Initialise the stack of a task to look exactly as if the task had been\r
+ * interrupted.\r
  * \r
  * See the header file portable.h.\r
  */\r
@@ -165,7 +184,6 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
        *pxTopOfStack = ( portSTACK_TYPE ) vPortStartFirstTask;/* Next LR. */\r
        pxTopOfStack--;\r
        *pxTopOfStack = 0x00000000UL;;/* Backchain. */\r
-//     pxTopOfStack--;\r
 \r
        return pxTopOfStack;\r
 }\r
@@ -173,14 +191,8 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
 \r
 portBASE_TYPE xPortStartScheduler( void )\r
 {\r
-extern void *pxCurrentTCB;\r
-\r
        prvSetupTimerInterrupt();\r
-\r
        XExc_RegisterHandler( XEXC_ID_SYSTEM_CALL, ( XExceptionHandler ) vPortYield, ( void * ) 0 );\r
-\r
-//     XExc_mEnableExceptions( XEXC_NON_CRITICAL );\r
-\r
        vPortStartFirstTask();\r
 \r
        /* Should not get here as the tasks are now running! */\r
@@ -197,7 +209,6 @@ void vPortEndScheduler( void )
 /*\r
  * Hardware initialisation to generate the RTOS tick.   \r
  */\r
-static void prvTickISR( void );\r
 static void prvSetupTimerInterrupt( void )\r
 {\r
 const unsigned portLONG ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );\r
@@ -216,69 +227,43 @@ const unsigned portLONG ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static void prvTickISR( void )\r
-{\r
-static unsigned portLONG ulTicks = 0;\r
-\r
-       ulTicks++;\r
-       if( ulTicks >= 1000 )\r
-       {\r
-               vParTestToggleLED( 0 );\r
-               ulTicks = 0;\r
-       }\r
-       XTime_PITClearInterrupt();\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
 void vPortISRHandler( void *vNullDoNotUse )\r
 {\r
-Xuint32 IntrStatus;\r
-Xuint32 IntrMask = 1;\r
-int IntrNumber;\r
-//extern XIntc xInterruptController;\r
-XIntc_Config *CfgPtr;// = xInterruptController.CfgPtr;\r
-         \r
-    /* Get the configuration data using the device ID */\r
-    //CfgPtr = &XIntc_ConfigTable[(Xuint32)DeviceId];\r
-       CfgPtr = &XIntc_ConfigTable[(Xuint32)XPAR_OPB_INTC_0_DEVICE_ID];\r
+unsigned portLONG ulInterruptStatus, ulInterruptMask = 1UL;\r
+portBASE_TYPE xInterruptNumber;\r
+XIntc_Config *pxInterruptController;\r
+XIntc_VectorTableEntry *pxTable;\r
+\r
+       /* Get the configuration by using the device ID - in this case it is\r
+       assumed that only one interrupt controller is being used. */\r
+       pxInterruptController = &XIntc_ConfigTable[ XPAR_OPB_INTC_0_DEVICE_ID ];\r
   \r
-    /* Get the interrupts that are waiting to be serviced */\r
-    IntrStatus = XIntc_mGetIntrStatus(CfgPtr->BaseAddress);\r
+       /* Which interrupts are pending? */\r
+       ulInterruptStatus = XIntc_mGetIntrStatus( pxInterruptController->BaseAddress );\r
   \r
-    /* Service each interrupt that is active and enabled by checking each\r
-     * bit in the register from LSB to MSB which corresponds to an interrupt\r
-     * intput signal\r
-     */\r
-    for (IntrNumber = 0; IntrNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS;\r
-         IntrNumber++)\r
-    {\r
-        if (IntrStatus & 1)\r
-        {\r
-            XIntc_VectorTableEntry *TablePtr;\r
-      \r
-            /* The interrupt is active and enabled, call the interrupt\r
-             * handler that was setup with the specified parameter\r
-             */\r
-            TablePtr = &(CfgPtr->HandlerTable[IntrNumber]);\r
-            TablePtr->Handler(TablePtr->CallBackRef);\r
-\r
-                       /* Clear the interrupt. */      \r
-            XIntc_mAckIntr(CfgPtr->BaseAddress, IntrMask);\r
+       for( xInterruptNumber = 0; xInterruptNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS; xInterruptNumber++ )\r
+       {\r
+               if( ulInterruptStatus & 0x01UL )\r
+               {\r
+                       /* Call the registered handler. */\r
+                       pxTable = &( pxInterruptController->HandlerTable[ xInterruptNumber ] );\r
+                       pxTable->Handler( pxTable->CallBackRef );\r
+\r
+                       /* Clear the pending interrupt. */\r
+                       XIntc_mAckIntr( pxInterruptController->BaseAddress, ulInterruptMask );\r
                        break;\r
-        }\r
+               }\r
         \r
-        /* Move to the next interrupt to check */\r
-        IntrMask <<= 1;\r
-        IntrStatus >>= 1;\r
-      \r
-        /* If there are no other bits set indicating that all interrupts\r
-         * have been serviced, then exit the loop\r
-         */\r
-        if (IntrStatus == 0)\r
-        {\r
-            break;\r
-        }\r
-    }\r
+               /* Check the next interrupt. */\r
+               ulInterruptMask <<= 0x01UL;\r
+               ulInterruptStatus >>= 0x01UL;\r
+\r
+               /* Have we serviced all interrupts? */\r
+               if( ulInterruptStatus == 0UL )\r
+               {\r
+                       break;\r
+               }\r
+       }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -286,9 +271,16 @@ void vPortSetupInterruptController( void )
 {\r
 extern void vPortISRWrapper( void );\r
 \r
+       /* Perform all library calls necessary to initialise the exception table\r
+       and interrupt controller.  This assumes only one interrupt controller is in\r
+       use. */\r
        XExc_mDisableExceptions( XEXC_NON_CRITICAL );\r
        XExc_Init();\r
-       XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, (XExceptionHandler)vPortISRWrapper, NULL );\r
+\r
+       /* The library functions save the context - we then jump to a wrapper to\r
+       save the stack into the TCB.  The wrapper then calls the handler defined\r
+       above. */\r
+       XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL );\r
        XIntc_Initialize( &xInterruptController, XPAR_OPB_INTC_0_DEVICE_ID );\r
        XIntc_Start( &xInterruptController, XIN_REAL_MODE );\r
 }\r
@@ -298,6 +290,9 @@ portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XIn
 {\r
 portBASE_TYPE xReturn = pdFAIL;\r
 \r
+       /* This function is defined here so the scope of xInterruptController can\r
+       remain within this file. */\r
+\r
        if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )\r
        {\r
                XIntc_Enable( &xInterruptController, ucInterruptID );\r
index 64b511ed8dfcb25e2d2a19601212072566310aa9..2957b45e5d7d9c64007a51fb49068a5f33c2b43e 100644 (file)
        .global vPortTickISR\r
        .global vPortISRWrapper\r
 \r
-.set portCONTEXT_SIZE, 156\r
-.set portR0_OFFSET, 152\r
-.set portGPR_OFFSET, 32\r
-.set portCR_OFFSET, 28\r
-.set portXER_OFFSET, 24\r
-.set portLR_OFFSET, 16\r
-.set portCTR_OFFSET, 16\r
-.set portUSPRG0_OFFSET, 12\r
-.set portSRR0_OFFSET, 8\r
-.set portSRR1_OFFSET, 4\r
-\r
-\r
 .set   BChainField, 0\r
 .set   NextLRField, BChainField + 4\r
 .set   MSRField,    NextLRField + 4\r
 .set   IFrameSize,  r3r31Field  + ( ( 31 - 3 ) + 1 ) * 4\r
 \r
 \r
-.macro portRESTORE_CONTEXT\r
+.macro portSAVE_STACK_POINTER_AND_LR\r
 \r
-       # Get the address of the TCB.\r
+       # Get the address of the TCB.                           \r
        xor             R0, R0, R0\r
-    addis   SP, R0, pxCurrentTCB@ha\r
-    lwz                SP,     pxCurrentTCB@l( SP )\r
-\r
-       # Get the task stack pointer from the TCB.\r
-       lwz             SP, 0( SP )\r
+       addis   R2, R0, pxCurrentTCB@ha\r
+       lwz             R2,     pxCurrentTCB@l( R2 )\r
 \r
-       # Pop the special purpose registers\r
-       lwz             R0, portSRR1_OFFSET( SP )\r
-       mtspr   SRR1, R0\r
-       lwz             R0, portSRR0_OFFSET( SP )\r
-       mtspr   SRR0, R0\r
-       lwz             R0, portUSPRG0_OFFSET( SP )\r
-       mtspr   256, R0 #USPRG0\r
-       lwz             R0, portCTR_OFFSET( SP )\r
-       mtspr   CTR, R0\r
-       lwz             R0, portLR_OFFSET( SP )\r
-       mtspr   LR, R0\r
-       lwz             R0, portXER_OFFSET( SP )\r
-       mtspr   XER, R0\r
-       lwz             R0, portCR_OFFSET( SP )\r
-       mtcr    R0\r
+       # Store the stack pointer into the TCB\r
+       stw             SP,     0( R2 )\r
 \r
-       # Pop GPRs\r
-       lmw             R2, portGPR_OFFSET( SP )\r
+       # Save the link register\r
+       stwu    R1, -24( R1 )\r
+       mflr    R0\r
+       stw             R31, 20( R1 )\r
+       stw             R0, 28( R1 )\r
+       mr              R31, r1\r
 \r
-       # Finally pop R0 and correct the stack pointer\r
-       lwz             R0, portR0_OFFSET( SP )\r
-       addi    R1, R1, portCONTEXT_SIZE\r
+.endm\r
 \r
-       # Start the task running\r
-       rfi\r
+.macro portRESTORE_STACK_POINTER_AND_LR\r
 \r
-       .endm\r
-\r
-.macro portSAVE_CONTEXT\r
-\r
-       # Make room on the stack.\r
-       subi    R1, R1, portCONTEXT_SIZE\r
-\r
-       # Push R0, then the GPRs\r
-       stw             R0, portR0_OFFSET( SP )\r
-       stm             R2, portGPR_OFFSET( SP )\r
-\r
-       # Push the SFRs\r
-       mfcr    R0\r
-       stw             R0, portCR_OFFSET( SP )\r
-       mfspr   R0, XER\r
-       stw             R0, portXER_OFFSET( SP )\r
-       mfspr   R0, LR\r
-       stw             R0, portLR_OFFSET( SP )\r
-       mfspr   R0, CTR\r
-       stw             R0, portCTR_OFFSET( SP )\r
-       mfspr   R0, 256 #USPRG0\r
-       stw             R0, portUSPRG0_OFFSET( SP )\r
-       mfspr   R0, SRR0\r
-       stw             R0, portSRR0_OFFSET( SP )\r
-       mfspr   R0, SRR1\r
-       stw             R0, portSRR1_OFFSET( SP )\r
+       # Restore the link register\r
+       lwz             R11, 0( R1 )\r
+       lwz             R0, 4( R11 )\r
+       mtlr    R0\r
+       lwz             R31, -4( R11 )\r
+       mr              R1, R11\r
 \r
        # Get the address of the TCB.\r
        xor             R0, R0, R0\r
-       addis   R2, R0, pxCurrentTCB@ha\r
-       lwz             R2,     pxCurrentTCB@l( R2 )\r
+       addis   SP, R0, pxCurrentTCB@ha\r
+       lwz             SP,     pxCurrentTCB@l( R1 )\r
 \r
-       # Store the stack pointer into the TCB\r
-       stw             SP,     0( R2 )\r
+       # Get the task stack pointer from the TCB.\r
+       lwz             SP, 0( SP )\r
 \r
-       .endm\r
+.endm\r
 \r
 \r
-.macro int_epilogue\r
+vPortStartFirstTask:\r
 \r
        # Get the address of the TCB.\r
        xor             R0, R0, R0\r
        lwz             SP, 0( SP )\r
        \r
        # Restore MSR register to SRR1.\r
-       lwz     R0,MSRField(R1)\r
+       lwz             R0, MSRField(R1)\r
        mtsrr1  R0\r
        \r
        # Restore current PC location to SRR0.\r
-       lwz     R0,PCField(R1)\r
+       lwz             R0, PCField(R1)\r
        mtsrr0  R0\r
 \r
-       # Save USPRG0 register\r
-       lwz     R0,USPRG0Field(R1)\r
+       # Save  USPRG0 register\r
+       lwz             R0, USPRG0Field(R1)\r
        mtspr   0x100,R0\r
        \r
        # Restore Condition register\r
-       lwz     R0,CRField(R1)\r
+       lwz             R0, CRField(R1)\r
        mtcr    R0\r
        \r
        # Restore Fixed Point Exception register\r
-       lwz     R0,XERField(R1)\r
+       lwz             R0, XERField(R1)\r
        mtxer   R0\r
        \r
        # Restore Counter register\r
-       lwz     R0,CTRField(R1)\r
+       lwz             R0, CTRField(R1)\r
        mtctr   R0\r
        \r
        # Restore Link register\r
-       lwz     R0,LRField(R1)\r
+       lwz             R0, LRField(R1)\r
        mtlr    R0\r
        \r
        # Restore remaining GPR registers.\r
        lmw     R3,r3r31Field(R1)\r
        \r
        # Restore r0 and r2.\r
-       lwz     R0,r0Field(R1)\r
-       lwz     R2,r2Field(R1)\r
+       lwz             R0, r0Field(R1)\r
+       lwz             R2, r2Field(R1)\r
        \r
        # Remove frame from stack\r
        addi    R1,R1,IFrameSize\r
-       \r
-.endm\r
 \r
-.macro portENTER_SWITCHING_ISR\r
-\r
-       # Get the address of the TCB.                           \r
-       xor             R0, R0, R0\r
-       addis   R2, R0, pxCurrentTCB@ha\r
-       lwz             R2,     pxCurrentTCB@l( R2 )\r
-\r
-       # Store the stack pointer into the TCB\r
-       stw             SP,     0( R2 )\r
-\r
-       # Save the link register\r
-       stwu    R1, -24( R1 )\r
-       mflr    R0\r
-       stw             R31, 20( R1 )\r
-       stw             R0, 28( R1 )\r
-       mr              R31, r1\r
-\r
-.endm\r
-\r
-.macro portEXIT_SWITCHING_ISR\r
-\r
-       # Restore the link register\r
-       lwz             R11, 0( R1 )\r
-       lwz             R0, 4( R11 )\r
-       mtlr    R0\r
-       lwz             R31, -4( R11 )\r
-       mr              R1, R11\r
-\r
-       # Get the address of the TCB.\r
-       xor             R0, R0, R0\r
-       addis   SP, R0, pxCurrentTCB@ha\r
-       lwz             SP,     pxCurrentTCB@l( R1 )\r
-\r
-       # Get the task stack pointer from the TCB.\r
-       lwz             SP, 0( SP )\r
-\r
-.endm\r
-\r
-\r
-vPortStartFirstTask:\r
-\r
-       int_epilogue\r
+       # Return into the first task\r
        rfi\r
 \r
-#vPortStartFirstTask:\r
-#      portRESTORE_CONTEXT\r
-#      rfi\r
-\r
 \r
 \r
 vPortYield:\r
 \r
-       portENTER_SWITCHING_ISR\r
+       portSAVE_STACK_POINTER_AND_LR\r
        bl vTaskSwitchContext\r
-       portEXIT_SWITCHING_ISR\r
+       portRESTORE_STACK_POINTER_AND_LR\r
        blr\r
 \r
 vPortTickISR:\r
 \r
-       portENTER_SWITCHING_ISR\r
+       portSAVE_STACK_POINTER_AND_LR\r
        bl vTaskIncrementTick\r
        #if configUSE_PREEMPTION == 1\r
                bl vTaskSwitchContext\r
@@ -230,12 +136,12 @@ vPortTickISR:
        lis             R0, 2048\r
        mttsr   R0\r
 \r
-       portEXIT_SWITCHING_ISR\r
+       portRESTORE_STACK_POINTER_AND_LR\r
        blr\r
 \r
 vPortISRWrapper:\r
 \r
-       portENTER_SWITCHING_ISR\r
+       portSAVE_STACK_POINTER_AND_LR\r
        bl vPortISRHandler\r
-       portEXIT_SWITCHING_ISR\r
+       portRESTORE_STACK_POINTER_AND_LR\r
        blr\r
index 6ba2c7f0847c846d599dfcacd03c9caa847c71ce..84fe0540bb9f323b4a23cd9531c89b30b701b6f2 100644 (file)
@@ -77,6 +77,8 @@ extern "C" {
 #endif\r
 /*-----------------------------------------------------------*/        \r
 \r
+/* This port uses the critical nesting count from the TCB rather than\r
+maintaining a separate value and then saving this value in the task stack. */\r
 #define portCRITICAL_NESTING_IN_TCB            1\r
 \r
 /* Interrupt control macros. */\r
@@ -97,6 +99,7 @@ void vTaskExitCritical( void );
 void vPortYield( void );\r
 #define portYIELD() asm volatile ( "SC \n\t NOP" )\r
 #define portYIELD_FROM_ISR() vTaskSwitchContext()\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* Hardware specifics. */\r
@@ -110,7 +113,7 @@ void vPortYield( void );
 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
 \r
-/* Port specific initialisation function. */\r
+/* Port specific interrupt handling functions. */\r
 void vPortSetupInterruptController( void );\r
 portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );\r
 \r