]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/IAR/ARM_CRx_No_GIC/portASM.s
Update MSP432 projects to use updated driver library files.
[freertos] / FreeRTOS / Source / portable / IAR / ARM_CRx_No_GIC / portASM.s
1 /*\r
2     FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5 \r
6     ***************************************************************************\r
7      *                                                                       *\r
8      *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
9      *    Complete, revised, and edited pdf reference manuals are also       *\r
10      *    available.                                                         *\r
11      *                                                                       *\r
12      *    Purchasing FreeRTOS documentation will not only help you, by       *\r
13      *    ensuring you get running as quickly as possible and with an        *\r
14      *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
15      *    the FreeRTOS project to continue with its mission of providing     *\r
16      *    professional grade, cross platform, de facto standard solutions    *\r
17      *    for microcontrollers - completely free of charge!                  *\r
18      *                                                                       *\r
19      *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
20      *                                                                       *\r
21      *    Thank you for using FreeRTOS, and thank you for your support!      *\r
22      *                                                                       *\r
23     ***************************************************************************\r
24 \r
25 \r
26     This file is part of the FreeRTOS distribution.\r
27 \r
28     FreeRTOS is free software; you can redistribute it and/or modify it under\r
29     the terms of the GNU General Public License (version 2) as published by the\r
30     Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
31     >>>NOTE<<< The modification to the GPL is included to allow you to\r
32     distribute a combined work that includes FreeRTOS without being obliged to\r
33     provide the source code for proprietary components outside of the FreeRTOS\r
34     kernel.  FreeRTOS is distributed in the hope that it will be useful, but\r
35     WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
36     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
37     more details. You should have received a copy of the GNU General Public\r
38     License and the FreeRTOS license exception along with FreeRTOS; if not it\r
39     can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
40     by writing to Richard Barry, contact details for whom are available on the\r
41     FreeRTOS WEB site.\r
42 \r
43     1 tab == 4 spaces!\r
44 \r
45     http://www.FreeRTOS.org - Documentation, latest information, license and\r
46     contact details.\r
47 \r
48     http://www.SafeRTOS.com - A version that is certified for use in safety\r
49     critical systems.\r
50 \r
51     http://www.OpenRTOS.com - Commercial support, development, porting,\r
52     licensing and training services.\r
53 */\r
54 \r
55 #include "FreeRTOSConfig.h"\r
56 \r
57         SECTION .text:CODE:ROOT(2)\r
58         arm\r
59 \r
60         /* Variables and functions. */\r
61         EXTERN pxCurrentTCB\r
62         EXTERN vTaskSwitchContext\r
63         EXTERN vApplicationIRQHandler\r
64         EXTERN ulPortInterruptNesting\r
65         EXTERN ulPortTaskHasFPUContext\r
66         EXTERN ulPortYieldRequired\r
67         EXTERN ulCriticalNesting\r
68 \r
69         PUBLIC FreeRTOS_IRQ_Handler\r
70         PUBLIC FreeRTOS_SVC_Handler\r
71         PUBLIC vPortRestoreTaskContext\r
72 \r
73 SYS_MODE                        EQU             0x1f\r
74 SVC_MODE                        EQU             0x13\r
75 IRQ_MODE                        EQU             0x12\r
76 \r
77 portSAVE_CONTEXT MACRO\r
78 \r
79         /* Save the LR and SPSR onto the system mode stack before switching to\r
80         system mode to save the remaining system mode registers. */\r
81         SRSDB   sp!, #SYS_MODE\r
82         CPS             #SYS_MODE\r
83         PUSH    {R0-R12, R14}\r
84 \r
85         /* Push the critical nesting count. */\r
86         LDR             R2, =ulCriticalNesting\r
87         LDR             R1, [R2]\r
88         PUSH    {R1}\r
89 \r
90         /* Does the task have a floating point context that needs saving?  If\r
91         ulPortTaskHasFPUContext is 0 then no. */\r
92         LDR             R2, =ulPortTaskHasFPUContext\r
93         LDR             R3, [R2]\r
94         CMP             R3, #0\r
95 \r
96         /* Save the floating point context, if any. */\r
97         FMRXNE  R1,  FPSCR\r
98         VPUSHNE {D0-D15}\r
99 #if configFPU_D32 == 1\r
100         VPUSHNE {D16-D31}\r
101 #endif /* configFPU_D32 */\r
102         PUSHNE  {R1}\r
103 \r
104         /* Save ulPortTaskHasFPUContext itself. */\r
105         PUSH    {R3}\r
106 \r
107         /* Save the stack pointer in the TCB. */\r
108         LDR             R0, =pxCurrentTCB\r
109         LDR             R1, [R0]\r
110         STR             SP, [R1]\r
111 \r
112         ENDM\r
113 \r
114 ; /**********************************************************************/\r
115 \r
116 portRESTORE_CONTEXT MACRO\r
117 \r
118         /* Set the SP to point to the stack of the task being restored. */\r
119         LDR             R0, =pxCurrentTCB\r
120         LDR             R1, [R0]\r
121         LDR             SP, [R1]\r
122 \r
123         /* Is there a floating point context to restore?  If the restored\r
124         ulPortTaskHasFPUContext is zero then no. */\r
125         LDR             R0, =ulPortTaskHasFPUContext\r
126         POP             {R1}\r
127         STR             R1, [R0]\r
128         CMP             R1, #0\r
129 \r
130         /* Restore the floating point context, if any. */\r
131         POPNE   {R0}\r
132 #if configFPU_D32 == 1\r
133         VPOPNE  {D16-D31}\r
134 #endif /* configFPU_D32 */\r
135         VPOPNE  {D0-D15}\r
136         VMSRNE  FPSCR, R0\r
137 \r
138         /* Restore the critical section nesting depth. */\r
139         LDR             R0, =ulCriticalNesting\r
140         POP             {R1}\r
141         STR             R1, [R0]\r
142 \r
143         /* Restore all system mode registers other than the SP (which is already\r
144         being used). */\r
145         POP             {R0-R12, R14}\r
146 \r
147         /* Return to the task code, loading CPSR on the way. */\r
148         RFEIA   sp!\r
149 \r
150         ENDM\r
151 \r
152 \r
153 \r
154 \r
155 /******************************************************************************\r
156  * SVC handler is used to yield.\r
157  *****************************************************************************/\r
158 FreeRTOS_SVC_Handler:\r
159         /* Save the context of the current task and select a new task to run. */\r
160         portSAVE_CONTEXT\r
161         LDR R0, =vTaskSwitchContext\r
162         BLX     R0\r
163         portRESTORE_CONTEXT\r
164 \r
165 \r
166 /******************************************************************************\r
167  * vPortRestoreTaskContext is used to start the scheduler.\r
168  *****************************************************************************/\r
169 vPortRestoreTaskContext:\r
170         /* Switch to system mode. */\r
171         CPS             #SYS_MODE\r
172         portRESTORE_CONTEXT\r
173 \r
174 FreeRTOS_IRQ_Handler:\r
175         /* Return to the interrupted instruction. */\r
176         SUB             lr, lr, #4\r
177 \r
178         /* Push the return address and SPSR. */\r
179         PUSH    {lr}\r
180         MRS             lr, SPSR\r
181         PUSH    {lr}\r
182 \r
183         /* Change to supervisor mode to allow reentry. */\r
184         CPS             #SVC_MODE\r
185 \r
186         /* Push used registers. */\r
187         PUSH    {r0-r3, r12}\r
188 \r
189         /* Increment nesting count.  r3 holds the address of ulPortInterruptNesting\r
190         for future use.  r1 holds the original ulPortInterruptNesting value for\r
191         future use. */\r
192         LDR             r3, =ulPortInterruptNesting\r
193         LDR             r1, [r3]\r
194         ADD             r0, r1, #1\r
195         STR             r0, [r3]\r
196 \r
197         /* Ensure bit 2 of the stack pointer is clear.  r2 holds the bit 2 value for\r
198         future use. */\r
199         MOV             r0, sp\r
200         AND             r2, r0, #4\r
201         SUB             sp, sp, r2\r
202 \r
203         /* Call the interrupt handler. */\r
204         PUSH    {r0-r3, lr}\r
205         LDR             r1, =vApplicationIRQHandler\r
206         BLX             r1\r
207         POP             {r0-r3, lr}\r
208         ADD             sp, sp, r2\r
209 \r
210         CPSID   i\r
211         DSB\r
212         ISB\r
213 \r
214         /* Write to the EOI register. */\r
215         LDR     r2, =configEOI_ADDRESS\r
216         STR             r0, [r2]\r
217 \r
218         /* Restore the old nesting count. */\r
219         STR             r1, [r3]\r
220 \r
221         /* A context switch is never performed if the nesting count is not 0. */\r
222         CMP             r1, #0\r
223         BNE             exit_without_switch\r
224 \r
225         /* Did the interrupt request a context switch?  r1 holds the address of\r
226         ulPortYieldRequired and r0 the value of ulPortYieldRequired for future\r
227         use. */\r
228         LDR             r1, =ulPortYieldRequired\r
229         LDR             r0, [r1]\r
230         CMP             r0, #0\r
231         BNE             switch_before_exit\r
232 \r
233 exit_without_switch:\r
234         /* No context switch.  Restore used registers, LR_irq and SPSR before\r
235         returning. */\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         MOVS    PC, LR\r
242 \r
243 switch_before_exit:\r
244         /* A context swtich is to be performed.  Clear the context switch pending\r
245         flag. */\r
246         MOV             r0, #0\r
247         STR             r0, [r1]\r
248 \r
249         /* Restore used registers, LR-irq and SPSR before saving the context\r
250         to the task stack. */\r
251         POP             {r0-r3, r12}\r
252         CPS             #IRQ_MODE\r
253         POP             {LR}\r
254         MSR             SPSR_cxsf, LR\r
255         POP             {LR}\r
256         portSAVE_CONTEXT\r
257 \r
258         /* Call the function that selects the new task to execute.\r
259         vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD\r
260         instructions, or 8 byte aligned stack allocated data.  LR does not need\r
261         saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */\r
262         LDR             R0, =vTaskSwitchContext\r
263         BLX             R0\r
264 \r
265         /* Restore the context of, and branch to, the task selected to execute\r
266         next. */\r
267         portRESTORE_CONTEXT\r
268 \r
269         END\r
270 \r
271 \r
272 \r
273 \r
274 \r