]> git.sur5r.net Git - freertos/blob - Source/portable/GCC/PPC405_Xilinx/port.c
Prepare for V5.0.4 release.
[freertos] / Source / portable / GCC / PPC405_Xilinx / port.c
1 /*\r
2         FreeRTOS.org V5.0.4 - Copyright (C) 2003-2008 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS.org distribution.\r
5 \r
6         FreeRTOS.org is free software; you can redistribute it and/or modify\r
7         it under the terms of the GNU General Public License as published by\r
8         the Free Software Foundation; either version 2 of the License, or\r
9         (at your option) any later version.\r
10 \r
11         FreeRTOS.org is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14         GNU General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU General Public License\r
17         along with FreeRTOS.org; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 \r
20         A special exception to the GPL can be applied should you wish to distribute\r
21         a combined work that includes FreeRTOS.org, without being obliged to provide\r
22         the source code for any proprietary components.  See the licensing section \r
23         of http://www.FreeRTOS.org for full details of how and when the exception\r
24         can be applied.\r
25 \r
26     ***************************************************************************\r
27     ***************************************************************************\r
28     *                                                                         *\r
29     * SAVE TIME AND MONEY!  We can port FreeRTOS.org to your own hardware,    *\r
30     * and even write all or part of your application on your behalf.          *\r
31     * See http://www.OpenRTOS.com for details of the services we provide to   *\r
32     * expedite your project.                                                  *\r
33     *                                                                         *\r
34     ***************************************************************************\r
35     ***************************************************************************\r
36 \r
37         Please ensure to read the configuration and relevant port sections of the\r
38         online documentation.\r
39 \r
40         http://www.FreeRTOS.org - Documentation, latest information, license and \r
41         contact details.\r
42 \r
43         http://www.SafeRTOS.com - A version that is certified for use in safety \r
44         critical systems.\r
45 \r
46         http://www.OpenRTOS.com - Commercial support, development, porting, \r
47         licensing and training services.\r
48 */\r
49 \r
50 /*-----------------------------------------------------------\r
51  * Implementation of functions defined in portable.h for the PPC405 port.\r
52  *----------------------------------------------------------*/\r
53 \r
54 \r
55 /* Scheduler includes. */\r
56 #include "FreeRTOS.h"\r
57 #include "task.h"\r
58 \r
59 /* Library includes. */\r
60 #include "xtime_l.h"\r
61 #include "xintc.h"\r
62 #include "xintc_i.h"\r
63 \r
64 /*-----------------------------------------------------------*/\r
65 \r
66 /* Definitions to set the initial MSR of each task. */\r
67 #define portCRITICAL_INTERRUPT_ENABLE   ( 1UL << 17UL )\r
68 #define portEXTERNAL_INTERRUPT_ENABLE   ( 1UL << 15UL )\r
69 #define portMACHINE_CHECK_ENABLE                ( 1UL << 12UL )\r
70 \r
71 #if configUSE_FPU == 1\r
72         #define portAPU_PRESENT                         ( 1UL << 25UL )\r
73         #define portFCM_FPU_PRESENT                     ( 1UL << 13UL )\r
74 #else\r
75         #define portAPU_PRESENT                         ( 0UL )\r
76         #define portFCM_FPU_PRESENT                     ( 0UL )\r
77 #endif\r
78 \r
79 #define portINITIAL_MSR         ( portCRITICAL_INTERRUPT_ENABLE | portEXTERNAL_INTERRUPT_ENABLE | portMACHINE_CHECK_ENABLE | portAPU_PRESENT | portFCM_FPU_PRESENT )\r
80 \r
81 /*-----------------------------------------------------------*/\r
82 \r
83 /*\r
84  * Setup the system timer to generate the tick interrupt.\r
85  */\r
86 static void prvSetupTimerInterrupt( void );\r
87 \r
88 /*\r
89  * The handler for the tick interrupt - defined in portasm.s.\r
90  */\r
91 extern void vPortTickISR( void );\r
92 \r
93 /*\r
94  * The handler for the yield function - defined in portasm.s.\r
95  */\r
96 extern void vPortYield( void );\r
97 \r
98 /*\r
99  * Function to start the scheduler running by starting the highest\r
100  * priority task that has thus far been created.\r
101  */\r
102 extern void vPortStartFirstTask( void );\r
103 \r
104 /*-----------------------------------------------------------*/\r
105 \r
106 /* Structure used to hold the state of the interrupt controller. */\r
107 static XIntc xInterruptController;\r
108 \r
109 /*-----------------------------------------------------------*/\r
110 \r
111 /* \r
112  * Initialise the stack of a task to look exactly as if the task had been\r
113  * interrupted.\r
114  * \r
115  * See the header file portable.h.\r
116  */\r
117 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
118 {\r
119         /* Place a known value at the bottom of the stack for debugging. */\r
120         *pxTopOfStack = 0xDEADBEEF;\r
121         pxTopOfStack--;\r
122 \r
123         /* EABI stack frame. */\r
124         pxTopOfStack -= 30;     /* Previous backchain and LR, R31 to R4 inclusive. */\r
125 \r
126         /* Parameters in R3. */\r
127         *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;\r
128         pxTopOfStack--;\r
129         *pxTopOfStack = 0x02020202UL;   /* R2. */\r
130         pxTopOfStack--;\r
131 \r
132         /* R1 is the stack pointer so is omitted. */\r
133 \r
134         *pxTopOfStack = 0x10000001UL;;  /* R0. */\r
135         pxTopOfStack--;\r
136         *pxTopOfStack = 0x00000000UL;   /* USPRG0. */\r
137         pxTopOfStack--;\r
138         *pxTopOfStack = 0x00000000UL;   /* CR. */\r
139         pxTopOfStack--;\r
140         *pxTopOfStack = 0x00000000UL;   /* XER. */\r
141         pxTopOfStack--;\r
142         *pxTopOfStack = 0x00000000UL;   /* CTR. */\r
143         pxTopOfStack--;\r
144         *pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler;   /* LR. */\r
145         pxTopOfStack--;\r
146         *pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* SRR0. */\r
147         pxTopOfStack--;\r
148         *pxTopOfStack = portINITIAL_MSR;/* SRR1. */\r
149         pxTopOfStack--;\r
150         *pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler;/* Next LR. */\r
151         pxTopOfStack--;\r
152         *pxTopOfStack = 0x00000000UL;/* Backchain. */\r
153 \r
154         return pxTopOfStack;\r
155 }\r
156 /*-----------------------------------------------------------*/\r
157 \r
158 portBASE_TYPE xPortStartScheduler( void )\r
159 {\r
160         prvSetupTimerInterrupt();\r
161         XExc_RegisterHandler( XEXC_ID_SYSTEM_CALL, ( XExceptionHandler ) vPortYield, ( void * ) 0 );\r
162         vPortStartFirstTask();\r
163 \r
164         /* Should not get here as the tasks are now running! */\r
165         return pdFALSE;\r
166 }\r
167 /*-----------------------------------------------------------*/\r
168 \r
169 void vPortEndScheduler( void )\r
170 {\r
171         /* Not implemented. */\r
172         for( ;; );\r
173 }\r
174 /*-----------------------------------------------------------*/\r
175 \r
176 /*\r
177  * Hardware initialisation to generate the RTOS tick.   \r
178  */\r
179 static void prvSetupTimerInterrupt( void )\r
180 {\r
181 const unsigned portLONG ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );\r
182 \r
183         XTime_PITClearInterrupt();\r
184         XTime_FITClearInterrupt();\r
185         XTime_WDTClearInterrupt();\r
186         XTime_WDTDisableInterrupt();\r
187         XTime_FITDisableInterrupt();\r
188 \r
189         XExc_RegisterHandler( XEXC_ID_PIT_INT, ( XExceptionHandler ) vPortTickISR, ( void * ) 0 );\r
190 \r
191         XTime_PITEnableAutoReload();\r
192         XTime_PITSetInterval( ulInterval );\r
193         XTime_PITEnableInterrupt();\r
194 }\r
195 /*-----------------------------------------------------------*/\r
196 \r
197 void vPortISRHandler( void *pvNullDoNotUse )\r
198 {\r
199 unsigned portLONG ulInterruptStatus, ulInterruptMask = 1UL;\r
200 portBASE_TYPE xInterruptNumber;\r
201 XIntc_Config *pxInterruptController;\r
202 XIntc_VectorTableEntry *pxTable;\r
203 \r
204         /* Just to remove compiler warning. */\r
205         ( void ) pvNullDoNotUse;        \r
206 \r
207         /* Get the configuration by using the device ID - in this case it is\r
208         assumed that only one interrupt controller is being used. */\r
209         pxInterruptController = &XIntc_ConfigTable[ XPAR_XPS_INTC_0_DEVICE_ID ];\r
210   \r
211         /* Which interrupts are pending? */\r
212         ulInterruptStatus = XIntc_mGetIntrStatus( pxInterruptController->BaseAddress );\r
213   \r
214         for( xInterruptNumber = 0; xInterruptNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS; xInterruptNumber++ )\r
215         {\r
216                 if( ulInterruptStatus & 0x01UL )\r
217                 {\r
218                         /* Clear the pending interrupt. */\r
219                         XIntc_mAckIntr( pxInterruptController->BaseAddress, ulInterruptMask );\r
220 \r
221                         /* Call the registered handler. */\r
222                         pxTable = &( pxInterruptController->HandlerTable[ xInterruptNumber ] );\r
223                         pxTable->Handler( pxTable->CallBackRef );\r
224                 }\r
225         \r
226                 /* Check the next interrupt. */\r
227                 ulInterruptMask <<= 0x01UL;\r
228                 ulInterruptStatus >>= 0x01UL;\r
229 \r
230                 /* Have we serviced all interrupts? */\r
231                 if( ulInterruptStatus == 0UL )\r
232                 {\r
233                         break;\r
234                 }\r
235         }\r
236 }\r
237 /*-----------------------------------------------------------*/\r
238 \r
239 void vPortSetupInterruptController( void )\r
240 {\r
241 extern void vPortISRWrapper( void );\r
242 \r
243         /* Perform all library calls necessary to initialise the exception table\r
244         and interrupt controller.  This assumes only one interrupt controller is in\r
245         use. */\r
246         XExc_mDisableExceptions( XEXC_NON_CRITICAL );\r
247         XExc_Init();\r
248 \r
249         /* The library functions save the context - we then jump to a wrapper to\r
250         save the stack into the TCB.  The wrapper then calls the handler defined\r
251         above. */\r
252         XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL );\r
253         XIntc_Initialize( &xInterruptController, XPAR_XPS_INTC_0_DEVICE_ID );\r
254         XIntc_Start( &xInterruptController, XIN_REAL_MODE );\r
255 }\r
256 /*-----------------------------------------------------------*/\r
257 \r
258 portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )\r
259 {\r
260 portBASE_TYPE xReturn = pdFAIL;\r
261 \r
262         /* This function is defined here so the scope of xInterruptController can\r
263         remain within this file. */\r
264 \r
265         if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )\r
266         {\r
267                 XIntc_Enable( &xInterruptController, ucInterruptID );\r
268                 xReturn = pdPASS;\r
269         }\r
270 \r
271         return xReturn;         \r
272 }\r