]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / rtos / rtx / TARGET_CORTEX_M / TARGET_M0P / TOOLCHAIN_ARM / HAL_CM0.c
1 /*----------------------------------------------------------------------------
2  *      RL-ARM - RTX
3  *----------------------------------------------------------------------------
4  *      Name:    HAL_CM0.C
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 #include "rt_TypeDef.h"
36 #include "RTX_Conf.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
50 __asm void rt_set_PSP (U32 stack) {
51         MSR     PSP,R0
52         BX      LR
53 }
54
55
56 /*--------------------------- rt_get_PSP ------------------------------------*/
57
58 __asm U32 rt_get_PSP (void) {
59         MRS     R0,PSP
60         BX      LR
61 }
62
63
64 /*--------------------------- os_set_env ------------------------------------*/
65
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         BNE     PrivilegedE
74         MOVS    R0,#0x03                ; Unprivileged Thread mode, use PSP
75         MSR     CONTROL,R0
76         BX      LR
77 PrivilegedE
78         MOVS    R0,#0x02                ; Privileged Thread mode, use PSP
79         MSR     CONTROL,R0
80         BX      LR
81
82         ALIGN
83 }
84
85
86 /*--------------------------- _alloc_box ------------------------------------*/
87
88 __asm void *_alloc_box (void *box_mem) {
89    /* Function wrapper for Unprivileged/Privileged mode. */
90         LDR     R3,=__cpp(rt_alloc_box)
91         MOV     R12,R3
92         MRS     R3,IPSR
93         LSLS    R3,#24
94         BNE     PrivilegedA
95         MRS     R3,CONTROL
96         LSLS    R3,#31
97         BEQ     PrivilegedA
98         SVC     0
99         BX      LR
100 PrivilegedA
101         BX      R12
102
103         ALIGN
104 }
105
106
107 /*--------------------------- _free_box -------------------------------------*/
108
109 __asm int _free_box (void *box_mem, void *box) {
110    /* Function wrapper for Unprivileged/Privileged mode. */
111         LDR     R3,=__cpp(rt_free_box)
112         MOV     R12,R3
113         MRS     R3,IPSR
114         LSLS    R3,#24
115         BNE     PrivilegedF
116         MRS     R3,CONTROL
117         LSLS    R3,#31
118         BEQ     PrivilegedF
119         SVC     0
120         BX      LR
121 PrivilegedF
122         BX      R12
123
124         ALIGN
125 }
126
127
128 /*-------------------------- SVC_Handler ------------------------------------*/
129
130 __asm void SVC_Handler (void) {
131         PRESERVE8
132
133         IMPORT  SVC_Count
134         IMPORT  SVC_Table
135         IMPORT  rt_stk_check
136
137         MRS     R0,PSP                  ; Read PSP
138         LDR     R1,[R0,#24]             ; Read Saved PC from Stack
139         SUBS    R1,R1,#2                ; Point to SVC Instruction
140         LDRB    R1,[R1]                 ; Load SVC Number
141         CMP     R1,#0
142         BNE     SVC_User                ; User SVC Number > 0
143
144         MOV     LR,R4
145         LDMIA   R0,{R0-R3,R4}           ; Read R0-R3,R12 from stack
146         MOV     R12,R4
147         MOV     R4,LR
148         BLX     R12                     ; Call SVC Function
149
150         MRS     R3,PSP                  ; Read PSP
151         STMIA   R3!,{R0-R2}             ; Store return values
152
153         LDR     R3,=__cpp(&os_tsk)
154         LDMIA   R3!,{R1,R2}             ; os_tsk.run, os_tsk.new
155         CMP     R1,R2
156         BEQ     SVC_Exit                ; no task switch
157
158         SUBS    R3,#8
159         CMP     R1,#0                   ; Runtask deleted?
160         BEQ     SVC_Next
161
162         MRS     R0,PSP                  ; Read PSP
163         SUBS    R0,R0,#32               ; Adjust Start Address
164         STR     R0,[R1,#TCB_TSTACK]     ; Update os_tsk.run->tsk_stack
165         STMIA   R0!,{R4-R7}             ; Save old context (R4-R7)
166         MOV     R4,R8
167         MOV     R5,R9
168         MOV     R6,R10
169         MOV     R7,R11
170         STMIA   R0!,{R4-R7}             ; Save old context (R8-R11)
171
172         PUSH    {R2,R3}
173         BL      rt_stk_check            ; Check for Stack overflow
174         POP     {R2,R3}
175
176 SVC_Next
177         STR     R2,[R3]                 ; os_tsk.run = os_tsk.new
178
179         LDR     R0,[R2,#TCB_TSTACK]     ; os_tsk.new->tsk_stack
180         ADDS    R0,R0,#16               ; Adjust Start Address
181         LDMIA   R0!,{R4-R7}             ; Restore new Context (R8-R11)
182         MOV     R8,R4
183         MOV     R9,R5
184         MOV     R10,R6
185         MOV     R11,R7
186         MSR     PSP,R0                  ; Write PSP
187         SUBS    R0,R0,#32               ; Adjust Start Address
188         LDMIA   R0!,{R4-R7}             ; Restore new Context (R4-R7)
189
190 SVC_Exit
191         MOVS    R0,#:NOT:0xFFFFFFFD     ; Set EXC_RETURN value
192         MVNS    R0,R0
193         BX      R0                      ; RETI to Thread Mode, use PSP
194
195         /*------------------- User SVC ------------------------------*/
196
197 SVC_User
198         PUSH    {R4,LR}                 ; Save Registers
199         LDR     R2,=SVC_Count
200         LDR     R2,[R2]
201         CMP     R1,R2
202         BHI     SVC_Done                ; Overflow
203
204         LDR     R4,=SVC_Table-4
205         LSLS    R1,R1,#2
206         LDR     R4,[R4,R1]              ; Load SVC Function Address
207         MOV     LR,R4
208
209         LDMIA   R0,{R0-R3,R4}           ; Read R0-R3,R12 from stack
210         MOV     R12,R4
211         BLX     LR                      ; Call SVC Function
212
213         MRS     R4,PSP                  ; Read PSP
214         STMIA   R4!,{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         BL      __cpp(rt_pop_req)
228
229 Sys_Switch
230         LDR     R3,=__cpp(&os_tsk)
231         LDMIA   R3!,{R1,R2}             ; os_tsk.run, os_tsk.new
232         CMP     R1,R2
233         BEQ     Sys_Exit                ; no task switch
234
235         SUBS    R3,#8
236
237         MRS     R0,PSP                  ; Read PSP
238         SUBS    R0,R0,#32               ; Adjust Start Address
239         STR     R0,[R1,#TCB_TSTACK]     ; Update os_tsk.run->tsk_stack
240         STMIA   R0!,{R4-R7}             ; Save old context (R4-R7)
241         MOV     R4,R8
242         MOV     R5,R9
243         MOV     R6,R10
244         MOV     R7,R11
245         STMIA   R0!,{R4-R7}             ; Save old context (R8-R11)
246
247         PUSH    {R2,R3}
248         BL      rt_stk_check            ; Check for Stack overflow
249         POP     {R2,R3}
250
251         STR     R2,[R3]                 ; os_tsk.run = os_tsk.new
252
253         LDR     R0,[R2,#TCB_TSTACK]     ; os_tsk.new->tsk_stack
254         ADDS    R0,R0,#16               ; Adjust Start Address
255         LDMIA   R0!,{R4-R7}             ; Restore new Context (R8-R11)
256         MOV     R8,R4
257         MOV     R9,R5
258         MOV     R10,R6
259         MOV     R11,R7
260         MSR     PSP,R0                  ; Write PSP
261         SUBS    R0,R0,#32               ; Adjust Start Address
262         LDMIA   R0!,{R4-R7}             ; Restore new Context (R4-R7)
263
264 Sys_Exit
265         MOVS    R0,#:NOT:0xFFFFFFFD     ; Set EXC_RETURN value
266         MVNS    R0,R0
267         BX      R0                      ; RETI to Thread Mode, use PSP
268
269         ALIGN
270 }
271
272
273 /*-------------------------- SysTick_Handler --------------------------------*/
274
275 __asm void SysTick_Handler (void) {
276         PRESERVE8
277
278         BL      __cpp(rt_systick)
279         B       Sys_Switch
280
281         ALIGN
282 }
283
284
285 /*-------------------------- OS_Tick_Handler --------------------------------*/
286
287 __asm void OS_Tick_Handler (void) {
288         PRESERVE8
289
290         BL      __cpp(os_tick_irqack)
291         BL      __cpp(rt_systick)
292         B       Sys_Switch
293
294         ALIGN
295 }
296
297
298 /*----------------------------------------------------------------------------
299  * end of file
300  *---------------------------------------------------------------------------*/
301