]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.s
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / rtos / rtx / TARGET_CORTEX_M / TARGET_M0P / TOOLCHAIN_GCC / HAL_CM0.s
1 /*----------------------------------------------------------------------------
2  *      RL-ARM - RTX
3  *----------------------------------------------------------------------------
4  *      Name:    HAL_CM0.S
5  *      Purpose: Hardware Abstraction Layer for Cortex-M0
6  *      Rev.:    V4.60
7  *----------------------------------------------------------------------------
8  *
9  * Copyright (c) 1999-2009 KEIL, 2009-2012 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_CM0.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
58 rt_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
76 rt_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
95 os_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         BNE     PrivilegedE
105         MOVS    R0,#0x03                /* Unprivileged Thread mode, use PSP */
106         MSR     CONTROL,R0
107         BX      LR
108 PrivilegedE:
109         MOVS    R0,#0x02                /* Privileged Thread mode, use PSP */
110         MSR     CONTROL,R0
111         BX      LR
112
113         .fnend
114         .size   os_set_env, .-os_set_env
115
116
117 /*--------------------------- _alloc_box ------------------------------------*/
118
119 #      void *_alloc_box (void *box_mem);
120        /* Function wrapper for Unprivileged/Privileged mode. */
121
122         .thumb_func
123         .type   _alloc_box, %function
124         .global _alloc_box
125 _alloc_box:
126         .fnstart
127         .cantunwind
128
129         LDR     R3,=rt_alloc_box
130         MOV     R12,R3
131         MRS     R3,IPSR
132         LSLS    R3,#24
133         BNE     PrivilegedA
134         MRS     R3,CONTROL
135         LSLS    R3,#31
136         BEQ     PrivilegedA
137         SVC     0
138         BX      LR
139 PrivilegedA:
140         BX      R12
141
142         .fnend
143         .size   _alloc_box, .-_alloc_box
144
145
146 /*--------------------------- _free_box -------------------------------------*/
147
148 #       int _free_box (void *box_mem, void *box);
149         /* Function wrapper for Unprivileged/Privileged mode. */
150
151         .thumb_func
152         .type   _free_box, %function
153         .global _free_box
154 _free_box:
155         .fnstart
156         .cantunwind
157
158         LDR     R3,=rt_free_box
159         MOV     R12,R3
160         MRS     R3,IPSR
161         LSLS    R3,#24
162         BNE     PrivilegedF
163         MRS     R3,CONTROL
164         LSLS    R3,#31
165         BEQ     PrivilegedF
166         SVC     0
167         BX      LR
168 PrivilegedF:
169         BX      R12
170
171         .fnend
172         .size   _free_box, .-_free_box
173
174
175 /*-------------------------- SVC_Handler ------------------------------------*/
176
177 #       void SVC_Handler (void);
178
179         .thumb_func
180         .type   SVC_Handler, %function
181         .global SVC_Handler
182 SVC_Handler:
183         .fnstart
184         .cantunwind
185
186         MRS     R0,PSP                  /* Read PSP */
187         LDR     R1,[R0,#24]             /* Read Saved PC from Stack */
188         SUBS    R1,R1,#2                /* Point to SVC Instruction */
189         LDRB    R1,[R1]                 /* Load SVC Number */
190         CMP     R1,#0
191         BNE     SVC_User                /* User SVC Number > 0 */
192
193         MOV     LR,R4
194         LDMIA   R0,{R0-R3,R4}           /* Read R0-R3,R12 from stack */
195         MOV     R12,R4
196         MOV     R4,LR
197         BLX     R12                     /* Call SVC Function */
198
199         MRS     R3,PSP                  /* Read PSP */
200         STMIA   R3!,{R0-R2}             /* Store return values */
201
202         LDR     R3,=os_tsk
203         LDMIA   R3!,{R1,R2}             /* os_tsk.run, os_tsk.new */
204         CMP     R1,R2
205         BEQ     SVC_Exit                /* no task switch */
206
207         SUBS    R3,#8
208         CMP     R1,#0                   /* Runtask deleted? */
209         BEQ     SVC_Next
210
211         MRS     R0,PSP                  /* Read PSP */
212         SUBS    R0,R0,#32               /* Adjust Start Address */
213         STR     R0,[R1,#TCB_TSTACK]     /* Update os_tsk.run->tsk_stack */
214         STMIA   R0!,{R4-R7}             /* Save old context (R4-R7) */
215         MOV     R4,R8
216         MOV     R5,R9
217         MOV     R6,R10
218         MOV     R7,R11
219         STMIA   R0!,{R4-R7}             /* Save old context (R8-R11) */
220
221         PUSH    {R2,R3}
222         BL      rt_stk_check            /* Check for Stack overflow */
223         POP     {R2,R3}
224
225 SVC_Next:
226         STR     R2,[R3]                 /* os_tsk.run = os_tsk.new */
227
228         LDR     R0,[R2,#TCB_TSTACK]     /* os_tsk.new->tsk_stack */
229         ADDS    R0,R0,#16               /* Adjust Start Address */
230         LDMIA   R0!,{R4-R7}             /* Restore new Context (R8-R11) */
231         MOV     R8,R4
232         MOV     R9,R5
233         MOV     R10,R6
234         MOV     R11,R7
235         MSR     PSP,R0                  /* Write PSP */
236         SUBS    R0,R0,#32               /* Adjust Start Address */
237         LDMIA   R0!,{R4-R7}             /* Restore new Context (R4-R7) */
238
239 SVC_Exit:
240         MOVS    R0,#~0xFFFFFFFD         /* Set EXC_RETURN value */
241         MVNS    R0,R0
242         BX      R0                      /* RETI to Thread Mode, use PSP */
243
244         /*------------------- User SVC ------------------------------*/
245
246 SVC_User:
247         PUSH    {R4,LR}                 /* Save Registers */
248         LDR     R2,=SVC_Count
249         LDR     R2,[R2]
250         CMP     R1,R2
251         BHI     SVC_Done                /* Overflow */
252
253         LDR     R4,=SVC_Table-4
254         LSLS    R1,R1,#2
255         LDR     R4,[R4,R1]              /* Load SVC Function Address */
256         MOV     LR,R4
257
258         LDMIA   R0,{R0-R3,R4}           /* Read R0-R3,R12 from stack */
259         MOV     R12,R4
260         BLX     LR                      /* Call SVC Function */
261
262         MRS     R4,PSP                  /* Read PSP */
263         STMIA   R4!,{R0-R3}             /* Function return values */
264 SVC_Done:
265         POP     {R4,PC}                 /* RETI */
266
267         .fnend
268         .size   SVC_Handler, .-SVC_Handler
269
270
271 /*-------------------------- PendSV_Handler ---------------------------------*/
272
273 #       void PendSV_Handler (void);
274
275         .thumb_func
276         .type   PendSV_Handler, %function
277         .global PendSV_Handler
278         .global Sys_Switch
279 PendSV_Handler:
280         .fnstart
281         .cantunwind
282
283         BL      rt_pop_req
284
285 Sys_Switch:
286         LDR     R3,=os_tsk
287         LDMIA   R3!,{R1,R2}             /* os_tsk.run, os_tsk.new */
288         CMP     R1,R2
289         BEQ     Sys_Exit                /* no task switch */
290
291         SUBS    R3,#8
292
293         MRS     R0,PSP                  /* Read PSP */
294         SUBS    R0,R0,#32               /* Adjust Start Address */
295         STR     R0,[R1,#TCB_TSTACK]     /* Update os_tsk.run->tsk_stack */
296         STMIA   R0!,{R4-R7}             /* Save old context (R4-R7) */
297         MOV     R4,R8
298         MOV     R5,R9
299         MOV     R6,R10
300         MOV     R7,R11
301         STMIA   R0!,{R4-R7}             /* Save old context (R8-R11) */
302
303         PUSH    {R2,R3}
304         BL      rt_stk_check            /* Check for Stack overflow */
305         POP     {R2,R3}
306
307         STR     R2,[R3]                 /* os_tsk.run = os_tsk.new */
308
309         LDR     R0,[R2,#TCB_TSTACK]     /* os_tsk.new->tsk_stack */
310         ADDS    R0,R0,#16               /* Adjust Start Address */
311         LDMIA   R0!,{R4-R7}             /* Restore new Context (R8-R11) */
312         MOV     R8,R4
313         MOV     R9,R5
314         MOV     R10,R6
315         MOV     R11,R7
316         MSR     PSP,R0                  /* Write PSP */
317         SUBS    R0,R0,#32               /* Adjust Start Address */
318         LDMIA   R0!,{R4-R7}             /* Restore new Context (R4-R7) */
319
320 Sys_Exit:
321         MOVS    R0,#~0xFFFFFFFD         /* Set EXC_RETURN value */
322         MVNS    R0,R0
323         BX      R0                      /* RETI to Thread Mode, use PSP */
324
325         .fnend
326         .size   PendSV_Handler, .-PendSV_Handler
327
328
329 /*-------------------------- SysTick_Handler --------------------------------*/
330
331 #       void SysTick_Handler (void);
332
333         .thumb_func
334         .type   SysTick_Handler, %function
335         .global SysTick_Handler
336 SysTick_Handler:
337         .fnstart
338         .cantunwind
339
340         BL      rt_systick
341         B       Sys_Switch
342
343         .fnend
344         .size   SysTick_Handler, .-SysTick_Handler
345
346
347 /*-------------------------- OS_Tick_Handler --------------------------------*/
348
349 #       void OS_Tick_Handler (void);
350
351         .thumb_func
352         .type   OS_Tick_Handler, %function
353         .global OS_Tick_Handler
354 OS_Tick_Handler:
355         .fnstart
356         .cantunwind
357
358         BL      os_tick_irqack
359         BL      rt_systick
360         B       Sys_Switch
361
362         .fnend
363         .size   OS_Tick_Handler, .-OS_Tick_Handler
364
365
366         .end
367
368 /*----------------------------------------------------------------------------
369  * end of file
370  *---------------------------------------------------------------------------*/