]> git.sur5r.net Git - freertos/blob - Source/portable/GCC/PPC405/port.c
PPC405 work in progress.
[freertos] / Source / portable / GCC / PPC405 / port.c
1 /*\r
2         FreeRTOS.org V4.7.1 - 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         Please ensure to read the configuration and relevant port sections of the \r
29         online documentation.\r
30 \r
31         +++ http://www.FreeRTOS.org +++\r
32         Documentation, latest information, license and contact details.  \r
33 \r
34         +++ http://www.SafeRTOS.com +++\r
35         A version that is certified for use in safety critical systems.\r
36 \r
37         +++ http://www.OpenRTOS.com +++\r
38         Commercial support, development, porting, licensing and training services.\r
39 \r
40         ***************************************************************************\r
41 */\r
42 \r
43 /*-----------------------------------------------------------\r
44  * Implementation of functions defined in portable.h for the PPC405 port.\r
45  *----------------------------------------------------------*/\r
46 \r
47 \r
48 /* Scheduler includes. */\r
49 #include "FreeRTOS.h"\r
50 #include "task.h"\r
51 \r
52 /* Library includes. */\r
53 #include "xtime_l.h"\r
54 #include "xintc.h"\r
55 #include "xintc_i.h"\r
56 \r
57 /* Standard includes. */\r
58 #include <string.h>\r
59 \r
60 /*-----------------------------------------------------------*/\r
61 \r
62 #define portCRITICAL_INTERRUPT_ENABLE   ( 0UL << 17UL )\r
63 #define portEXTERNAL_INTERRUPT_ENABLE   ( 1UL << 15UL )\r
64 #define portMACHINE_CHECK_ENABLE                ( 0UL << 12UL )\r
65 #define portINITIAL_MSR         ( portCRITICAL_INTERRUPT_ENABLE | portEXTERNAL_INTERRUPT_ENABLE | portMACHINE_CHECK_ENABLE )\r
66 \r
67 /*\r
68  */\r
69 static void prvSetupTimerInterrupt( void );\r
70 extern void vPortTickISR( void );\r
71 extern void vPortYield( void );\r
72 extern void vPortStartFirstTask( void );\r
73 \r
74 static XIntc xInterruptController;\r
75 \r
76 /* \r
77  * Initialise the stack of a task to look exactly as if a call to \r
78  * portSAVE_CONTEXT had been made.\r
79  * \r
80  * See the header file portable.h.\r
81  */\r
82 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
83 {\r
84         /* Place a known value at the bottom of the stack for debugging. */\r
85         *pxTopOfStack = 0xDEADBEEF;\r
86         *pxTopOfStack--;\r
87 \r
88         /* EABI stack frame. */\r
89         *pxTopOfStack = 0x31313131UL;   /* R31. */\r
90         pxTopOfStack--;\r
91         *pxTopOfStack = 0x30303030UL;   /* R30. */\r
92         pxTopOfStack--;\r
93         *pxTopOfStack = 0x29292929UL;   /* R29. */\r
94         pxTopOfStack--;\r
95         *pxTopOfStack = 0x28282828UL;   /* R28. */\r
96         pxTopOfStack--;\r
97         *pxTopOfStack = 0x27272727UL;   /* R27. */\r
98         pxTopOfStack--;\r
99         *pxTopOfStack = 0x26262626UL;   /* R26. */\r
100         pxTopOfStack--;\r
101         *pxTopOfStack = 0x25252525UL;   /* R25. */\r
102         pxTopOfStack--;\r
103         *pxTopOfStack = 0x24242424UL;   /* R24. */\r
104         pxTopOfStack--;\r
105         *pxTopOfStack = 0x23232323UL;   /* R23. */\r
106         pxTopOfStack--;\r
107         *pxTopOfStack = 0x22222222UL;   /* R22. */\r
108         pxTopOfStack--;\r
109         *pxTopOfStack = 0x21212121UL;   /* R21. */\r
110         pxTopOfStack--;\r
111         *pxTopOfStack = 0x20202020UL;   /* R20. */\r
112         pxTopOfStack--;\r
113         *pxTopOfStack = 0x19191919UL;   /* R19. */\r
114         pxTopOfStack--;\r
115         *pxTopOfStack = 0x18181818UL;   /* R18. */\r
116         pxTopOfStack--;\r
117         *pxTopOfStack = 0x17171717UL;   /* R17. */\r
118         pxTopOfStack--;\r
119         *pxTopOfStack = 0x16161616UL;   /* R16. */\r
120         pxTopOfStack--;\r
121         *pxTopOfStack = 0x15151515UL;   /* R15. */\r
122         pxTopOfStack--;\r
123         *pxTopOfStack = 0x14141414UL;   /* R14. */\r
124         pxTopOfStack--;\r
125         *pxTopOfStack = 0x13131313UL;   /* R13. */\r
126         pxTopOfStack--;\r
127         *pxTopOfStack = 0x12121212UL;   /* R12. */\r
128         pxTopOfStack--;\r
129         *pxTopOfStack = 0x11111111UL;   /* R11. */\r
130         pxTopOfStack--;\r
131         *pxTopOfStack = 0x10101010UL;   /* R10. */\r
132         pxTopOfStack--;\r
133         *pxTopOfStack = 0x09090909UL;   /* R9. */\r
134         pxTopOfStack--;\r
135         *pxTopOfStack = 0x08080808UL;   /* R8. */\r
136         pxTopOfStack--;\r
137         *pxTopOfStack = 0x07070707UL;   /* R7. */\r
138         pxTopOfStack--;\r
139         *pxTopOfStack = 0x06060606UL;   /* R6. */\r
140         pxTopOfStack--;\r
141         *pxTopOfStack = 0x05050505UL;   /* R5. */\r
142         pxTopOfStack--;\r
143         *pxTopOfStack = 0x04040404UL;   /* R4. */\r
144         pxTopOfStack--;\r
145         *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;\r
146         pxTopOfStack--;\r
147         *pxTopOfStack = 0x02020202UL;   /* R2. */\r
148         pxTopOfStack--;\r
149         *pxTopOfStack = 0x10000001UL;;  /* R0. */\r
150         pxTopOfStack--;\r
151         *pxTopOfStack = 0x00000000UL;   /* USPRG0. */\r
152         pxTopOfStack--;\r
153         *pxTopOfStack = 0x00000000UL;   /* CR. */\r
154         pxTopOfStack--;\r
155         *pxTopOfStack = 0x00000000UL;   /* XER. */\r
156         pxTopOfStack--;\r
157         *pxTopOfStack = 0x00000000UL;   /* CTR. */\r
158         pxTopOfStack--;\r
159         *pxTopOfStack = ( portSTACK_TYPE ) vPortStartFirstTask; /* LR. */\r
160         pxTopOfStack--;\r
161         *pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* SRR0. */\r
162         pxTopOfStack--;\r
163         *pxTopOfStack = portINITIAL_MSR;/* SRR1. */\r
164         pxTopOfStack--;\r
165         *pxTopOfStack = ( portSTACK_TYPE ) vPortStartFirstTask;/* Next LR. */\r
166         pxTopOfStack--;\r
167         *pxTopOfStack = 0x00000000UL;;/* Backchain. */\r
168 //      pxTopOfStack--;\r
169 \r
170         return pxTopOfStack;\r
171 }\r
172 /*-----------------------------------------------------------*/\r
173 \r
174 portBASE_TYPE xPortStartScheduler( void )\r
175 {\r
176 extern void *pxCurrentTCB;\r
177 \r
178         prvSetupTimerInterrupt();\r
179 \r
180         XExc_RegisterHandler( XEXC_ID_SYSTEM_CALL, ( XExceptionHandler ) vPortYield, ( void * ) 0 );\r
181 \r
182 //      XExc_mEnableExceptions( XEXC_NON_CRITICAL );\r
183 \r
184         vPortStartFirstTask();\r
185 \r
186         /* Should not get here as the tasks are now running! */\r
187         return pdFALSE;\r
188 }\r
189 /*-----------------------------------------------------------*/\r
190 \r
191 void vPortEndScheduler( void )\r
192 {\r
193         /* Not implemented. */\r
194 }\r
195 /*-----------------------------------------------------------*/\r
196 \r
197 /*\r
198  * Hardware initialisation to generate the RTOS tick.   \r
199  */\r
200 static void prvTickISR( void );\r
201 static void prvSetupTimerInterrupt( void )\r
202 {\r
203 const unsigned portLONG ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );\r
204 \r
205         XTime_PITClearInterrupt();\r
206         XTime_FITClearInterrupt();\r
207         XTime_WDTClearInterrupt();\r
208         XTime_WDTDisableInterrupt();\r
209         XTime_FITDisableInterrupt();\r
210 \r
211         XExc_RegisterHandler( XEXC_ID_PIT_INT, ( XExceptionHandler ) vPortTickISR, ( void * ) 0 );\r
212 \r
213         XTime_PITEnableAutoReload();\r
214         XTime_PITSetInterval( ulInterval );\r
215         XTime_PITEnableInterrupt();\r
216 }\r
217 /*-----------------------------------------------------------*/\r
218 \r
219 static void prvTickISR( void )\r
220 {\r
221 static unsigned portLONG ulTicks = 0;\r
222 \r
223         ulTicks++;\r
224         if( ulTicks >= 1000 )\r
225         {\r
226                 vParTestToggleLED( 0 );\r
227                 ulTicks = 0;\r
228         }\r
229         XTime_PITClearInterrupt();\r
230 }\r
231 /*-----------------------------------------------------------*/\r
232 \r
233 void vPortISRHandler( void *vNullDoNotUse )\r
234 {\r
235 Xuint32 IntrStatus;\r
236 Xuint32 IntrMask = 1;\r
237 int IntrNumber;\r
238 //extern XIntc xInterruptController;\r
239 XIntc_Config *CfgPtr;// = xInterruptController.CfgPtr;\r
240           \r
241     /* Get the configuration data using the device ID */\r
242     //CfgPtr = &XIntc_ConfigTable[(Xuint32)DeviceId];\r
243         CfgPtr = &XIntc_ConfigTable[(Xuint32)XPAR_OPB_INTC_0_DEVICE_ID];\r
244   \r
245     /* Get the interrupts that are waiting to be serviced */\r
246     IntrStatus = XIntc_mGetIntrStatus(CfgPtr->BaseAddress);\r
247   \r
248     /* Service each interrupt that is active and enabled by checking each\r
249      * bit in the register from LSB to MSB which corresponds to an interrupt\r
250      * intput signal\r
251      */\r
252     for (IntrNumber = 0; IntrNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS;\r
253          IntrNumber++)\r
254     {\r
255         if (IntrStatus & 1)\r
256         {\r
257             XIntc_VectorTableEntry *TablePtr;\r
258       \r
259             /* The interrupt is active and enabled, call the interrupt\r
260              * handler that was setup with the specified parameter\r
261              */\r
262             TablePtr = &(CfgPtr->HandlerTable[IntrNumber]);\r
263             TablePtr->Handler(TablePtr->CallBackRef);\r
264 \r
265                         /* Clear the interrupt. */      \r
266             XIntc_mAckIntr(CfgPtr->BaseAddress, IntrMask);\r
267                         break;\r
268         }\r
269         \r
270         /* Move to the next interrupt to check */\r
271         IntrMask <<= 1;\r
272         IntrStatus >>= 1;\r
273       \r
274         /* If there are no other bits set indicating that all interrupts\r
275          * have been serviced, then exit the loop\r
276          */\r
277         if (IntrStatus == 0)\r
278         {\r
279             break;\r
280         }\r
281     }\r
282 }\r
283 /*-----------------------------------------------------------*/\r
284 \r
285 void vPortSetupInterruptController( void )\r
286 {\r
287 extern void vPortISRWrapper( void );\r
288 \r
289         XExc_mDisableExceptions( XEXC_NON_CRITICAL );\r
290         XExc_Init();\r
291         XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, (XExceptionHandler)vPortISRWrapper, NULL );\r
292         XIntc_Initialize( &xInterruptController, XPAR_OPB_INTC_0_DEVICE_ID );\r
293         XIntc_Start( &xInterruptController, XIN_REAL_MODE );\r
294 }\r
295 /*-----------------------------------------------------------*/\r
296 \r
297 portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )\r
298 {\r
299 portBASE_TYPE xReturn = pdFAIL;\r
300 \r
301         if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )\r
302         {\r
303                 XIntc_Enable( &xInterruptController, ucInterruptID );\r
304                 xReturn = pdPASS;\r
305         }\r
306 \r
307         return xReturn;         \r
308 }\r