1 /*----------------------------------------------------------------------------
2 * CMSIS-RTOS - RTX
3 *----------------------------------------------------------------------------
4 * Name: HAL_CM4.C
5 * Purpose: Hardware Abstraction Layer for Cortex-M4
6 * Rev.: V4.79
7 *----------------------------------------------------------------------------
8 *
9 * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
10 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * - Neither the name of ARM nor the names of its contributors may be used
19 * to endorse or promote products derived from this software without
20 * specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *---------------------------------------------------------------------------*/
34
35 #include "rt_TypeDef.h"
36 #include "RTX_Config.h"
37 #include "rt_System.h"
38 #include "rt_HAL_CM.h"
39 #include "rt_Task.h"
40 #include "rt_MemBox.h"
41
42
43 /*----------------------------------------------------------------------------
44 * Functions
45 *---------------------------------------------------------------------------*/
46
47
48 /*--------------------------- rt_set_PSP ------------------------------------*/
49
rt_set_PSP(U32 stack)50 __asm void rt_set_PSP (U32 stack) {
51 MSR PSP,R0
52 BX LR
53 }
54
55
56 /*--------------------------- rt_get_PSP ------------------------------------*/
57
rt_get_PSP(void)58 __asm U32 rt_get_PSP (void) {
59 MRS R0,PSP
60 BX LR
61 }
62
63
64 /*--------------------------- os_set_env ------------------------------------*/
65
os_set_env(void)66 __asm void os_set_env (void) {
67 /* Switch to Unprivileged/Privileged Thread mode, use PSP. */
68 MOV R0,SP ; PSP = MSP
69 MSR PSP,R0
70 LDR R0,=__cpp(&os_flags)
71 LDRB R0,[R0]
72 LSLS R0,#31
73 MOVNE R0,#0x02 ; Privileged Thread mode, use PSP
74 MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP
75 MSR CONTROL,R0
76 BX LR
77
78 ALIGN
79 }
80
81
82 /*--------------------------- _alloc_box ------------------------------------*/
83
_alloc_box(void * box_mem)84 __asm void *_alloc_box (void *box_mem) {
85 /* Function wrapper for Unprivileged/Privileged mode. */
86 LDR R12,=__cpp(rt_alloc_box)
87 MRS R3,IPSR
88 LSLS R3,#24
89 BXNE R12
90 MRS R3,CONTROL
91 LSLS R3,#31
92 BXEQ R12
93 SVC 0
94 BX LR
95
96 ALIGN
97 }
98
99
100 /*--------------------------- _free_box -------------------------------------*/
101
_free_box(void * box_mem,void * box)102 __asm U32 _free_box (void *box_mem, void *box) {
103 /* Function wrapper for Unprivileged/Privileged mode. */
104 LDR R12,=__cpp(rt_free_box)
105 MRS R3,IPSR
106 LSLS R3,#24
107 BXNE R12
108 MRS R3,CONTROL
109 LSLS R3,#31
110 BXEQ R12
111 SVC 0
112 BX LR
113
114 ALIGN
115 }
116
117
118 /*-------------------------- SVC_Handler ------------------------------------*/
119
SVC_Handler(void)120 __asm void SVC_Handler (void) {
121 PRESERVE8
122
123 IMPORT SVC_Count
124 IMPORT SVC_Table
125 IMPORT rt_stk_check
126
127 #ifdef IFX_XMC4XXX
128 EXPORT SVC_Handler_Veneer
129 SVC_Handler_Veneer
130 #endif
131
132 MRS R0,PSP ; Read PSP
133 LDR R1,[R0,#24] ; Read Saved PC from Stack
134 LDRB R1,[R1,#-2] ; Load SVC Number
135 CBNZ R1,SVC_User
136
137 LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack
138 PUSH {R4,LR} ; Save EXC_RETURN
139 BLX R12 ; Call SVC Function
140 POP {R4,LR} ; Restore EXC_RETURN
141
142 MRS R12,PSP ; Read PSP
143 STM R12,{R0-R2} ; Store return values
144
145 LDR R3,=__cpp(&os_tsk)
146 LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new
147 CMP R1,R2
148 #ifdef IFX_XMC4XXX
149 PUSHEQ {LR}
150 POPEQ {PC}
151 #else
152 BXEQ LR ; RETI, no task switch
153 #endif
154
155 CBNZ R1,SVC_ContextSave ; Runtask not deleted?
156
157 TST LR,#0x10 ; is it extended frame?
158 BNE SVC_ContextRestore
159 LDR R1,=0xE000EF34
160 LDR R0,[R1] ; Load FPCCR
161 BIC R0,#1 ; Clear LSPACT (Lazy state)
162 STR R0,[R1] ; Store FPCCR
163 B SVC_ContextRestore
164
165 SVC_ContextSave
166 TST LR,#0x10 ; is it extended frame?
167 VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs
168 MOVEQ R0,#0x01 ; os_tsk->stack_frame val
169 MOVNE R0,#0x00
170 STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val
171 STMDB R12!,{R4-R11} ; Save Old context
172 STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack
173
174 PUSH {R2,R3}
175 BL rt_stk_check ; Check for Stack overflow
176 POP {R2,R3}
177
178 SVC_ContextRestore
179 STR R2,[R3] ; os_tsk.run = os_tsk.new
180
181 LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack
182 LDMIA R12!,{R4-R11} ; Restore New Context
183 LDRB R0,[R2,#TCB_STACKF] ; Stack Frame
184 CMP R0,#0 ; Basic/Extended Stack Frame
185 MVNEQ LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value
186 MVNNE LR,#:NOT:0xFFFFFFED
187 VLDMIANE R12!,{S16-S31} ; restore VFP hi-registers
188 MSR PSP,R12 ; Write PSP
189
190 SVC_Exit
191 #ifdef IFX_XMC4XXX
192 PUSH {LR}
193 POP {PC}
194 #else
195 BX LR
196 #endif
197
198 /*------------------- User SVC ------------------------------*/
199
200 SVC_User
201 PUSH {R4,LR} ; Save Registers
202 LDR R2,=SVC_Count
203 LDR R2,[R2]
204 CMP R1,R2
205 BHI SVC_Done ; Overflow
206
207 LDR R4,=SVC_Table-4
208 LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address
209
210 LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack
211 BLX R4 ; Call SVC Function
212
213 MRS R12,PSP
214 STM R12,{R0-R3} ; Function return values
215 SVC_Done
216 POP {R4,PC} ; RETI
217
218 ALIGN
219 }
220
221
222 /*-------------------------- PendSV_Handler ---------------------------------*/
223
224 __asm void PendSV_Handler (void) {
225 PRESERVE8
226
227 #ifdef IFX_XMC4XXX
228 EXPORT PendSV_Handler_Veneer
229 PendSV_Handler_Veneer
230 #endif
231
232 PUSH {R4,LR} ; Save EXC_RETURN
233 BL __cpp(rt_pop_req)
234
235 Sys_Switch
236 POP {R4,LR} ; Restore EXC_RETURN
237
238 LDR R3,=__cpp(&os_tsk)
239 LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new
240 CMP R1,R2
241 #ifdef IFX_XMC4XXX
242 PUSHEQ {LR}
243 POPEQ {PC}
244 #else
245 BXEQ LR ; RETI, no task switch
246 #endif
247
248 MRS R12,PSP ; Read PSP
249 TST LR,#0x10 ; is it extended frame?
250 VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs
251 MOVEQ R0,#0x01 ; os_tsk->stack_frame val
252 MOVNE R0,#0x00
253 STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val
254 STMDB R12!,{R4-R11} ; Save Old context
255 STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack
256
257 PUSH {R2,R3}
258 BL rt_stk_check ; Check for Stack overflow
259 POP {R2,R3}
260
261 STR R2,[R3] ; os_tsk.run = os_tsk.new
262
263 LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack
264 LDMIA R12!,{R4-R11} ; Restore New Context
265 LDRB R0,[R2,#TCB_STACKF] ; Stack Frame
266 CMP R0,#0 ; Basic/Extended Stack Frame
267 MVNEQ LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value
268 MVNNE LR,#:NOT:0xFFFFFFED
269 VLDMIANE R12!,{S16-S31} ; restore VFP hi-regs
270 MSR PSP,R12 ; Write PSP
271
272 Sys_Exit
273 #ifdef IFX_XMC4XXX
274 PUSH {LR}
275 POP {PC}
276 #else
277 BX LR ; Return to Thread Mode
278 #endif
279
280 ALIGN
281 }
282
283
284 /*-------------------------- SysTick_Handler --------------------------------*/
285
286 __asm void SysTick_Handler (void) {
287 PRESERVE8
288
289 #ifdef IFX_XMC4XXX
290 EXPORT SysTick_Handler_Veneer
291 SysTick_Handler_Veneer
292 #endif
293
294 PUSH {R4,LR} ; Save EXC_RETURN
295 BL __cpp(rt_systick)
296 B Sys_Switch
297
298 ALIGN
299 }
300
301
302 /*-------------------------- OS_Tick_Handler --------------------------------*/
303
304 __asm void OS_Tick_Handler (void) {
305 PRESERVE8
306
307 PUSH {R4,LR} ; Save EXC_RETURN
308 BL __cpp(os_tick_irqack)
309 BL __cpp(rt_systick)
310 B Sys_Switch
311
312 ALIGN
313 }
314
315
316 /*----------------------------------------------------------------------------
317 * end of file
318 *---------------------------------------------------------------------------*/
319