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