]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/portasm.s
Update version number ready for next release.
[freertos] / FreeRTOS / Source / portable / IAR / ARM_CM4F_MPU / portasm.s
1 /*\r
2  * FreeRTOS Kernel V10.2.1\r
3  * Copyright (C) 2019 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 #include <FreeRTOSConfig.h>\r
29 \r
30         RSEG    CODE:CODE(2)\r
31         thumb\r
32 \r
33         EXTERN pxCurrentTCB\r
34         EXTERN vTaskSwitchContext\r
35         EXTERN vPortSVCHandler_C\r
36 \r
37         PUBLIC xPortPendSVHandler\r
38         PUBLIC vPortSVCHandler\r
39         PUBLIC vPortStartFirstTask\r
40         PUBLIC vPortEnableVFP\r
41         PUBLIC vPortRestoreContextOfFirstTask\r
42         PUBLIC xIsPrivileged\r
43         PUBLIC vResetPrivilege\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 xIsPrivileged:\r
184         mrs r0, control         /* r0 = CONTROL. */\r
185         tst r0, #1                      /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */\r
186         ite ne\r
187         movne r0, #0            /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */\r
188         moveq r0, #1            /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */\r
189         bx lr                           /* Return. */\r
190 /*-----------------------------------------------------------*/\r
191 \r
192 vResetPrivilege:\r
193         mrs r0, control         /* r0 = CONTROL. */\r
194         orr r0, r0, #1          /* r0 = r0 | 1. */\r
195         msr control, r0         /* CONTROL = r0. */\r
196         bx lr                           /* Return to the caller. */\r
197 /*-----------------------------------------------------------*/\r
198 \r
199         END\r