xref: /Kernel-v10.6.2/portable/GCC/PPC440_Xilinx/portasm.S (revision ef7b253b56c9788077f5ecd6c9deb4021923d646)
1/*
2 * FreeRTOS Kernel V10.6.2
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
8 * this software and associated documentation files (the "Software"), to deal in
9 * the Software without restriction, including without limitation the rights to
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 * the Software, and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * https://www.FreeRTOS.org
25 * https://github.com/FreeRTOS
26 *
27 */
28
29#include "FreeRTOSConfig.h"
30
31    .extern pxCurrentTCB
32    .extern vTaskSwitchContext
33    .extern xTaskIncrementTick
34    .extern vPortISRHandler
35
36    .global vPortStartFirstTask
37    .global vPortYield
38    .global vPortTickISR
39    .global vPortISRWrapper
40    .global vPortSaveFPURegisters
41    .global vPortRestoreFPURegisters
42
43.set    BChainField, 0
44.set    NextLRField, BChainField + 4
45.set    MSRField,    NextLRField + 4
46.set    PCField,     MSRField    + 4
47.set    LRField,     PCField     + 4
48.set    CTRField,    LRField     + 4
49.set    XERField,    CTRField    + 4
50.set    CRField,     XERField    + 4
51.set    USPRG0Field, CRField     + 4
52.set    r0Field,     USPRG0Field + 4
53.set    r2Field,     r0Field     + 4
54.set    r3r31Field,  r2Field     + 4
55.set    IFrameSize,  r3r31Field  + ( ( 31 - 3 ) + 1 ) * 4
56
57
58.macro portSAVE_STACK_POINTER_AND_LR
59
60    /* Get the address of the TCB. */
61    xor     R0, R0, R0
62    addis   R2, R0, pxCurrentTCB@ha
63    lwz     R2, pxCurrentTCB@l( R2 )
64
65    /* Store the stack pointer into the TCB */
66    stw     SP, 0( R2 )
67
68    /* Save the link register */
69    stwu    R1, -24( R1 )
70    mflr    R0
71    stw     R31, 20( R1 )
72    stw     R0, 28( R1 )
73    mr      R31, r1
74
75.endm
76
77.macro portRESTORE_STACK_POINTER_AND_LR
78
79    /* Restore the link register */
80    lwz     R11, 0( R1 )
81    lwz     R0, 4( R11 )
82    mtlr    R0
83    lwz     R31, -4( R11 )
84    mr      R1, R11
85
86    /* Get the address of the TCB. */
87    xor     R0, R0, R0
88    addis   SP, R0, pxCurrentTCB@ha
89    lwz     SP, pxCurrentTCB@l( R1 )
90
91    /* Get the task stack pointer from the TCB. */
92    lwz     SP, 0( SP )
93
94.endm
95
96
97vPortStartFirstTask:
98
99    /* Get the address of the TCB. */
100    xor     R0, R0, R0
101    addis   SP, R0, pxCurrentTCB@ha
102    lwz     SP, pxCurrentTCB@l( SP )
103
104    /* Get the task stack pointer from the TCB. */
105    lwz     SP, 0( SP )
106
107    /* Restore MSR register to SRR1. */
108    lwz     R0, MSRField(R1)
109    mtsrr1  R0
110
111    /* Restore current PC location to SRR0. */
112    lwz     R0, PCField(R1)
113    mtsrr0  R0
114
115    /* Save  USPRG0 register */
116    lwz     R0, USPRG0Field(R1)
117    mtspr   0x100,R0
118
119    /* Restore Condition register */
120    lwz     R0, CRField(R1)
121    mtcr    R0
122
123    /* Restore Fixed Point Exception register */
124    lwz     R0, XERField(R1)
125    mtxer   R0
126
127    /* Restore Counter register */
128    lwz     R0, CTRField(R1)
129    mtctr   R0
130
131    /* Restore Link register */
132    lwz     R0, LRField(R1)
133    mtlr    R0
134
135    /* Restore remaining GPR registers. */
136    lmw R3,r3r31Field(R1)
137
138    /* Restore r0 and r2. */
139    lwz     R0, r0Field(R1)
140    lwz     R2, r2Field(R1)
141
142    /* Remove frame from stack */
143    addi    R1,R1,IFrameSize
144
145    /* Return into the first task */
146    rfi
147
148
149
150vPortYield:
151
152    portSAVE_STACK_POINTER_AND_LR
153    bl vTaskSwitchContext
154    portRESTORE_STACK_POINTER_AND_LR
155    blr
156
157vPortTickISR:
158
159    portSAVE_STACK_POINTER_AND_LR
160    bl xTaskIncrementTick
161
162    #if configUSE_PREEMPTION == 1
163        bl vTaskSwitchContext
164    #endif
165
166    /* Clear the interrupt */
167    lis     R0, 2048
168    mttsr   R0
169
170    portRESTORE_STACK_POINTER_AND_LR
171    blr
172
173vPortISRWrapper:
174
175    portSAVE_STACK_POINTER_AND_LR
176    bl vPortISRHandler
177    portRESTORE_STACK_POINTER_AND_LR
178    blr
179
180#if configUSE_FPU == 1
181
182vPortSaveFPURegisters:
183
184    /* Enable APU and mark FPU as present. */
185    mfmsr   r0
186    xor     r30, r30, r30
187    oris    r30, r30, 512
188    ori     r30, r30, 8192
189    or      r0, r0, r30
190    mtmsr   r0
191
192#ifdef USE_DP_FPU
193
194    /* Buffer address is in r3.  Save each flop register into an offset from
195    this buffer address. */
196    stfd    f0, 0(r3)
197    stfd    f1, 8(r3)
198    stfd    f2, 16(r3)
199    stfd    f3, 24(r3)
200    stfd    f4, 32(r3)
201    stfd    f5, 40(r3)
202    stfd    f6, 48(r3)
203    stfd    f7, 56(r3)
204    stfd    f8, 64(r3)
205    stfd    f9, 72(r3)
206    stfd    f10, 80(r3)
207    stfd    f11, 88(r3)
208    stfd    f12, 96(r3)
209    stfd    f13, 104(r3)
210    stfd    f14, 112(r3)
211    stfd    f15, 120(r3)
212    stfd    f16, 128(r3)
213    stfd    f17, 136(r3)
214    stfd    f18, 144(r3)
215    stfd    f19, 152(r3)
216    stfd    f20, 160(r3)
217    stfd    f21, 168(r3)
218    stfd    f22, 176(r3)
219    stfd    f23, 184(r3)
220    stfd    f24, 192(r3)
221    stfd    f25, 200(r3)
222    stfd    f26, 208(r3)
223    stfd    f27, 216(r3)
224    stfd    f28, 224(r3)
225    stfd    f29, 232(r3)
226    stfd    f30, 240(r3)
227    stfd    f31, 248(r3)
228
229    /* Also save the FPSCR. */
230    mffs    f31
231    stfs    f31, 256(r3)
232
233#else
234
235    /* Buffer address is in r3.  Save each flop register into an offset from
236    this buffer address. */
237    stfs    f0, 0(r3)
238    stfs    f1, 4(r3)
239    stfs    f2, 8(r3)
240    stfs    f3, 12(r3)
241    stfs    f4, 16(r3)
242    stfs    f5, 20(r3)
243    stfs    f6, 24(r3)
244    stfs    f7, 28(r3)
245    stfs    f8, 32(r3)
246    stfs    f9, 36(r3)
247    stfs    f10, 40(r3)
248    stfs    f11, 44(r3)
249    stfs    f12, 48(r3)
250    stfs    f13, 52(r3)
251    stfs    f14, 56(r3)
252    stfs    f15, 60(r3)
253    stfs    f16, 64(r3)
254    stfs    f17, 68(r3)
255    stfs    f18, 72(r3)
256    stfs    f19, 76(r3)
257    stfs    f20, 80(r3)
258    stfs    f21, 84(r3)
259    stfs    f22, 88(r3)
260    stfs    f23, 92(r3)
261    stfs    f24, 96(r3)
262    stfs    f25, 100(r3)
263    stfs    f26, 104(r3)
264    stfs    f27, 108(r3)
265    stfs    f28, 112(r3)
266    stfs    f29, 116(r3)
267    stfs    f30, 120(r3)
268    stfs    f31, 124(r3)
269
270    /* Also save the FPSCR. */
271    mffs    f31
272    stfs    f31, 128(r3)
273
274#endif
275
276    blr
277
278#endif /* configUSE_FPU. */
279
280
281#if configUSE_FPU == 1
282
283vPortRestoreFPURegisters:
284
285    /* Enable APU and mark FPU as present. */
286    mfmsr   r0
287    xor     r30, r30, r30
288    oris    r30, r30, 512
289    ori     r30, r30, 8192
290    or      r0, r0, r30
291    mtmsr   r0
292
293#ifdef USE_DP_FPU
294
295    /* Buffer address is in r3.  Restore each flop register from an offset
296    into this buffer.
297
298    First the FPSCR. */
299    lfs     f31, 256(r3)
300    mtfsf   f31, 7
301
302    lfd     f0, 0(r3)
303    lfd     f1, 8(r3)
304    lfd     f2, 16(r3)
305    lfd     f3, 24(r3)
306    lfd     f4, 32(r3)
307    lfd     f5, 40(r3)
308    lfd     f6, 48(r3)
309    lfd     f7, 56(r3)
310    lfd     f8, 64(r3)
311    lfd     f9, 72(r3)
312    lfd     f10, 80(r3)
313    lfd     f11, 88(r3)
314    lfd     f12, 96(r3)
315    lfd     f13, 104(r3)
316    lfd     f14, 112(r3)
317    lfd     f15, 120(r3)
318    lfd     f16, 128(r3)
319    lfd     f17, 136(r3)
320    lfd     f18, 144(r3)
321    lfd     f19, 152(r3)
322    lfd     f20, 160(r3)
323    lfd     f21, 168(r3)
324    lfd     f22, 176(r3)
325    lfd     f23, 184(r3)
326    lfd     f24, 192(r3)
327    lfd     f25, 200(r3)
328    lfd     f26, 208(r3)
329    lfd     f27, 216(r3)
330    lfd     f28, 224(r3)
331    lfd     f29, 232(r3)
332    lfd     f30, 240(r3)
333    lfd     f31, 248(r3)
334
335#else
336
337    /* Buffer address is in r3.  Restore each flop register from an offset
338    into this buffer.
339
340    First the FPSCR. */
341    lfs     f31, 128(r3)
342    mtfsf   f31, 7
343
344    lfs     f0, 0(r3)
345    lfs     f1, 4(r3)
346    lfs     f2, 8(r3)
347    lfs     f3, 12(r3)
348    lfs     f4, 16(r3)
349    lfs     f5, 20(r3)
350    lfs     f6, 24(r3)
351    lfs     f7, 28(r3)
352    lfs     f8, 32(r3)
353    lfs     f9, 36(r3)
354    lfs     f10, 40(r3)
355    lfs     f11, 44(r3)
356    lfs     f12, 48(r3)
357    lfs     f13, 52(r3)
358    lfs     f14, 56(r3)
359    lfs     f15, 60(r3)
360    lfs     f16, 64(r3)
361    lfs     f17, 68(r3)
362    lfs     f18, 72(r3)
363    lfs     f19, 76(r3)
364    lfs     f20, 80(r3)
365    lfs     f21, 84(r3)
366    lfs     f22, 88(r3)
367    lfs     f23, 92(r3)
368    lfs     f24, 96(r3)
369    lfs     f25, 100(r3)
370    lfs     f26, 104(r3)
371    lfs     f27, 108(r3)
372    lfs     f28, 112(r3)
373    lfs     f29, 116(r3)
374    lfs     f30, 120(r3)
375    lfs     f31, 124(r3)
376
377#endif
378
379    blr
380
381#endif /* configUSE_FPU. */
382