]> begriffs open source - freertos/blob - portable/CCS/ARM_Cortex-R4/portASM.asm
Change XCC to xClang for XCore ports (#332)
[freertos] / portable / CCS / ARM_Cortex-R4 / portASM.asm
1 ;/*
2 ; * FreeRTOS Kernel V10.4.3
3 ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4 ; *
5 ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
6 ; * this software and associated documentation files (the "Software"), to deal in
7 ; * the Software without restriction, including without limitation the rights to
8 ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 ; * the Software, and to permit persons to whom the Software is furnished to do so,
10 ; * subject to the following conditions:
11 ; *
12 ; * The above copyright notice and this permission notice shall be included in all
13 ; * copies or substantial portions of the Software.
14 ; *
15 ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 ; *
22 ; * https://www.FreeRTOS.org
23 ; * https://github.com/FreeRTOS
24 ; *
25 ; * 1 tab == 4 spaces!
26 ; */
27
28         .text
29         .arm
30         .ref vTaskSwitchContext
31         .ref xTaskIncrementTick
32         .ref ulTaskHasFPUContext
33                 .ref pxCurrentTCB
34
35 ;/*-----------------------------------------------------------*/
36 ;
37 ; Save Task Context
38 ;
39 portSAVE_CONTEXT .macro
40                 DSB
41
42                 ; Push R0 as we are going to use it
43                 STMDB   SP!, {R0}
44
45                 ; Set R0 to point to the task stack pointer.
46                 STMDB   SP,{SP}^
47                 SUB     SP, SP, #4
48                 LDMIA   SP!,{R0}
49
50                 ; Push the return address onto the stack.
51                 STMDB   R0!, {LR}
52
53                 ; Now LR has been saved, it can be used instead of R0.
54                 MOV     LR, R0
55
56                 ; Pop R0 so it can be saved onto the task stack.
57                 LDMIA   SP!, {R0}
58
59                 ; Push all the system mode registers onto the task stack.
60                 STMDB   LR,{R0-LR}^
61                 SUB     LR, LR, #60
62
63                 ; Push the SPSR onto the task stack.
64                 MRS     R0, SPSR
65                 STMDB   LR!, {R0}
66
67     .if (__TI_VFP_SUPPORT__)
68                 ;Determine if the task maintains an FPU context.
69                 LDR     R0, ulFPUContextConst
70                 LDR     R0, [R0]
71
72                 ; Test the flag
73                 CMP             R0, #0
74
75                 ; If the task is not using a floating point context then skip the
76                 ; saving of the FPU registers.
77                 BEQ             $+16
78                 FSTMDBD LR!, {D0-D15}
79                 FMRX    R1,  FPSCR
80                 STMFD   LR!, {R1}
81
82                 ; Save the flag
83                 STMDB   LR!, {R0}
84         .endif
85
86                 ; Store the new top of stack for the task.
87                 LDR     R0, pxCurrentTCBConst
88                 LDR     R0, [R0]
89                 STR     LR, [R0]
90
91         .endm
92
93 ;/*-----------------------------------------------------------*/
94 ;
95 ; Restore Task Context
96 ;
97 portRESTORE_CONTEXT .macro
98                 LDR             R0, pxCurrentTCBConst
99                 LDR             R0, [R0]
100                 LDR             LR, [R0]
101
102         .if (__TI_VFP_SUPPORT__)
103                 ; The floating point context flag is the first thing on the stack.
104                 LDR             R0, ulFPUContextConst
105                 LDMFD   LR!, {R1}
106                 STR             R1, [R0]
107
108                 ; Test the flag
109                 CMP             R1, #0
110
111                 ; If the task is not using a floating point context then skip the
112                 ; VFP register loads.
113                 BEQ             $+16
114
115                 ; Restore the floating point context.
116                 LDMFD   LR!, {R0}
117                 FLDMIAD LR!, {D0-D15}
118                 FMXR    FPSCR, R0
119         .endif
120
121                 ; Get the SPSR from the stack.
122                 LDMFD   LR!, {R0}
123                 MSR             SPSR_CSXF, R0
124
125                 ; Restore all system mode registers for the task.
126                 LDMFD   LR, {R0-R14}^
127
128                 ; Restore the return address.
129                 LDR             LR, [LR, #+60]
130
131                 ; And return - correcting the offset in the LR to obtain the
132                 ; correct address.
133                 SUBS    PC, LR, #4
134         .endm
135
136 ;/*-----------------------------------------------------------*/
137 ; Start the first task by restoring its context.
138
139         .def vPortStartFirstTask
140
141 vPortStartFirstTask:
142         portRESTORE_CONTEXT
143
144 ;/*-----------------------------------------------------------*/
145 ; Yield to another task.
146
147         .def vPortYieldProcessor
148
149 vPortYieldProcessor:
150                 ; Within an IRQ ISR the link register has an offset from the true return
151                 ; address.  SWI doesn't do this. Add the offset manually so the ISR
152                 ; return code can be used.
153         ADD     LR, LR, #4
154
155         ; First save the context of the current task.
156         portSAVE_CONTEXT
157
158         ; Select the next task to execute. */
159         BL      vTaskSwitchContext
160
161         ; Restore the context of the task selected to execute.
162         portRESTORE_CONTEXT
163
164 ;/*-----------------------------------------------------------*/
165 ; Yield to another task from within the FreeRTOS API
166
167                 .def vPortYeildWithinAPI
168
169 vPortYeildWithinAPI:
170                 ; Save the context of the current task.
171
172         portSAVE_CONTEXT
173                 ; Clear SSI flag.
174                 MOVW    R0, #0xFFF4
175                 MOVT    R0, #0xFFFF
176                 LDR     R0, [R0]
177
178                 ; Select the next task to execute. */
179         BL      vTaskSwitchContext
180
181         ; Restore the context of the task selected to execute.
182         portRESTORE_CONTEXT
183
184 ;/*-----------------------------------------------------------*/
185 ; Preemptive Tick
186
187         .def vPortPreemptiveTick
188
189 vPortPreemptiveTick:
190
191                 ; Save the context of the current task.
192         portSAVE_CONTEXT
193
194         ; Clear interrupt flag
195         MOVW    R0, #0xFC88
196         MOVT    R0, #0xFFFF
197         MOV     R1, #1
198         STR     R1, [R0]
199
200         ; Increment the tick count, making any adjustments to the blocked lists
201         ; that may be necessary.
202         BL      xTaskIncrementTick
203
204         ; Select the next task to execute.
205         CMP     R0, #0
206         BLNE    vTaskSwitchContext
207
208         ; Restore the context of the task selected to execute.
209         portRESTORE_CONTEXT
210
211 ;-------------------------------------------------------------------------------
212
213         .if (__TI_VFP_SUPPORT__)
214
215                 .def vPortInitialiseFPSCR
216
217 vPortInitialiseFPSCR:
218
219                 MOV             R0, #0
220                 FMXR    FPSCR, R0
221                 BX              LR
222
223         .endif ;__TI_VFP_SUPPORT__
224
225
226 pxCurrentTCBConst       .word   pxCurrentTCB
227 ulFPUContextConst       .word   ulTaskHasFPUContext
228 ;-------------------------------------------------------------------------------
229