]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/GCC/IA32_flat/portASM.S
Update version numbers in preparation for new release.
[freertos] / FreeRTOS / Source / portable / GCC / IA32_flat / portASM.S
1 /*\r
2     FreeRTOS V8.2.2 - Copyright (C) 2015 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     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
12 \r
13     ***************************************************************************\r
14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
15     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
16     >>!   obliged to provide the source code for proprietary components     !<<\r
17     >>!   outside of the FreeRTOS kernel.                                   !<<\r
18     ***************************************************************************\r
19 \r
20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
23     link: http://www.freertos.org/a00114.html\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    FreeRTOS provides completely free yet professionally developed,    *\r
28      *    robust, strictly quality controlled, supported, and cross          *\r
29      *    platform software that is more than just the market leader, it     *\r
30      *    is the industry's de facto standard.                               *\r
31      *                                                                       *\r
32      *    Help yourself get started quickly while simultaneously helping     *\r
33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
34      *    tutorial book, reference manual, or both:                          *\r
35      *    http://www.FreeRTOS.org/Documentation                              *\r
36      *                                                                       *\r
37     ***************************************************************************\r
38 \r
39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
40     the FAQ page "My application does not run, what could be wrong?".  Have you\r
41     defined configASSERT()?\r
42 \r
43     http://www.FreeRTOS.org/support - In return for receiving this top quality\r
44     embedded software for free we request you assist our global community by\r
45     participating in the support forum.\r
46 \r
47     http://www.FreeRTOS.org/training - Investing in training allows your team to\r
48     be as productive as possible as early as possible.  Now you can receive\r
49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
50     Ltd, and the world's leading authority on the world's leading RTOS.\r
51 \r
52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
54     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
55 \r
56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
58 \r
59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
61     licenses offer ticketed support, indemnification and commercial middleware.\r
62 \r
63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
64     engineered and independently SIL3 certified version for use in safety and\r
65     mission critical applications that require provable dependability.\r
66 \r
67     1 tab == 4 spaces!\r
68 */\r
69 \r
70 .file "portASM.S"\r
71 #include "FreeRTOSConfig.h"\r
72 #include "ISR_Support.h"\r
73 \r
74         .extern pxCurrentTCB\r
75         .extern vTaskSwitchContext\r
76         .extern vPortCentralInterruptHandler\r
77         .extern xTaskIncrementTick\r
78         .extern vPortAPICErrorHandler\r
79         .extern pucPortTaskFPUContextBuffer\r
80         .extern ulPortYieldPending\r
81 \r
82         .global vPortStartFirstTask\r
83         .global vPortCentralInterruptWrapper\r
84         .global vPortAPICErrorHandlerWrapper\r
85         .global vPortTimerHandler\r
86         .global vPortYieldCall\r
87         .global vPortAPICSpuriousHandler\r
88 \r
89         .text\r
90 \r
91 /*-----------------------------------------------------------*/\r
92 \r
93 .align 4\r
94 .func vPortYieldCall\r
95 vPortYieldCall:\r
96         /* Save general purpose registers. */\r
97         pusha\r
98 \r
99         .if configSUPPORT_FPU == 1\r
100 \r
101                 /* If the task has a buffer allocated to save the FPU context then save\r
102                 the FPU context now. */\r
103                 movl    pucPortTaskFPUContextBuffer, %eax\r
104                 test    %eax, %eax\r
105                 je              1f\r
106                 fnsave  ( %eax )\r
107                 fwait\r
108 \r
109                 1:\r
110 \r
111                 /* Save the address of the FPU context, if any. */\r
112                 push    pucPortTaskFPUContextBuffer\r
113 \r
114         .endif /* configSUPPORT_FPU */\r
115 \r
116         /* Find the TCB. */\r
117         movl    pxCurrentTCB, %eax\r
118 \r
119         /* Stack location is first item in the TCB. */\r
120         movl    %esp, (%eax)\r
121 \r
122         call vTaskSwitchContext\r
123 \r
124         /* Find the location of pxCurrentTCB again - a callee saved register could\r
125         be used in place of eax to prevent this second load, but that then relies\r
126         on the compiler and other asm code. */\r
127         movl    pxCurrentTCB, %eax\r
128         movl    (%eax), %esp\r
129 \r
130         .if configSUPPORT_FPU == 1\r
131 \r
132                 /* Restore address of task's FPU context buffer. */\r
133                 pop     pucPortTaskFPUContextBuffer\r
134 \r
135                 /* If the task has a buffer allocated in which its FPU context is saved,\r
136                 then restore it now. */\r
137                 movl    pucPortTaskFPUContextBuffer, %eax\r
138                 test    %eax, %eax\r
139                 je              1f\r
140                 frstor  ( %eax )\r
141                 1:\r
142         .endif\r
143 \r
144         popa\r
145         iret\r
146 \r
147 .endfunc\r
148 /*-----------------------------------------------------------*/\r
149 \r
150 .align 4\r
151 .func vPortStartFirstTask\r
152 vPortStartFirstTask:\r
153 \r
154         /* Find the TCB. */\r
155         movl    pxCurrentTCB, %eax\r
156 \r
157         /* Stack location is first item in the TCB. */\r
158         movl    (%eax), %esp\r
159 \r
160         /* Restore FPU context flag. */\r
161         .if configSUPPORT_FPU == 1\r
162 \r
163                 pop     pucPortTaskFPUContextBuffer\r
164 \r
165         .endif /* configSUPPORT_FPU */\r
166 \r
167         /* Restore general purpose registers. */\r
168         popa\r
169         iret\r
170 .endfunc\r
171 /*-----------------------------------------------------------*/\r
172 \r
173 .align 4\r
174 .func vPortAPICErrorHandlerWrapper\r
175 vPortAPICErrorHandlerWrapper:\r
176         pusha\r
177         call    vPortAPICErrorHandler\r
178         popa\r
179         /* EOI. */\r
180         movl    $0x00, (0xFEE000B0)\r
181         iret\r
182 .endfunc\r
183 /*-----------------------------------------------------------*/\r
184 \r
185 .align 4\r
186 .func vPortTimerHandler\r
187 vPortTimerHandler:\r
188 \r
189         /* Save general purpose registers. */\r
190         pusha\r
191 \r
192         /* Interrupts are not nested, so save the rest of the task context. */\r
193         .if configSUPPORT_FPU == 1\r
194 \r
195                 /* If the task has a buffer allocated to save the FPU context then save the\r
196                 FPU context now. */\r
197                 movl    pucPortTaskFPUContextBuffer, %eax\r
198                 test    %eax, %eax\r
199                 je              1f\r
200                 fnsave  ( %eax ) /* Save FLOP context into ucTempFPUBuffer array. */\r
201                 fwait\r
202 \r
203                 1:\r
204                 /* Save the address of the FPU context, if any. */\r
205                 push    pucPortTaskFPUContextBuffer\r
206 \r
207         .endif /* configSUPPORT_FPU */\r
208 \r
209         /* Find the TCB. */\r
210         movl    pxCurrentTCB, %eax\r
211 \r
212         /* Stack location is first item in the TCB. */\r
213         movl    %esp, (%eax)\r
214 \r
215         /* Switch stacks. */\r
216         movl    ulTopOfSystemStack, %esp\r
217         movl    %esp, %ebp\r
218 \r
219         /* Increment nesting count. */\r
220         add     $1, ulInterruptNesting\r
221 \r
222         call    xTaskIncrementTick\r
223 \r
224         sti\r
225 \r
226         /* Is a switch to another task required? */\r
227         test    %eax, %eax\r
228         je              _skip_context_switch\r
229         cli\r
230         call    vTaskSwitchContext\r
231 \r
232 _skip_context_switch:\r
233         cli\r
234 \r
235         /* Decrement the variable used to determine if a switch to a system\r
236         stack is necessary. */\r
237         sub             $1, ulInterruptNesting\r
238 \r
239         /* Stack location is first item in the TCB. */\r
240         movl    pxCurrentTCB, %eax\r
241         movl    (%eax), %esp\r
242 \r
243         .if configSUPPORT_FPU == 1\r
244 \r
245                 /* Restore address of task's FPU context buffer. */\r
246                 pop     pucPortTaskFPUContextBuffer\r
247 \r
248                 /* If the task has a buffer allocated in which its FPU context is saved,\r
249                 then restore it now. */\r
250                 movl    pucPortTaskFPUContextBuffer, %eax\r
251                 test    %eax, %eax\r
252                 je              1f\r
253                 frstor  ( %eax )\r
254                 1:\r
255         .endif\r
256 \r
257         popa\r
258 \r
259         /* EOI. */\r
260         movl    $0x00, (0xFEE000B0)\r
261         iret\r
262 \r
263 .endfunc\r
264 /*-----------------------------------------------------------*/\r
265 \r
266 .if configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1\r
267 \r
268         .align 4\r
269         .func vPortCentralInterruptWrapper\r
270         vPortCentralInterruptWrapper:\r
271 \r
272                 portFREERTOS_INTERRUPT_ENTRY\r
273 \r
274                 movl $0xFEE00170, %eax                  /* Highest In Service Register (ISR) long word. */\r
275                 movl $8, %ecx                                   /* Loop counter. */\r
276 \r
277         next_isr_long_word:\r
278                 test %ecx, %ecx                                 /* Loop counter reached 0? */\r
279                 je wrapper_epilogue                             /* Looked at all ISR registers without finding a bit set. */\r
280                 sub $1, %ecx                                    /* Sub 1 from loop counter. */\r
281                 movl (%eax), %ebx                               /* Load next ISR long word. */\r
282                 sub $0x10, %eax                                 /* Point to next ISR long word in case no bits are set in the current long word. */\r
283                 test %ebx, %ebx                                 /* Are there any bits set? */\r
284                 je next_isr_long_word                   /* Look at next ISR long word if no bits were set. */\r
285                 sti\r
286                 bsr %ebx, %ebx                                  /* A bit was set, which one? */\r
287                 movl $32, %eax                                  /* Destination operand for following multiplication. */\r
288                 mul %ecx                                                /* Calculate base vector for current register, 32 vectors per register. */\r
289                 add %ebx, %eax                                  /* Add bit offset into register to get final vector number. */\r
290                 push %eax                                               /* Vector number is function parameter. */\r
291                 call vPortCentralInterruptHandler\r
292                 pop %eax                                                /* Remove parameter. */\r
293 \r
294         wrapper_epilogue:\r
295                 portFREERTOS_INTERRUPT_EXIT\r
296 \r
297         .endfunc\r
298 \r
299 .endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */\r
300 /*-----------------------------------------------------------*/\r
301 \r
302 .align 4\r
303 .func vPortAPISpuriousHandler\r
304 vPortAPICSpuriousHandler:\r
305         iret\r
306 \r
307 .endfunc\r
308 \r
309 .end\r
310 \r
311 \r
312 \r
313 \r
314 \r
315 \r
316 \r