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