]> git.sur5r.net Git - freertos/blob
a3852a6cbd8a91d679dc8107e7f6509f1fe9fb9c
[freertos] /
1 /*\r
2     FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
3 \r
4 \r
5         FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:\r
6         Atollic AB - Atollic provides professional embedded systems development\r
7         tools for C/C++ development, code analysis and test automation.\r
8         See http://www.atollic.com\r
9 \r
10 \r
11     ***************************************************************************\r
12      *                                                                       *\r
13      *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
14      *    Complete, revised, and edited pdf reference manuals are also       *\r
15      *    available.                                                         *\r
16      *                                                                       *\r
17      *    Purchasing FreeRTOS documentation will not only help you, by       *\r
18      *    ensuring you get running as quickly as possible and with an        *\r
19      *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
20      *    the FreeRTOS project to continue with its mission of providing     *\r
21      *    professional grade, cross platform, de facto standard solutions    *\r
22      *    for microcontrollers - completely free of charge!                  *\r
23      *                                                                       *\r
24      *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
25      *                                                                       *\r
26      *    Thank you for using FreeRTOS, and thank you for your support!      *\r
27      *                                                                       *\r
28     ***************************************************************************\r
29 \r
30 \r
31     This file is part of the FreeRTOS distribution.\r
32 \r
33     FreeRTOS is free software; you can redistribute it and/or modify it under\r
34     the terms of the GNU General Public License (version 2) as published by the\r
35     Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
36     >>>NOTE<<< The modification to the GPL is included to allow you to\r
37     distribute a combined work that includes FreeRTOS without being obliged to\r
38     provide the source code for proprietary components outside of the FreeRTOS\r
39     kernel.  FreeRTOS is distributed in the hope that it will be useful, but\r
40     WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
41     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
42     more details. You should have received a copy of the GNU General Public\r
43     License and the FreeRTOS license exception along with FreeRTOS; if not it\r
44     can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
45     by writing to Richard Barry, contact details for whom are available on the\r
46     FreeRTOS WEB site.\r
47 \r
48     1 tab == 4 spaces!\r
49 \r
50     http://www.FreeRTOS.org - Documentation, latest information, license and\r
51     contact details.\r
52 \r
53     http://www.SafeRTOS.com - A version that is certified for use in safety\r
54     critical systems.\r
55 \r
56     http://www.OpenRTOS.com - Commercial support, development, porting,\r
57     licensing and training services.\r
58 */\r
59 \r
60 #include "FreeRTOSConfig.h"\r
61 #include "xparameters.h"\r
62 \r
63 /* The context is oversized to allow functions called from the ISR to write\r
64 back into the caller stack. */\r
65 #if XPAR_MICROBLAZE_0_USE_FPU == 1\r
66         #define portCONTEXT_SIZE 136\r
67 #else\r
68         #define portCONTEXT_SIZE 132\r
69 #endif\r
70 \r
71 /* Offsets from the stack pointer at which saved registers are placed. */\r
72 #define portR31_OFFSET  4\r
73 #define portR30_OFFSET  8\r
74 #define portR29_OFFSET  12\r
75 #define portR28_OFFSET  16\r
76 #define portR27_OFFSET  20\r
77 #define portR26_OFFSET  24\r
78 #define portR25_OFFSET  28\r
79 #define portR24_OFFSET  32\r
80 #define portR23_OFFSET  36\r
81 #define portR22_OFFSET  40\r
82 #define portR21_OFFSET  44\r
83 #define portR20_OFFSET  48\r
84 #define portR19_OFFSET  52\r
85 #define portR18_OFFSET  56\r
86 #define portR17_OFFSET  60\r
87 #define portR16_OFFSET  64\r
88 #define portR15_OFFSET  68\r
89 #define portR14_OFFSET  72\r
90 #define portR13_OFFSET  76\r
91 #define portR12_OFFSET  80\r
92 #define portR11_OFFSET  84\r
93 #define portR10_OFFSET  88\r
94 #define portR9_OFFSET   92\r
95 #define portR8_OFFSET   96\r
96 #define portR7_OFFSET   100\r
97 #define portR6_OFFSET   104\r
98 #define portR5_OFFSET   108\r
99 #define portR4_OFFSET   112\r
100 #define portR3_OFFSET   116\r
101 #define portR2_OFFSET   120\r
102 #define portCRITICAL_NESTING_OFFSET 124\r
103 #define portMSR_OFFSET 128\r
104 #define portFSR_OFFSET 132\r
105 \r
106         .extern pxCurrentTCB\r
107         .extern XIntc_DeviceInterruptHandler\r
108         .extern vTaskSwitchContext\r
109         .extern uxCriticalNesting\r
110         .extern pulISRStack\r
111         .extern ulTaskSwitchRequested\r
112 \r
113         .global _interrupt_handler\r
114         .global VPortYieldASM\r
115         .global vPortStartFirstTask\r
116 \r
117 \r
118 .macro portSAVE_CONTEXT\r
119 \r
120         /* Make room for the context on the stack. */\r
121         addik r1, r1, -portCONTEXT_SIZE\r
122 \r
123         /* Stack general registers. */\r
124         swi r31, r1, portR31_OFFSET\r
125         swi r30, r1, portR30_OFFSET\r
126         swi r29, r1, portR29_OFFSET\r
127         swi r28, r1, portR28_OFFSET\r
128         swi r27, r1, portR27_OFFSET\r
129         swi r26, r1, portR26_OFFSET\r
130         swi r25, r1, portR25_OFFSET\r
131         swi r24, r1, portR24_OFFSET\r
132         swi r23, r1, portR23_OFFSET\r
133         swi r22, r1, portR22_OFFSET\r
134         swi r21, r1, portR21_OFFSET\r
135         swi r20, r1, portR20_OFFSET\r
136         swi r19, r1, portR19_OFFSET\r
137         swi r18, r1, portR18_OFFSET\r
138         swi r17, r1, portR17_OFFSET\r
139         swi r16, r1, portR16_OFFSET\r
140         swi r15, r1, portR15_OFFSET\r
141         /* R14 is saved later as it needs adjustment if a yield is performed. */\r
142         swi r13, r1, portR13_OFFSET\r
143         swi r12, r1, portR12_OFFSET\r
144         swi r11, r1, portR11_OFFSET\r
145         swi r10, r1, portR10_OFFSET\r
146         swi r9, r1, portR9_OFFSET\r
147         swi r8, r1, portR8_OFFSET\r
148         swi r7, r1, portR7_OFFSET\r
149         swi r6, r1, portR6_OFFSET\r
150         swi r5, r1, portR5_OFFSET\r
151         swi r4, r1, portR4_OFFSET\r
152         swi r3, r1, portR3_OFFSET\r
153         swi r2, r1, portR2_OFFSET\r
154 \r
155         /* Stack the critical section nesting value. */\r
156         lwi r18, r0, uxCriticalNesting\r
157         swi r18, r1, portCRITICAL_NESTING_OFFSET\r
158 \r
159         /* Stack MSR. */\r
160         mfs r18, rmsr\r
161         swi r18, r1, portMSR_OFFSET\r
162 \r
163         #if XPAR_MICROBLAZE_0_USE_FPU == 1\r
164                 /* Stack FSR. */\r
165                 mfs r18, rfsr\r
166                 swi r18, r1, portFSR_OFFSET\r
167         #endif\r
168 \r
169         /* Save the top of stack value to the TCB. */\r
170         lwi r3, r0, pxCurrentTCB\r
171         sw      r1, r0, r3\r
172         \r
173         .endm\r
174 \r
175 .macro portRESTORE_CONTEXT\r
176 \r
177         /* Load the top of stack value from the TCB. */\r
178         lwi r18, r0, pxCurrentTCB\r
179         lw      r1, r0, r18\r
180 \r
181         /* Restore the general registers. */\r
182         lwi r31, r1, portR31_OFFSET\r
183         lwi r30, r1, portR30_OFFSET\r
184         lwi r29, r1, portR29_OFFSET\r
185         lwi r28, r1, portR28_OFFSET\r
186         lwi r27, r1, portR27_OFFSET\r
187         lwi r26, r1, portR26_OFFSET\r
188         lwi r25, r1, portR25_OFFSET\r
189         lwi r24, r1, portR24_OFFSET\r
190         lwi r23, r1, portR23_OFFSET\r
191         lwi r22, r1, portR22_OFFSET\r
192         lwi r21, r1, portR21_OFFSET\r
193         lwi r20, r1, portR20_OFFSET\r
194         lwi r19, r1, portR19_OFFSET\r
195         lwi r17, r1, portR17_OFFSET\r
196         lwi r16, r1, portR16_OFFSET\r
197         lwi r15, r1, portR15_OFFSET\r
198         lwi r14, r1, portR14_OFFSET\r
199         lwi r13, r1, portR13_OFFSET\r
200         lwi r12, r1, portR12_OFFSET\r
201         lwi r11, r1, portR11_OFFSET\r
202         lwi r10, r1, portR10_OFFSET\r
203         lwi r9, r1, portR9_OFFSET\r
204         lwi r8, r1, portR8_OFFSET\r
205         lwi r7, r1, portR7_OFFSET\r
206         lwi r6, r1, portR6_OFFSET\r
207         lwi r5, r1, portR5_OFFSET\r
208         lwi r4, r1, portR4_OFFSET\r
209         lwi r3, r1, portR3_OFFSET\r
210         lwi r2, r1, portR2_OFFSET\r
211 \r
212         /* Reload the rmsr from the stack. */\r
213         lwi r18, r1, portMSR_OFFSET\r
214         mts rmsr, r18\r
215 \r
216         #if XPAR_MICROBLAZE_0_USE_FPU == 1\r
217                 /* Reload the FSR from the stack. */\r
218                 lwi r18, r1, portFSR_OFFSET\r
219                 mts rfsr, r18\r
220         #endif\r
221 \r
222         /* Load the critical nesting value. */\r
223         lwi r18, r1, portCRITICAL_NESTING_OFFSET\r
224         swi r18, r0, uxCriticalNesting\r
225 \r
226         /* Test the critical nesting value.  If it is non zero then the task last\r
227         exited the running state using a yield.  If it is zero, then the task\r
228         last exited the running state through an interrupt. */\r
229         xori r18, r18, 0\r
230         bnei r18, exit_from_yield\r
231 \r
232         /* r18 was being used as a temporary.  Now restore its true value from the\r
233         stack. */\r
234         lwi r18, r1, portR18_OFFSET\r
235 \r
236         /* Remove the stack frame. */\r
237         addik r1, r1, portCONTEXT_SIZE\r
238 \r
239         /* Return using rtid so interrupts are re-enabled as this function is\r
240         exited. */\r
241         rtid r14, 0\r
242         or r0, r0, r0\r
243 \r
244         .endm\r
245 \r
246 /* This function is used to exit portRESTORE_CONTEXT() if the task being\r
247 returned to last left the Running state by calling taskYIELD() (rather than\r
248 being preempted by an interrupt. */\r
249         .text\r
250         .align  2\r
251 exit_from_yield:\r
252 \r
253         /* r18 was being used as a temporary.  Now restore its true value from the\r
254         stack. */\r
255         lwi r18, r1, portR18_OFFSET\r
256 \r
257         /* Remove the stack frame. */\r
258         addik r1, r1, portCONTEXT_SIZE\r
259 \r
260         /* Return to the task. */\r
261         rtsd r14, 0\r
262         or r0, r0, r0\r
263 \r
264 \r
265         .text\r
266         .align  2\r
267 _interrupt_handler:\r
268 \r
269         portSAVE_CONTEXT\r
270 \r
271         /* Stack the return address. */\r
272         swi r14, r1, portR14_OFFSET\r
273 \r
274         /* Switch to the ISR stack.  The pulISRStack value has already been set to\r
275         leave space for the caller function to write back into the stack of this\r
276         function. */\r
277         lwi r1, r0, pulISRStack\r
278 \r
279         /* The parameter to the interrupt handler. */\r
280         ori     r5, r0, configINTERRUPT_CONTROLLER_TO_USE\r
281 \r
282         /* Execute any pending interrupts. */\r
283         bralid r15, XIntc_DeviceInterruptHandler\r
284         or r0, r0, r0\r
285 \r
286         /* See if a new task should be selected to execute. */\r
287         lwi r18, r0, ulTaskSwitchRequested\r
288         or r18, r18, r0\r
289 \r
290         /* If ulTaskSwitchRequested is already zero, then jump straight to\r
291         restoring the task that is already in the Running state. */\r
292         beqi r18, task_switch_not_requested\r
293 \r
294         /* Set ulTaskSwitchRequested back to zero as a task switch is about to be\r
295         performed. */\r
296         swi r0, r0, ulTaskSwitchRequested\r
297 \r
298         /* ulTaskSwitchRequested was not 0 when tested.  Select the next task to\r
299         execute. */\r
300         bralid r15, vTaskSwitchContext\r
301         or r0, r0, r0\r
302 \r
303 task_switch_not_requested:\r
304 \r
305         /* Restore the context of the next task scheduled to execute. */\r
306         portRESTORE_CONTEXT\r
307 \r
308 \r
309         .text\r
310         .align  2\r
311 VPortYieldASM:\r
312 \r
313         portSAVE_CONTEXT\r
314 \r
315         /* Modify the return address so a return is done to the instruction after\r
316         the call to VPortYieldASM. */\r
317         addi r14, r14, 8\r
318         swi r14, r1, portR14_OFFSET\r
319 \r
320         /* Switch to use the ISR stack. */\r
321         lwi r1, r0, pulISRStack\r
322 \r
323         /* Select the next task to execute. */\r
324         bralid r15, vTaskSwitchContext\r
325         or r0, r0, r0\r
326 \r
327         /* Restore the context of the next task scheduled to execute. */\r
328         portRESTORE_CONTEXT\r
329 \r
330         .text\r
331         .align  2\r
332 vPortStartFirstTask:\r
333 \r
334         portRESTORE_CONTEXT\r
335         \r
336         \r
337 \r
338 \r
339 \r
340 \r