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