]> git.sur5r.net Git - freertos/blob - Source/portable/GCC/CORTUS_APS3/port.c
Work in progress on the Cortus port.
[freertos] / Source / portable / GCC / CORTUS_APS3 / port.c
1 /*
2     FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd.
3
4     ***************************************************************************
5     *                                                                         *
6     * If you are:                                                             *
7     *                                                                         *
8     *    + New to FreeRTOS,                                                   *
9     *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
10     *    + Looking for basic training,                                        *
11     *    + Wanting to improve your FreeRTOS skills and productivity           *
12     *                                                                         *
13     * then take a look at the FreeRTOS eBook                                  *
14     *                                                                         *
15     *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
16     *                  http://www.FreeRTOS.org/Documentation                  *
17     *                                                                         *
18     * A pdf reference manual is also available.  Both are usually delivered   *
19     * to your inbox within 20 minutes to two hours when purchased between 8am *
20     * and 8pm GMT (although please allow up to 24 hours in case of            *
21     * exceptional circumstances).  Thank you for your support!                *
22     *                                                                         *
23     ***************************************************************************
24
25     This file is part of the FreeRTOS distribution.
26
27     FreeRTOS is free software; you can redistribute it and/or modify it under
28     the terms of the GNU General Public License (version 2) as published by the
29     Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
30     ***NOTE*** The exception to the GPL is included to allow you to distribute
31     a combined work that includes FreeRTOS without being obliged to provide the
32     source code for proprietary components outside of the FreeRTOS kernel.
33     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
34     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36     more details. You should have received a copy of the GNU General Public
37     License and the FreeRTOS license exception along with FreeRTOS; if not it
38     can be viewed here: http://www.freertos.org/a00114.html and also obtained
39     by writing to Richard Barry, contact details for whom are available on the
40     FreeRTOS WEB site.
41
42     1 tab == 4 spaces!
43
44     http://www.FreeRTOS.org - Documentation, latest information, license and
45     contact details.
46
47     http://www.SafeRTOS.com - A version that is certified for use in safety
48     critical systems.
49
50     http://www.OpenRTOS.com - Commercial support, development, porting,
51     licensing and training services.
52 */
53
54 /* Standard includes. */
55 #include <stdlib.h>
56
57 /* Kernel includes. */
58 #include "FreeRTOS.h"
59 #include "task.h"
60
61 /* Machine includes */
62 #include <machine/counter.h>
63 #include <machine/ic.h>
64 /*-----------------------------------------------------------*/
65
66 /* The initial PSR has the Previous Interrupt Enabled (PIEN) flag set. */
67 #define portINITIAL_PSR                 ( 0x00020000 )
68
69 /*-----------------------------------------------------------*/
70
71 /*
72  * Perform any hardware configuration necessary to generate the tick interrupt.
73  */
74 static void prvSetupTimerInterrupt( void );
75 /*-----------------------------------------------------------*/
76
77 /* Variables used to hold interrupt and critical nesting depths, with variables
78 that provide a convenient method of obtaining their addresses. */
79 volatile unsigned portBASE_TYPE uxInterruptNestingCount = 999UL;
80 const volatile unsigned portBASE_TYPE *puxInterruptNestingCount = &uxInterruptNestingCount;
81 volatile unsigned portBASE_TYPE uxInterruptStack[ configMINIMAL_STACK_SIZE ];
82 const volatile unsigned portBASE_TYPE *puxTopOfInterruptStack = &( uxInterruptStack[ configMINIMAL_STACK_SIZE - 1 ] );
83 /*-----------------------------------------------------------*/
84
85 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
86 {
87         /* For the time being, mimic the stack when using the
88         __attribute__((interrupt)) plus the extra caller saved registers. */
89         pxTopOfStack -= 17;
90
91         /* RTT */
92         pxTopOfStack[ 16 ] = ( portSTACK_TYPE )pxCode;
93
94         /* PSR */
95         pxTopOfStack[ 15 ] = portINITIAL_PSR;
96
97         /* R14 and R15 aka FuncSP and LR, respectively */
98         pxTopOfStack[ 14 ] = 0x00000000;
99         pxTopOfStack[ 13 ] = ( portSTACK_TYPE )( pxTopOfStack + 17 );
100
101         /* R7 to R2 */
102         pxTopOfStack[ 12 ] = 0x07070707;
103         pxTopOfStack[ 11 ] = 0x06060606;
104         pxTopOfStack[ 10 ] = 0x05050505;
105         pxTopOfStack[ 9 ] = 0x04040404;
106         pxTopOfStack[ 8 ] = 0x03030303;
107         pxTopOfStack[ 7 ] = ( portSTACK_TYPE )pvParameters;
108
109         /* Set the Interrupt Priority on Task entry. */
110         pxTopOfStack[ 6 ] = portKERNEL_INTERRUPT_PRIORITY_LEVEL;
111
112         /* R13 to R8. */
113         pxTopOfStack[ 5 ] = 0x0D0D0D0D;
114         pxTopOfStack[ 4 ] = 0x0C0C0C0C;
115         pxTopOfStack[ 3 ] = 0x0B0B0B0B;
116         pxTopOfStack[ 2 ] = 0x0A0A0A0A;
117         pxTopOfStack[ 1 ] = 0x09090909;
118         pxTopOfStack[ 0 ] = 0x08080808;
119
120         return pxTopOfStack;
121 }
122 /*-----------------------------------------------------------*/
123
124 portBASE_TYPE xPortStartScheduler( void )
125 {
126         /* Set-up the timer interrupt. */
127         prvSetupTimerInterrupt();
128
129         /* Enable the TRAP yield. */
130         irq[ portIRQ_TRAP_YIELD ].ien = 1;
131         irq[ portIRQ_TRAP_YIELD ].ipl = portKERNEL_INTERRUPT_PRIORITY_LEVEL;
132
133         /* Integrated Interrupt Controller: Enable all interrupts. */
134         ic->ien = 1;
135         uxInterruptNestingCount = 1UL;
136
137         /* Restore calleree saved registers. */
138         portRESTORE_CONTEXT_REDUCED();
139
140         /* Mimic an ISR epilogue to start the task executing. */
141         asm __volatile__(                                               \
142                 "mov    r1, r14                                 \n"     \
143                 "ldd    r6, [r1]+0x20                   \n"     \
144                 "mov    psr, r6                                 \n"     \
145                 "mov    rtt, r7                                 \n"     \
146                 "ldd    r14, [r1]+0x18                  \n"     \
147                 "ldq    r4, [r1]+0x8                    \n"     \
148                 "ldd    r2, [r1]                                \n"     \
149                 "add    r1, #0x28                               \n"     \
150                 "rti                                                    \n"     \
151                 );                                                                      \
152
153         /* Should not get here. */
154         return 0;
155 }
156 /*-----------------------------------------------------------*/
157
158 static void prvSetupTimerInterrupt( void )
159 {
160         /* Enable timer interrupts */
161         counter1->reload = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1;
162         counter1->value = counter1->reload;
163         counter1->mask = 1;
164
165         /* Set the IRQ Handler priority and enable it. */
166         irq[ IRQ_COUNTER1 ].ien = 1;
167         irq[ IRQ_COUNTER1 ].ipl = portKERNEL_INTERRUPT_PRIORITY_LEVEL;
168 }
169 /*-----------------------------------------------------------*/
170
171 void interrupt_handler( portIRQ_TRAP_YIELD )
172 {
173         /* Save remaining registers. */
174         portSAVE_CONTEXT_REDUCED();
175
176         /* Perform the actual Yield. */
177         portYIELD_FROM_ISR();
178
179         /* Restore the first lot of registers, the remains will be resotred when
180         this function exits. */
181         portRESTORE_CONTEXT_REDUCED();
182 }
183 /*-----------------------------------------------------------*/
184
185 /* Timer tick interrupt handler */
186 void interrupt_handler( IRQ_COUNTER1 )
187 {
188         portSAVE_CONTEXT_REDUCED();
189
190         asm __volatile__(
191                         " sub           r1, #4                  \n"             /* Make space on the stack.  r1 is stack pointer. */
192                         " movhi         r2, #16384              \n"             /* Load the pointer to the IC. */
193                         " ldub          r3, [r2]+2              \n"             /* Copy the Current Priority Level. */
194                         " st            r3, [r1]                \n"             /* Store it on the stack. */
195                         " mov           r3, #%0                 \n"             /* Load the highest priority level. */
196                         " stb           r3, [r2]+2              \n"             /* Set the CPL to the highest level. */
197                         " call          vTaskIncrementTick      \n"     /* Increment the tick. */
198                         " ld            r3, [r1]                \n"             /* Load the previous CPL from the stack. */
199                         " movhi         r2, #16384              \n"             /* Load the pointer to the IC. */
200                         " stb           r3, [r2]+2              \n"             /* Set the CPL to the previous CPL. */
201                         " add           r1, #4                  "
202                         :
203                         :"i"( portSYSTEM_INTERRUPT_PRIORITY_LEVEL + 1 )
204                         :"r2","r3" /* Fix the stack. */
205         );
206
207         #if configUSE_PREEMPTION == 1
208                 portYIELD_FROM_ISR();
209         #endif
210
211         {
212                 /* Clear the Tick Interrupt. */
213                 counter1->expired = 0;
214         }
215
216         portRESTORE_CONTEXT_REDUCED();
217 }
218 /*-----------------------------------------------------------*/
219
220 void vPortEndScheduler( void )
221 {
222         /* Nothing to do. Unlikely to want to end. */
223 }
224 /*-----------------------------------------------------------*/