]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/portasm.s
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Source / portable / IAR / ARM_CM4F_MPU / 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 #include <FreeRTOSConfig.h>\r
30 \r
31         RSEG    CODE:CODE(2)\r
32         thumb\r
33 \r
34         EXTERN pxCurrentTCB\r
35         EXTERN vTaskSwitchContext\r
36         EXTERN vPortSVCHandler_C\r
37 \r
38         PUBLIC xPortPendSVHandler\r
39         PUBLIC vPortSVCHandler\r
40         PUBLIC vPortStartFirstTask\r
41         PUBLIC vPortEnableVFP\r
42         PUBLIC vPortRestoreContextOfFirstTask\r
43         PUBLIC xPortRaisePrivilege\r
44 \r
45 /*-----------------------------------------------------------*/\r
46 \r
47 xPortPendSVHandler:\r
48         mrs r0, psp\r
49         isb\r
50         /* Get the location of the current TCB. */\r
51         ldr     r3, =pxCurrentTCB\r
52         ldr     r2, [r3]\r
53 \r
54         /* Is the task using the FPU context?  If so, push high vfp registers. */\r
55         tst r14, #0x10\r
56         it eq\r
57         vstmdbeq r0!, {s16-s31}\r
58 \r
59         /* Save the core registers. */\r
60         mrs r1, control\r
61         stmdb r0!, {r1, r4-r11, r14}\r
62 \r
63         /* Save the new top of stack into the first member of the TCB. */\r
64         str r0, [r2]\r
65 \r
66         stmdb sp!, {r0, r3}\r
67         mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY\r
68         msr basepri, r0\r
69         dsb\r
70         isb\r
71         bl vTaskSwitchContext\r
72         mov r0, #0\r
73         msr basepri, r0\r
74         ldmia sp!, {r0, r3}\r
75 \r
76         /* The first item in pxCurrentTCB is the task top of stack. */\r
77         ldr r1, [r3]\r
78         ldr r0, [r1]\r
79         /* Move onto the second item in the TCB... */\r
80         add r1, r1, #4\r
81         /* Region Base Address register. */\r
82         ldr r2, =0xe000ed9c\r
83         /* Read 4 sets of MPU registers. */\r
84         ldmia r1!, {r4-r11}\r
85         /* Write 4 sets of MPU registers. */\r
86         stmia r2!, {r4-r11}\r
87         /* Pop the registers that are not automatically saved on exception entry. */\r
88         ldmia r0!, {r3-r11, r14}\r
89         msr control, r3\r
90 \r
91         /* Is the task using the FPU context?  If so, pop the high vfp registers\r
92         too. */\r
93         tst r14, #0x10\r
94         it eq\r
95         vldmiaeq r0!, {s16-s31}\r
96 \r
97         msr psp, r0\r
98         isb\r
99 \r
100         bx r14\r
101 \r
102 \r
103 /*-----------------------------------------------------------*/\r
104 \r
105 vPortSVCHandler:\r
106         #ifndef USE_PROCESS_STACK       /* Code should not be required if a main() is using the process stack. */\r
107                 tst lr, #4\r
108                 ite eq\r
109                 mrseq r0, msp\r
110                 mrsne r0, psp\r
111         #else\r
112                 mrs r0, psp\r
113         #endif\r
114                 b vPortSVCHandler_C\r
115 \r
116 /*-----------------------------------------------------------*/\r
117 \r
118 vPortStartFirstTask\r
119         /* Use the NVIC offset register to locate the stack. */\r
120         ldr r0, =0xE000ED08\r
121         ldr r0, [r0]\r
122         ldr r0, [r0]\r
123         /* Set the msp back to the start of the stack. */\r
124         msr msp, r0\r
125         /* Clear the bit that indicates the FPU is in use in case the FPU was used\r
126         before the scheduler was started - which would otherwise result in the\r
127         unnecessary leaving of space in the SVC stack for lazy saving of FPU\r
128         registers. */\r
129         mov r0, #0\r
130         msr control, r0\r
131         /* Call SVC to start the first task. */\r
132         cpsie i\r
133         cpsie f\r
134         dsb\r
135         isb\r
136         svc 0\r
137 \r
138 /*-----------------------------------------------------------*/\r
139 \r
140 vPortRestoreContextOfFirstTask\r
141         /* Use the NVIC offset register to locate the stack. */\r
142         ldr r0, =0xE000ED08\r
143         ldr r0, [r0]\r
144         ldr r0, [r0]\r
145         /* Set the msp back to the start of the stack. */\r
146         msr msp, r0\r
147         /* Restore the context. */\r
148         ldr     r3, =pxCurrentTCB\r
149         ldr r1, [r3]\r
150         /* The first item in the TCB is the task top of stack. */\r
151         ldr r0, [r1]\r
152         /* Move onto the second item in the TCB... */\r
153         add r1, r1, #4\r
154         /* Region Base Address register. */\r
155         ldr r2, =0xe000ed9c\r
156         /* Read 4 sets of MPU registers. */\r
157         ldmia r1!, {r4-r11}\r
158         /* Write 4 sets of MPU registers. */\r
159         stmia r2!, {r4-r11}\r
160         /* Pop the registers that are not automatically saved on exception entry. */\r
161         ldmia r0!, {r3-r11, r14}\r
162         msr control, r3\r
163         /* Restore the task stack pointer. */\r
164         msr psp, r0\r
165         mov r0, #0\r
166         msr     basepri, r0\r
167         bx r14\r
168 \r
169 /*-----------------------------------------------------------*/\r
170 \r
171 vPortEnableVFP\r
172         /* The FPU enable bits are in the CPACR. */\r
173         ldr.w r0, =0xE000ED88\r
174         ldr     r1, [r0]\r
175 \r
176         /* Enable CP10 and CP11 coprocessors, then save back. */\r
177         orr     r1, r1, #( 0xf << 20 )\r
178         str r1, [r0]\r
179         bx      r14\r
180 \r
181 /*-----------------------------------------------------------*/\r
182 \r
183 xPortRaisePrivilege\r
184         mrs r0, control\r
185         /* Is the task running privileged? */\r
186         tst r0, #1\r
187         itte ne\r
188         /* CONTROL[0]!=0, return false. */\r
189         movne r0, #0\r
190         /* Switch to privileged. */\r
191         svcne 2 /* 2 == portSVC_RAISE_PRIVILEGE */\r
192         /* CONTROL[0]==0, return true. */\r
193         moveq r0, #1\r
194         bx lr\r
195 \r
196 \r
197         END\r
198 \r