]> begriffs open source - freertos/blob - portable/IAR/ARM_CM7/r0p1/portasm.s
Add SPDX-License-Identifier: MIT to MIT licensed files.
[freertos] / portable / IAR / ARM_CM7 / r0p1 / portasm.s
1 /*\r
2  * FreeRTOS Kernel <DEVELOPMENT BRANCH>\r
3  * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
8  * this software and associated documentation files (the "Software"), to deal in\r
9  * the Software without restriction, including without limitation the rights to\r
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
11  * the Software, and to permit persons to whom the Software is furnished to do so,\r
12  * subject to the following conditions:\r
13  *\r
14  * The above copyright notice and this permission notice shall be included in all\r
15  * copies or substantial portions of the Software.\r
16  *\r
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
23  *\r
24  * https://www.FreeRTOS.org\r
25  * https://github.com/FreeRTOS\r
26  *\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 \r
37         PUBLIC xPortPendSVHandler\r
38         PUBLIC vPortSVCHandler\r
39         PUBLIC vPortStartFirstTask\r
40         PUBLIC vPortEnableVFP\r
41 \r
42 \r
43 /*-----------------------------------------------------------*/\r
44 \r
45 xPortPendSVHandler:\r
46         mrs r0, psp\r
47         isb\r
48         /* Get the location of the current TCB. */\r
49         ldr     r3, =pxCurrentTCB\r
50         ldr     r2, [r3]\r
51 \r
52         /* Is the task using the FPU context?  If so, push high vfp registers. */\r
53         tst r14, #0x10\r
54         it eq\r
55         vstmdbeq r0!, {s16-s31}\r
56 \r
57         /* Save the core registers. */\r
58         stmdb r0!, {r4-r11, r14}\r
59 \r
60         /* Save the new top of stack into the first member of the TCB. */\r
61         str r0, [r2]\r
62 \r
63         stmdb sp!, {r0, r3}\r
64         mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY\r
65         cpsid i\r
66         msr basepri, r0\r
67         dsb\r
68         isb\r
69         cpsie i\r
70         bl vTaskSwitchContext\r
71         mov r0, #0\r
72         msr basepri, r0\r
73         ldmia sp!, {r0, r3}\r
74 \r
75         /* The first item in pxCurrentTCB is the task top of stack. */\r
76         ldr r1, [r3]\r
77         ldr r0, [r1]\r
78 \r
79         /* Pop the core registers. */\r
80         ldmia r0!, {r4-r11, r14}\r
81 \r
82         /* Is the task using the FPU context?  If so, pop the high vfp registers\r
83         too. */\r
84         tst r14, #0x10\r
85         it eq\r
86         vldmiaeq r0!, {s16-s31}\r
87 \r
88         msr psp, r0\r
89         isb\r
90         #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */\r
91                 #if WORKAROUND_PMU_CM001 == 1\r
92                         push { r14 }\r
93                         pop { pc }\r
94                 #endif\r
95         #endif\r
96 \r
97         bx r14\r
98 \r
99 \r
100 /*-----------------------------------------------------------*/\r
101 \r
102 vPortSVCHandler:\r
103         /* Get the location of the current TCB. */\r
104         ldr     r3, =pxCurrentTCB\r
105         ldr r1, [r3]\r
106         ldr r0, [r1]\r
107         /* Pop the core registers. */\r
108         ldmia r0!, {r4-r11, r14}\r
109         msr psp, r0\r
110         isb\r
111         mov r0, #0\r
112         msr     basepri, r0\r
113         bx r14\r
114 \r
115 /*-----------------------------------------------------------*/\r
116 \r
117 vPortStartFirstTask\r
118         /* Use the NVIC offset register to locate the stack. */\r
119         ldr r0, =0xE000ED08\r
120         ldr r0, [r0]\r
121         ldr r0, [r0]\r
122         /* Set the msp back to the start of the stack. */\r
123         msr msp, r0\r
124         /* Clear the bit that indicates the FPU is in use in case the FPU was used\r
125         before the scheduler was started - which would otherwise result in the\r
126         unnecessary leaving of space in the SVC stack for lazy saving of FPU\r
127         registers. */\r
128         mov r0, #0\r
129         msr control, r0\r
130         /* Call SVC to start the first task. */\r
131         cpsie i\r
132         cpsie f\r
133         dsb\r
134         isb\r
135         svc 0\r
136 \r
137 /*-----------------------------------------------------------*/\r
138 \r
139 vPortEnableVFP:\r
140         /* The FPU enable bits are in the CPACR. */\r
141         ldr.w r0, =0xE000ED88\r
142         ldr     r1, [r0]\r
143 \r
144         /* Enable CP10 and CP11 coprocessors, then save back. */\r
145         orr     r1, r1, #( 0xf << 20 )\r
146         str r1, [r0]\r
147         bx      r14\r
148 \r
149 \r
150 \r
151         END\r
152 \r