1;/*
2; * FreeRTOS Kernel V11.1.0
3; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4; *
5; * SPDX-License-Identifier: MIT
6; *
7; * Permission is hereby granted, free of charge, to any person obtaining a copy of
8; * this software and associated documentation files (the "Software"), to deal in
9; * the Software without restriction, including without limitation the rights to
10; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11; * the Software, and to permit persons to whom the Software is furnished to do so,
12; * subject to the following conditions:
13; *
14; * The above copyright notice and this permission notice shall be included in all
15; * copies or substantial portions of the Software.
16; *
17; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23; *
24; * https://www.FreeRTOS.org
25; * https://github.com/FreeRTOS
26; *
27; */
28
29
30    .extern pxCurrentTCB
31    .extern vTaskSwitchContext
32    .extern ulMaxSyscallInterruptPriorityConst
33
34    .global _vector_14
35    .global _lc_ref__vector_pp_14
36    .global SVC_Handler
37    .global vPortStartFirstTask
38    .global vPortEnableVFP
39    .global ulPortSetInterruptMask
40    .global vPortClearInterruptMask
41
42;-----------------------------------------------------------
43
44    .section .text
45    .thumb
46    .align 4
47_vector_14: .type func
48
49    mrs r0, psp
50    isb
51
52    ;Get the location of the current TCB.
53    ldr.w   r3, =pxCurrentTCB
54    ldr r2, [r3]
55
56    ;Is the task using the FPU context?  If so, push high vfp registers.
57    tst r14, #0x10
58    it eq
59    vstmdbeq r0!, {s16-s31}
60
61    ;Save the core registers.
62    stmdb r0!, {r4-r11, r14}
63
64    ;Save the new top of stack into the first member of the TCB.
65    str r0, [r2]
66
67    stmdb sp!, {r0, r3}
68    ldr.w r0, =ulMaxSyscallInterruptPriorityConst
69    ldr r0, [r0]
70    msr basepri, r0
71    bl vTaskSwitchContext
72    mov r0, #0
73    msr basepri, r0
74    ldmia sp!, {r0, r3}
75
76    ;The first item in pxCurrentTCB is the task top of stack.
77    ldr r1, [r3]
78    ldr r0, [r1]
79
80    ;Pop the core registers.
81    ldmia r0!, {r4-r11, r14}
82
83    ;Is the task using the FPU context?  If so, pop the high vfp registers too.
84    tst r14, #0x10
85    it eq
86    vldmiaeq r0!, {s16-s31}
87
88    msr psp, r0
89    isb
90    bx r14
91
92    .size   _vector_14, $-_vector_14
93    .endsec
94
95;-----------------------------------------------------------
96
97; This function is an XMC4000 silicon errata workaround.  It will get used when
98; the SILICON_BUG_PMC_CM_001 linker macro is defined.
99    .section .text
100    .thumb
101    .align 4
102_lc_ref__vector_pp_14: .type func
103
104    mrs r0, psp
105    isb
106
107    ;Get the location of the current TCB.
108    ldr.w   r3, =pxCurrentTCB
109    ldr r2, [r3]
110
111    ;Is the task using the FPU context?  If so, push high vfp registers.
112    tst r14, #0x10
113    it eq
114    vstmdbeq r0!, {s16-s31}
115
116    ;Save the core registers.
117    stmdb r0!, {r4-r11, r14}
118
119    ;Save the new top of stack into the first member of the TCB.
120    str r0, [r2]
121
122    stmdb sp!, {r3}
123    ldr.w r0, =ulMaxSyscallInterruptPriorityConst
124    ldr r0, [r0]
125    msr basepri, r0
126    bl vTaskSwitchContext
127    mov r0, #0
128    msr basepri, r0
129    ldmia sp!, {r3}
130
131    ;The first item in pxCurrentTCB is the task top of stack.
132    ldr r1, [r3]
133    ldr r0, [r1]
134
135    ;Pop the core registers.
136    ldmia r0!, {r4-r11, r14}
137
138    ;Is the task using the FPU context?  If so, pop the high vfp registers too.
139    tst r14, #0x10
140    it eq
141    vldmiaeq r0!, {s16-s31}
142
143    msr psp, r0
144    isb
145    push { lr }
146    pop { pc } ; XMC4000 specific errata workaround.  Do not used "bx lr" here.
147
148    .size   _lc_ref__vector_pp_14, $-_lc_ref__vector_pp_14
149    .endsec
150
151;-----------------------------------------------------------
152
153    .section .text
154    .thumb
155    .align 4
156SVC_Handler: .type func
157    ;Get the location of the current TCB.
158    ldr.w   r3, =pxCurrentTCB
159    ldr r1, [r3]
160    ldr r0, [r1]
161    ;Pop the core registers.
162    ldmia r0!, {r4-r11, r14}
163    msr psp, r0
164    isb
165    mov r0, #0
166    msr basepri, r0
167    bx r14
168    .size   SVC_Handler, $-SVC_Handler
169    .endsec
170
171;-----------------------------------------------------------
172
173    .section .text
174    .thumb
175    .align 4
176vPortStartFirstTask .type func
177    ;Use the NVIC offset register to locate the stack.
178    ldr.w r0, =0xE000ED08
179    ldr r0, [r0]
180    ldr r0, [r0]
181    ;Set the msp back to the start of the stack.
182    msr msp, r0
183    ;Call SVC to start the first task.
184    cpsie i
185    cpsie f
186    dsb
187    isb
188    svc 0
189    .size   vPortStartFirstTask, $-vPortStartFirstTask
190    .endsec
191
192;-----------------------------------------------------------
193
194    .section .text
195    .thumb
196    .align 4
197vPortEnableVFP .type func
198    ;The FPU enable bits are in the CPACR.
199    ldr.w r0, =0xE000ED88
200    ldr r1, [r0]
201
202    ;Enable CP10 and CP11 coprocessors, then save back.
203    orr r1, r1, #( 0xf << 20 )
204    str r1, [r0]
205    bx  r14
206    .size   vPortEnableVFP, $-vPortEnableVFP
207    .endsec
208
209;-----------------------------------------------------------
210
211    .section .text
212    .thumb
213    .align 4
214ulPortSetInterruptMask:
215    mrs r0, basepri
216    ldr.w r1, =ulMaxSyscallInterruptPriorityConst
217    ldr r1, [r1]
218    msr basepri, r1
219    bx r14
220    .size   ulPortSetInterruptMask, $-ulPortSetInterruptMask
221    .endsec
222
223;-----------------------------------------------------------
224
225    .section .text
226    .thumb
227    .align 4
228vPortClearInterruptMask:
229    msr basepri, r0
230    bx r14
231    .size   vPortClearInterruptMask, $-vPortClearInterruptMask
232    .endsec
233
234;-----------------------------------------------------------
235
236    .end
237