1/*----------------------------------------------------------------------------
2 *      CMSIS-RTOS  -  RTX
3 *----------------------------------------------------------------------------
4 *      Name:    HAL_CM3.S
5 *      Purpose: Hardware Abstraction Layer for Cortex-M3
6 *      Rev.:    V4.70
7 *----------------------------------------------------------------------------
8 *
9 * Copyright (c) 1999-2009 KEIL, 2009-2013 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        .file   "HAL_CM3.S"
36        .syntax unified
37
38        .equ    TCB_TSTACK, 40
39
40
41/*----------------------------------------------------------------------------
42 *      Functions
43 *---------------------------------------------------------------------------*/
44
45        .thumb
46
47        .section ".text"
48        .align  2
49
50
51/*--------------------------- rt_set_PSP ------------------------------------*/
52
53#       void rt_set_PSP (U32 stack);
54
55        .thumb_func
56        .type   rt_set_PSP, %function
57        .global rt_set_PSP
58rt_set_PSP:
59        .fnstart
60        .cantunwind
61
62        MSR     PSP,R0
63        BX      LR
64
65        .fnend
66        .size   rt_set_PSP, .-rt_set_PSP
67
68
69/*--------------------------- rt_get_PSP ------------------------------------*/
70
71#       U32 rt_get_PSP (void);
72
73        .thumb_func
74        .type   rt_get_PSP, %function
75        .global rt_get_PSP
76rt_get_PSP:
77        .fnstart
78        .cantunwind
79
80        MRS     R0,PSP
81        BX      LR
82
83        .fnend
84        .size   rt_get_PSP, .-rt_get_PSP
85
86
87/*--------------------------- os_set_env ------------------------------------*/
88
89#       void os_set_env (void);
90        /* Switch to Unprivileged/Privileged Thread mode, use PSP. */
91
92        .thumb_func
93        .type   os_set_env, %function
94        .global os_set_env
95os_set_env:
96        .fnstart
97        .cantunwind
98
99        MOV     R0,SP                   /* PSP = MSP */
100        MSR     PSP,R0
101        LDR     R0,=os_flags
102        LDRB    R0,[R0]
103        LSLS    R0,#31
104        ITE     NE
105        MOVNE   R0,#0x02                /* Privileged Thread mode, use PSP */
106        MOVEQ   R0,#0x03                /* Unprivileged Thread mode, use PSP */
107        MSR     CONTROL,R0
108        BX      LR
109
110        .fnend
111        .size   os_set_env, .-os_set_env
112
113
114/*--------------------------- _alloc_box ------------------------------------*/
115
116#      void *_alloc_box (void *box_mem);
117       /* Function wrapper for Unprivileged/Privileged mode. */
118
119        .thumb_func
120        .type   _alloc_box, %function
121        .global _alloc_box
122_alloc_box:
123        .fnstart
124        .cantunwind
125
126        LDR     R12,=rt_alloc_box
127        MRS     R3,IPSR
128        LSLS    R3,#24
129        IT      NE
130        BXNE    R12
131        MRS     R3,CONTROL
132        LSLS    R3,#31
133        IT      EQ
134        BXEQ    R12
135        SVC     0
136        BX      LR
137
138        .fnend
139        .size   _alloc_box, .-_alloc_box
140
141
142/*--------------------------- _free_box -------------------------------------*/
143
144#       U32 _free_box (void *box_mem, void *box);
145        /* Function wrapper for Unprivileged/Privileged mode. */
146
147        .thumb_func
148        .type   _free_box, %function
149        .global _free_box
150_free_box:
151        .fnstart
152        .cantunwind
153
154        LDR     R12,=rt_free_box
155        MRS     R3,IPSR
156        LSLS    R3,#24
157        IT      NE
158        BXNE    R12
159        MRS     R3,CONTROL
160        LSLS    R3,#31
161        IT      EQ
162        BXEQ    R12
163        SVC     0
164        BX      LR
165
166        .fnend
167        .size   _free_box, .-_free_box
168
169
170/*-------------------------- SVC_Handler ------------------------------------*/
171
172#       void SVC_Handler (void);
173
174        .thumb_func
175        .type   SVC_Handler, %function
176        .global SVC_Handler
177SVC_Handler:
178        .ifdef  IFX_XMC4XXX
179        .global SVC_Handler_Veneer
180SVC_Handler_Veneer:
181        .endif
182        .fnstart
183        .cantunwind
184
185        MRS     R0,PSP                  /* Read PSP */
186        LDR     R1,[R0,#24]             /* Read Saved PC from Stack */
187        LDRB    R1,[R1,#-2]             /* Load SVC Number */
188        CBNZ    R1,SVC_User
189
190        LDM     R0,{R0-R3,R12}          /* Read R0-R3,R12 from stack */
191        BLX     R12                     /* Call SVC Function */
192
193        MRS     R12,PSP                 /* Read PSP */
194        STM     R12,{R0-R2}             /* Store return values */
195
196        LDR     R3,=os_tsk
197        LDM     R3,{R1,R2}              /* os_tsk.run, os_tsk.new */
198        CMP     R1,R2
199        BEQ     SVC_Exit                /* no task switch */
200
201        CBZ     R1,SVC_Next             /* Runtask deleted? */
202        STMDB   R12!,{R4-R11}           /* Save Old context */
203        STR     R12,[R1,#TCB_TSTACK]    /* Update os_tsk.run->tsk_stack */
204
205        PUSH    {R2,R3}
206        BL      rt_stk_check            /* Check for Stack overflow */
207        POP     {R2,R3}
208
209SVC_Next:
210        STR     R2,[R3]                 /* os_tsk.run = os_tsk.new */
211
212        LDR     R12,[R2,#TCB_TSTACK]    /* os_tsk.new->tsk_stack */
213        LDMIA   R12!,{R4-R11}           /* Restore New Context */
214        MSR     PSP,R12                 /* Write PSP */
215
216SVC_Exit:
217        MVN     LR,#~0xFFFFFFFD         /* set EXC_RETURN value */
218        .ifdef  IFX_XMC4XXX
219        PUSH    {LR}
220        POP     {PC}
221        .else
222        BX      LR
223        .endif
224
225        /*------------------- User SVC ------------------------------*/
226
227SVC_User:
228        PUSH    {R4,LR}                 /* Save Registers */
229        LDR     R2,=SVC_Count
230        LDR     R2,[R2]
231        CMP     R1,R2
232        BHI     SVC_Done                /* Overflow */
233
234        LDR     R4,=SVC_Table-4
235        LDR     R4,[R4,R1,LSL #2]       /* Load SVC Function Address */
236
237        LDM     R0,{R0-R3,R12}          /* Read R0-R3,R12 from stack */
238        BLX     R4                      /* Call SVC Function */
239
240        MRS     R12,PSP
241        STM     R12,{R0-R3}             /* Function return values */
242SVC_Done:
243        POP     {R4,PC}                 /* RETI */
244
245        .fnend
246        .size   SVC_Handler, .-SVC_Handler
247
248
249/*-------------------------- PendSV_Handler ---------------------------------*/
250
251#       void PendSV_Handler (void);
252
253        .thumb_func
254        .type   PendSV_Handler, %function
255        .global PendSV_Handler
256        .global Sys_Switch
257PendSV_Handler:
258        .ifdef  IFX_XMC4XXX
259        .global PendSV_Handler_Veneer
260PendSV_Handler_Veneer:
261        .endif
262        .fnstart
263        .cantunwind
264
265        BL      rt_pop_req
266
267Sys_Switch:
268        LDR     R3,=os_tsk
269        LDM     R3,{R1,R2}              /* os_tsk.run, os_tsk.new */
270        CMP     R1,R2
271        BEQ     Sys_Exit
272
273        MRS     R12,PSP                 /* Read PSP */
274        STMDB   R12!,{R4-R11}           /* Save Old context */
275        STR     R12,[R1,#TCB_TSTACK]    /* Update os_tsk.run->tsk_stack */
276
277        PUSH    {R2,R3}
278        BL      rt_stk_check            /* Check for Stack overflow */
279        POP     {R2,R3}
280
281        STR     R2,[R3]                 /* os_tsk.run = os_tsk.new */
282
283        LDR     R12,[R2,#TCB_TSTACK]    /* os_tsk.new->tsk_stack */
284        LDMIA   R12!,{R4-R11}           /* Restore New Context */
285        MSR     PSP,R12                 /* Write PSP */
286
287Sys_Exit:
288        MVN     LR,#~0xFFFFFFFD         /* set EXC_RETURN value */
289        .ifdef  IFX_XMC4XXX
290        PUSH    {LR}
291        POP     {PC}
292        .else
293        BX      LR                      /* Return to Thread Mode */
294        .endif
295
296        .fnend
297        .size   PendSV_Handler, .-PendSV_Handler
298
299
300/*-------------------------- SysTick_Handler --------------------------------*/
301
302#       void SysTick_Handler (void);
303
304        .thumb_func
305        .type   SysTick_Handler, %function
306        .global SysTick_Handler
307SysTick_Handler:
308        .ifdef  IFX_XMC4XXX
309        .global SysTick_Handler_Veneer
310SysTick_Handler_Veneer:
311        .endif
312        .fnstart
313        .cantunwind
314
315        BL      rt_systick
316        B       Sys_Switch
317
318        .fnend
319        .size   SysTick_Handler, .-SysTick_Handler
320
321
322/*-------------------------- OS_Tick_Handler --------------------------------*/
323
324#       void OS_Tick_Handler (void);
325
326        .thumb_func
327        .type   OS_Tick_Handler, %function
328        .global OS_Tick_Handler
329OS_Tick_Handler:
330        .fnstart
331        .cantunwind
332
333        BL      os_tick_irqack
334        BL      rt_systick
335        B       Sys_Switch
336
337        .fnend
338        .size   OS_Tick_Handler, .-OS_Tick_Handler
339
340
341        .end
342
343/*----------------------------------------------------------------------------
344 * end of file
345 *---------------------------------------------------------------------------*/
346