]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/GCC/MicroBlazeV8/portasm.S
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Source / portable / GCC / MicroBlazeV8 / portasm.S
1 /*\r
2  * FreeRTOS Kernel V10.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 \r
29 /* FreeRTOS includes. */\r
30 #include "FreeRTOSConfig.h"\r
31 \r
32 /* Xilinx library includes. */\r
33 #include "microblaze_exceptions_g.h"\r
34 #include "xparameters.h"\r
35 \r
36 /* The context is oversized to allow functions called from the ISR to write\r
37 back into the caller stack. */\r
38 #if( XPAR_MICROBLAZE_USE_FPU != 0 )\r
39         #define portCONTEXT_SIZE 136\r
40         #define portMINUS_CONTEXT_SIZE -136\r
41 #else\r
42         #define portCONTEXT_SIZE 132\r
43         #define portMINUS_CONTEXT_SIZE -132\r
44 #endif\r
45 \r
46 /* Offsets from the stack pointer at which saved registers are placed. */\r
47 #define portR31_OFFSET  4\r
48 #define portR30_OFFSET  8\r
49 #define portR29_OFFSET  12\r
50 #define portR28_OFFSET  16\r
51 #define portR27_OFFSET  20\r
52 #define portR26_OFFSET  24\r
53 #define portR25_OFFSET  28\r
54 #define portR24_OFFSET  32\r
55 #define portR23_OFFSET  36\r
56 #define portR22_OFFSET  40\r
57 #define portR21_OFFSET  44\r
58 #define portR20_OFFSET  48\r
59 #define portR19_OFFSET  52\r
60 #define portR18_OFFSET  56\r
61 #define portR17_OFFSET  60\r
62 #define portR16_OFFSET  64\r
63 #define portR15_OFFSET  68\r
64 #define portR14_OFFSET  72\r
65 #define portR13_OFFSET  76\r
66 #define portR12_OFFSET  80\r
67 #define portR11_OFFSET  84\r
68 #define portR10_OFFSET  88\r
69 #define portR9_OFFSET   92\r
70 #define portR8_OFFSET   96\r
71 #define portR7_OFFSET   100\r
72 #define portR6_OFFSET   104\r
73 #define portR5_OFFSET   108\r
74 #define portR4_OFFSET   112\r
75 #define portR3_OFFSET   116\r
76 #define portR2_OFFSET   120\r
77 #define portCRITICAL_NESTING_OFFSET 124\r
78 #define portMSR_OFFSET 128\r
79 #define portFSR_OFFSET 132\r
80 \r
81         .extern pxCurrentTCB\r
82         .extern XIntc_DeviceInterruptHandler\r
83         .extern vTaskSwitchContext\r
84         .extern uxCriticalNesting\r
85         .extern pulISRStack\r
86         .extern ulTaskSwitchRequested\r
87         .extern vPortExceptionHandler\r
88         .extern pulStackPointerOnFunctionEntry\r
89 \r
90         .global _interrupt_handler\r
91         .global VPortYieldASM\r
92         .global vPortStartFirstTask\r
93         .global vPortExceptionHandlerEntry\r
94 \r
95 \r
96 .macro portSAVE_CONTEXT\r
97 \r
98         /* Make room for the context on the stack. */\r
99         addik r1, r1, portMINUS_CONTEXT_SIZE\r
100 \r
101         /* Stack general registers. */\r
102         swi r31, r1, portR31_OFFSET\r
103         swi r30, r1, portR30_OFFSET\r
104         swi r29, r1, portR29_OFFSET\r
105         swi r28, r1, portR28_OFFSET\r
106         swi r27, r1, portR27_OFFSET\r
107         swi r26, r1, portR26_OFFSET\r
108         swi r25, r1, portR25_OFFSET\r
109         swi r24, r1, portR24_OFFSET\r
110         swi r23, r1, portR23_OFFSET\r
111         swi r22, r1, portR22_OFFSET\r
112         swi r21, r1, portR21_OFFSET\r
113         swi r20, r1, portR20_OFFSET\r
114         swi r19, r1, portR19_OFFSET\r
115         swi r18, r1, portR18_OFFSET\r
116         swi r17, r1, portR17_OFFSET\r
117         swi r16, r1, portR16_OFFSET\r
118         swi r15, r1, portR15_OFFSET\r
119         /* R14 is saved later as it needs adjustment if a yield is performed. */\r
120         swi r13, r1, portR13_OFFSET\r
121         swi r12, r1, portR12_OFFSET\r
122         swi r11, r1, portR11_OFFSET\r
123         swi r10, r1, portR10_OFFSET\r
124         swi r9, r1, portR9_OFFSET\r
125         swi r8, r1, portR8_OFFSET\r
126         swi r7, r1, portR7_OFFSET\r
127         swi r6, r1, portR6_OFFSET\r
128         swi r5, r1, portR5_OFFSET\r
129         swi r4, r1, portR4_OFFSET\r
130         swi r3, r1, portR3_OFFSET\r
131         swi r2, r1, portR2_OFFSET\r
132 \r
133         /* Stack the critical section nesting value. */\r
134         lwi r18, r0, uxCriticalNesting\r
135         swi r18, r1, portCRITICAL_NESTING_OFFSET\r
136 \r
137         /* Stack MSR. */\r
138         mfs r18, rmsr\r
139         swi r18, r1, portMSR_OFFSET\r
140 \r
141         #if( XPAR_MICROBLAZE_USE_FPU != 0 )\r
142                 /* Stack FSR. */\r
143                 mfs r18, rfsr\r
144                 swi r18, r1, portFSR_OFFSET\r
145         #endif\r
146 \r
147         /* Save the top of stack value to the TCB. */\r
148         lwi r3, r0, pxCurrentTCB\r
149         sw      r1, r0, r3\r
150 \r
151         .endm\r
152 \r
153 .macro portRESTORE_CONTEXT\r
154 \r
155         /* Load the top of stack value from the TCB. */\r
156         lwi r18, r0, pxCurrentTCB\r
157         lw      r1, r0, r18\r
158 \r
159         /* Restore the general registers. */\r
160         lwi r31, r1, portR31_OFFSET\r
161         lwi r30, r1, portR30_OFFSET\r
162         lwi r29, r1, portR29_OFFSET\r
163         lwi r28, r1, portR28_OFFSET\r
164         lwi r27, r1, portR27_OFFSET\r
165         lwi r26, r1, portR26_OFFSET\r
166         lwi r25, r1, portR25_OFFSET\r
167         lwi r24, r1, portR24_OFFSET\r
168         lwi r23, r1, portR23_OFFSET\r
169         lwi r22, r1, portR22_OFFSET\r
170         lwi r21, r1, portR21_OFFSET\r
171         lwi r20, r1, portR20_OFFSET\r
172         lwi r19, r1, portR19_OFFSET\r
173         lwi r17, r1, portR17_OFFSET\r
174         lwi r16, r1, portR16_OFFSET\r
175         lwi r15, r1, portR15_OFFSET\r
176         lwi r14, r1, portR14_OFFSET\r
177         lwi r13, r1, portR13_OFFSET\r
178         lwi r12, r1, portR12_OFFSET\r
179         lwi r11, r1, portR11_OFFSET\r
180         lwi r10, r1, portR10_OFFSET\r
181         lwi r9, r1, portR9_OFFSET\r
182         lwi r8, r1, portR8_OFFSET\r
183         lwi r7, r1, portR7_OFFSET\r
184         lwi r6, r1, portR6_OFFSET\r
185         lwi r5, r1, portR5_OFFSET\r
186         lwi r4, r1, portR4_OFFSET\r
187         lwi r3, r1, portR3_OFFSET\r
188         lwi r2, r1, portR2_OFFSET\r
189 \r
190         /* Reload the rmsr from the stack. */\r
191         lwi r18, r1, portMSR_OFFSET\r
192         mts rmsr, r18\r
193 \r
194         #if( XPAR_MICROBLAZE_USE_FPU != 0 )\r
195                 /* Reload the FSR from the stack. */\r
196                 lwi r18, r1, portFSR_OFFSET\r
197                 mts rfsr, r18\r
198         #endif\r
199 \r
200         /* Load the critical nesting value. */\r
201         lwi r18, r1, portCRITICAL_NESTING_OFFSET\r
202         swi r18, r0, uxCriticalNesting\r
203 \r
204         /* Test the critical nesting value.  If it is non zero then the task last\r
205         exited the running state using a yield.  If it is zero, then the task\r
206         last exited the running state through an interrupt. */\r
207         xori r18, r18, 0\r
208         bnei r18, exit_from_yield\r
209 \r
210         /* r18 was being used as a temporary.  Now restore its true value from the\r
211         stack. */\r
212         lwi r18, r1, portR18_OFFSET\r
213 \r
214         /* Remove the stack frame. */\r
215         addik r1, r1, portCONTEXT_SIZE\r
216 \r
217         /* Return using rtid so interrupts are re-enabled as this function is\r
218         exited. */\r
219         rtid r14, 0\r
220         or r0, r0, r0\r
221 \r
222         .endm\r
223 \r
224 /* This function is used to exit portRESTORE_CONTEXT() if the task being\r
225 returned to last left the Running state by calling taskYIELD() (rather than\r
226 being preempted by an interrupt). */\r
227         .text\r
228         .align  4\r
229 exit_from_yield:\r
230 \r
231         /* r18 was being used as a temporary.  Now restore its true value from the\r
232         stack. */\r
233         lwi r18, r1, portR18_OFFSET\r
234 \r
235         /* Remove the stack frame. */\r
236         addik r1, r1, portCONTEXT_SIZE\r
237 \r
238         /* Return to the task. */\r
239         rtsd r14, 0\r
240         or r0, r0, r0\r
241 \r
242 \r
243         .text\r
244         .align  4\r
245 _interrupt_handler:\r
246 \r
247         portSAVE_CONTEXT\r
248 \r
249         /* Stack the return address. */\r
250         swi r14, r1, portR14_OFFSET\r
251 \r
252         /* Switch to the ISR stack. */\r
253         lwi r1, r0, pulISRStack\r
254 \r
255         /* The parameter to the interrupt handler. */\r
256         ori r5, r0, configINTERRUPT_CONTROLLER_TO_USE\r
257 \r
258         /* Execute any pending interrupts. */\r
259         bralid r15, XIntc_DeviceInterruptHandler\r
260         or r0, r0, r0\r
261 \r
262         /* See if a new task should be selected to execute. */\r
263         lwi r18, r0, ulTaskSwitchRequested\r
264         or r18, r18, r0\r
265 \r
266         /* If ulTaskSwitchRequested is already zero, then jump straight to\r
267         restoring the task that is already in the Running state. */\r
268         beqi r18, task_switch_not_requested\r
269 \r
270         /* Set ulTaskSwitchRequested back to zero as a task switch is about to be\r
271         performed. */\r
272         swi r0, r0, ulTaskSwitchRequested\r
273 \r
274         /* ulTaskSwitchRequested was not 0 when tested.  Select the next task to\r
275         execute. */\r
276         bralid r15, vTaskSwitchContext\r
277         or r0, r0, r0\r
278 \r
279 task_switch_not_requested:\r
280 \r
281         /* Restore the context of the next task scheduled to execute. */\r
282         portRESTORE_CONTEXT\r
283 \r
284 \r
285         .text\r
286         .align  4\r
287 VPortYieldASM:\r
288 \r
289         portSAVE_CONTEXT\r
290 \r
291         /* Modify the return address so a return is done to the instruction after\r
292         the call to VPortYieldASM. */\r
293         addi r14, r14, 8\r
294         swi r14, r1, portR14_OFFSET\r
295 \r
296         /* Switch to use the ISR stack. */\r
297         lwi r1, r0, pulISRStack\r
298 \r
299         /* Select the next task to execute. */\r
300         bralid r15, vTaskSwitchContext\r
301         or r0, r0, r0\r
302 \r
303         /* Restore the context of the next task scheduled to execute. */\r
304         portRESTORE_CONTEXT\r
305 \r
306         .text\r
307         .align  4\r
308 vPortStartFirstTask:\r
309 \r
310         portRESTORE_CONTEXT\r
311 \r
312 \r
313 \r
314 #if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )\r
315 \r
316         .text\r
317         .align 4\r
318 vPortExceptionHandlerEntry:\r
319 \r
320         /* Take a copy of the stack pointer before vPortExecptionHandler is called,\r
321         storing its value prior to the function stack frame being created. */\r
322         swi r1, r0, pulStackPointerOnFunctionEntry\r
323         bralid r15, vPortExceptionHandler\r
324         or r0, r0, r0\r
325 \r
326 #endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */\r
327 \r
328 \r
329 \r