]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/ThirdParty/GCC/Wiced_CY/portASM.S
Remove the FreeRTOS-IoT-Libraries from FreeRTOS-Plus as it was an old copy with a...
[freertos] / FreeRTOS / Source / portable / ThirdParty / GCC / Wiced_CY / portASM.S
1 /*\r
2  * FreeRTOS Kernel V10.2.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.\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         .text\r
29         .arm\r
30 \r
31         .set SYS_MODE,  0x1f\r
32         .set SVC_MODE,  0x13\r
33         .set IRQ_MODE,  0x12\r
34 \r
35         /* Variables and functions. */\r
36         .extern ulMaxAPIPriorityMask\r
37         .extern _freertos_vector_table\r
38         .extern pxCurrentTCB\r
39         .extern vTaskSwitchContext\r
40         .extern vApplicationIRQHandler\r
41         .extern ulPortInterruptNesting\r
42         .extern ulPortTaskHasFPUContext\r
43         .extern ulICCEOIR\r
44         .extern ulPortYieldRequired\r
45 \r
46         .global FreeRTOS_IRQ_Handler\r
47         .global FreeRTOS_SVC_Handler\r
48         .global vPortRestoreTaskContext\r
49 \r
50 \r
51 .macro portSAVE_CONTEXT\r
52 \r
53         /* Save the LR and SPSR onto the system mode stack before switching to\r
54         system mode to save the remaining system mode registers. */\r
55         SRSDB   sp!, #SYS_MODE\r
56         CPS             #SYS_MODE\r
57         PUSH    {R0-R12, R14}\r
58 \r
59         /* Push the critical nesting count. */\r
60         LDR             R2, ulCriticalNestingConst\r
61         LDR             R1, [R2]\r
62         PUSH    {R1}\r
63 \r
64         /* Does the task have a floating point context that needs saving?  If\r
65         ulPortTaskHasFPUContext is 0 then no. */\r
66         LDR             R2, ulPortTaskHasFPUContextConst\r
67         LDR             R3, [R2]\r
68         CMP             R3, #0\r
69 \r
70 #if configFPU == 1\r
71         /* Save the floating point context, if any. */\r
72         FMRXNE  R1,  FPSCR\r
73         VPUSHNE {D0-D15}\r
74 #if configFPU_D32 == 1\r
75         VPUSHNE {D16-D31}\r
76 #endif /* configFPU_D32 */\r
77         PUSHNE  {R1}\r
78 #endif\r
79 \r
80         /* Save ulPortTaskHasFPUContext itself. */\r
81         PUSH    {R3}\r
82 \r
83         /* Save the stack pointer in the TCB. */\r
84         LDR             R0, pxCurrentTCBConst\r
85         LDR             R1, [R0]\r
86         STR             SP, [R1]\r
87 \r
88         .endm\r
89 \r
90 ; /**********************************************************************/\r
91 \r
92 .macro portRESTORE_CONTEXT\r
93 \r
94         /* Set the SP to point to the stack of the task being restored. */\r
95         LDR             R0, pxCurrentTCBConst\r
96         LDR             R1, [R0]\r
97         LDR             SP, [R1]\r
98 \r
99         /* Is there a floating point context to restore?  If the restored\r
100         ulPortTaskHasFPUContext is zero then no. */\r
101         LDR             R0, ulPortTaskHasFPUContextConst\r
102         POP             {R1}\r
103         STR             R1, [R0]\r
104         CMP             R1, #0\r
105 \r
106 #if configFPU == 1\r
107         /* Restore the floating point context, if any. */\r
108         POPNE   {R0}\r
109 #if configFPU_D32 == 1\r
110         VPOPNE  {D16-D31}\r
111 #endif /* configFPU_D32 */\r
112         VPOPNE  {D0-D15}\r
113         VMSRNE  FPSCR, R0\r
114 #endif\r
115 \r
116         /* Restore the critical section nesting depth. */\r
117         LDR             R0, ulCriticalNestingConst\r
118         POP             {R1}\r
119         STR             R1, [R0]\r
120 \r
121         /* Restore all system mode registers other than the SP (which is already\r
122         being used). */\r
123         POP             {R0-R12, R14}\r
124 \r
125         /* Return to the task code, loading CPSR on the way. */\r
126         RFEIA   sp!\r
127 \r
128         .endm\r
129 \r
130 \r
131 \r
132 \r
133 /******************************************************************************\r
134  * SVC handler is used to yield.\r
135  *****************************************************************************/\r
136 .align 4\r
137 .type FreeRTOS_SVC_Handler, %function\r
138 FreeRTOS_SVC_Handler:\r
139         /* Save the context of the current task and select a new task to run. */\r
140         portSAVE_CONTEXT\r
141         LDR R0, vTaskSwitchContextConst\r
142         BLX     R0\r
143         portRESTORE_CONTEXT\r
144 \r
145 \r
146 /******************************************************************************\r
147  * vPortRestoreTaskContext is used to start the scheduler.\r
148  *****************************************************************************/\r
149 .align 4\r
150 .type vPortRestoreTaskContext, %function\r
151 vPortRestoreTaskContext:\r
152         /* Switch to system mode. */\r
153         CPS             #SYS_MODE\r
154         portRESTORE_CONTEXT\r
155 \r
156 .align 4\r
157 .type FreeRTOS_IRQ_Handler, %function\r
158 FreeRTOS_IRQ_Handler:\r
159         /* Return to the interrupted instruction. */\r
160         SUB             lr, lr, #4\r
161 \r
162         /* Push the return address and SPSR. */\r
163         PUSH    {lr}\r
164         MRS             lr, SPSR\r
165         PUSH    {lr}\r
166 \r
167         /* Change to supervisor mode to allow reentry. */\r
168         CPS             #0x13\r
169 \r
170         /* Push used registers. */\r
171         PUSH    {r0-r3, r12}\r
172 \r
173         /* Increment nesting count.  r3 holds the address of ulPortInterruptNesting\r
174         for future use.  r1 holds the original ulPortInterruptNesting value for\r
175         future use. */\r
176         LDR             r3, ulPortInterruptNestingConst\r
177         LDR             r1, [r3]\r
178         ADD             r0, r1, #1\r
179         STR             r0, [r3]\r
180 \r
181         /* Ensure bit 2 of the stack pointer is clear.  r2 holds the bit 2 value for\r
182         future use. */\r
183         MOV             r0, sp\r
184         AND             r2, r0, #4\r
185         SUB             sp, sp, r2\r
186 \r
187         /* Call the interrupt handler. */\r
188         PUSH    {r0-r3, lr}\r
189         LDR             r1, vApplicationIRQHandlerConst\r
190         BLX             r1\r
191         POP             {r0-r3, lr}\r
192         ADD             sp, sp, r2\r
193 \r
194         CPSID   i\r
195         DSB\r
196         ISB\r
197 \r
198         /* Write to the EOI register. */\r
199         LDR     r0, ulICCEOIRConst\r
200         LDR             r2, [r0]\r
201         STR             r0, [r2]\r
202 \r
203         /* Restore the old nesting count. */\r
204         STR             r1, [r3]\r
205 \r
206         /* A context switch is never performed if the nesting count is not 0. */\r
207         CMP             r1, #0\r
208         BNE             exit_without_switch\r
209 \r
210         /* Did the interrupt request a context switch?  r1 holds the address of\r
211         ulPortYieldRequired and r0 the value of ulPortYieldRequired for future\r
212         use. */\r
213         LDR             r1, ulPortYieldRequiredConst\r
214         LDR             r0, [r1]\r
215         CMP             r0, #0\r
216         BNE             switch_before_exit\r
217 \r
218 exit_without_switch:\r
219         /* No context switch.  Restore used registers, LR_irq and SPSR before\r
220         returning. */\r
221         POP             {r0-r3, r12}\r
222         CPS             #IRQ_MODE\r
223         POP             {LR}\r
224         MSR             SPSR_cxsf, LR\r
225         POP             {LR}\r
226         MOVS    PC, LR\r
227 \r
228 switch_before_exit:\r
229         /* A context swtich is to be performed.  Clear the context switch pending\r
230         flag. */\r
231         MOV             r0, #0\r
232         STR             r0, [r1]\r
233 \r
234         /* Restore used registers, LR-irq and SPSR before saving the context\r
235         to the task stack. */\r
236         POP             {r0-r3, r12}\r
237         CPS             #IRQ_MODE\r
238         POP             {LR}\r
239         MSR             SPSR_cxsf, LR\r
240         POP             {LR}\r
241         portSAVE_CONTEXT\r
242 \r
243         /* Call the function that selects the new task to execute.\r
244         vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD\r
245         instructions, or 8 byte aligned stack allocated data.  LR does not need\r
246         saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */\r
247         LDR             R0, vTaskSwitchContextConst\r
248         BLX             R0\r
249 \r
250         /* Restore the context of, and branch to, the task selected to execute\r
251         next. */\r
252         portRESTORE_CONTEXT\r
253 \r
254 ulICCEOIRConst: .word ulICCEOIR\r
255 pxCurrentTCBConst: .word pxCurrentTCB\r
256 ulCriticalNestingConst: .word ulCriticalNesting\r
257 ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext\r
258 vTaskSwitchContextConst: .word vTaskSwitchContext\r
259 vApplicationIRQHandlerConst: .word vApplicationIRQHandler\r
260 ulPortInterruptNestingConst: .word ulPortInterruptNesting\r
261 ulPortYieldRequiredConst: .word ulPortYieldRequired\r
262 \r
263 .end\r
264 \r
265 \r
266 \r
267 \r
268 \r