source: rtems/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S @ 3e2647a7

4.115
Last change on this file since 3e2647a7 was 3e2647a7, checked in by Sebastian Huber <sebastian.huber@…>, on 12/23/14 at 13:18:06

powerpc: AltiVec? and FPU context support

Add AltiVec? and FPU support to the Context_Control in case we use the
e6500 multilib.

Add PPC_MULTILIB_ALTIVEC and PPC_MULTILIB_FPU multilib defines. Add
non-volatile AltiVec? and FPU context to Context_Control. Add save/restore of
non-volatile AltiVec? and FPU to _CPU_Context_switch(). Add save/restore
of volatile AltiVec? and FPU context to the exception code. Adjust data
cache optimizations for the new context and cache line size.

  • Property mode set to 100644
File size: 14.7 KB
RevLine 
[acc25ee]1/*  cpu_asm.s   1.1 - 95/12/04
2 *
3 *  This file contains the assembly code for the PowerPC implementation
4 *  of RTEMS.
5 *
6 *  Author:     Andrew Bray <andy@i-cubed.co.uk>
7 *
8 *  COPYRIGHT (c) 1995 by i-cubed ltd.
9 *
10 *  To anyone who acknowledges that this file is provided "AS IS"
11 *  without any express or implied warranty:
12 *      permission to use, copy, modify, and distribute this file
13 *      for any purpose is hereby granted without fee, provided that
14 *      the above copyright notice and this notice appears in all
15 *      copies, and that the name of i-cubed limited not be used in
16 *      advertising or publicity pertaining to distribution of the
17 *      software without specific, written prior permission.
18 *      i-cubed limited makes no representations about the suitability
19 *      of this software for any purpose.
20 *
21 *  Derived from c/src/exec/cpu/no_cpu/cpu_asm.c:
22 *
23 *  COPYRIGHT (c) 1989-1997.
24 *  On-Line Applications Research Corporation (OAR).
25 *
[3e2647a7]26 *  Copyright (c) 2011-2015 embedded brains GmbH
[fdd9de80]27 *
[acc25ee]28 *  The license and distribution terms for this file may in
29 *  the file LICENSE in this distribution or at
[c499856]30 *  http://www.rtems.org/license/LICENSE.
[acc25ee]31 */
32
[b49bcfc]33#include <rtems/asm.h>
[3e5a93cc]34#include <rtems/powerpc/powerpc.h>
[fbda4a8]35#include <rtems/score/percpu.h>
36#include <libcpu/powerpc-utility.h>
[fdd9de80]37#include <bspopts.h>
38
[1869bb7]39#ifdef BSP_USE_DATA_CACHE_BLOCK_TOUCH
[fdd9de80]40  #define DATA_CACHE_TOUCH(rega, regb) \
[1869bb7]41        dcbt rega, regb
[fdd9de80]42#else
43  #define DATA_CACHE_TOUCH(rega, regb)
[1869bb7]44#endif
45
[7c16e1a5]46#if BSP_DATA_CACHE_ENABLED && PPC_DEFAULT_CACHE_LINE_SIZE == 32
[fdd9de80]47  #define DATA_CACHE_ZERO_AND_TOUCH(reg, offset) \
[1869bb7]48        li reg, offset; dcbz reg, r3; DATA_CACHE_TOUCH(reg, r4)
49#else
50  #define DATA_CACHE_ZERO_AND_TOUCH(reg, offset)
[fdd9de80]51#endif
[acc25ee]52
[7c16e1a5]53#define PPC_CONTEXT_CACHE_LINE_0 (1 * PPC_DEFAULT_CACHE_LINE_SIZE)
54#define PPC_CONTEXT_CACHE_LINE_1 (2 * PPC_DEFAULT_CACHE_LINE_SIZE)
55#define PPC_CONTEXT_CACHE_LINE_2 (3 * PPC_DEFAULT_CACHE_LINE_SIZE)
56#define PPC_CONTEXT_CACHE_LINE_3 (4 * PPC_DEFAULT_CACHE_LINE_SIZE)
57#define PPC_CONTEXT_CACHE_LINE_4 (5 * PPC_DEFAULT_CACHE_LINE_SIZE)
[3e2647a7]58#define PPC_CONTEXT_CACHE_LINE_5 (6 * PPC_DEFAULT_CACHE_LINE_SIZE)
[1869bb7]59
[2e19bfd]60        BEGIN_CODE
61
62#if PPC_HAS_FPU == 1
63
[acc25ee]64/*
[2e19bfd]65 * Offsets for Context_Control_fp
[acc25ee]66 */
67
[3ddf3b5]68#if (PPC_HAS_DOUBLE==1)
69        .set    FP_SIZE,        8
70#define LDF     lfd
71#define STF     stfd
72#else
73        .set    FP_SIZE,        4
74#define LDF     lfs
75#define STF     stfs
76#endif
77
[acc25ee]78        .set    FP_0, 0
[3ddf3b5]79        .set    FP_1, (FP_0 + FP_SIZE)
80        .set    FP_2, (FP_1 + FP_SIZE)
81        .set    FP_3, (FP_2 + FP_SIZE)
82        .set    FP_4, (FP_3 + FP_SIZE)
83        .set    FP_5, (FP_4 + FP_SIZE)
84        .set    FP_6, (FP_5 + FP_SIZE)
85        .set    FP_7, (FP_6 + FP_SIZE)
86        .set    FP_8, (FP_7 + FP_SIZE)
87        .set    FP_9, (FP_8 + FP_SIZE)
88        .set    FP_10, (FP_9 + FP_SIZE)
89        .set    FP_11, (FP_10 + FP_SIZE)
90        .set    FP_12, (FP_11 + FP_SIZE)
91        .set    FP_13, (FP_12 + FP_SIZE)
92        .set    FP_14, (FP_13 + FP_SIZE)
93        .set    FP_15, (FP_14 + FP_SIZE)
94        .set    FP_16, (FP_15 + FP_SIZE)
95        .set    FP_17, (FP_16 + FP_SIZE)
96        .set    FP_18, (FP_17 + FP_SIZE)
97        .set    FP_19, (FP_18 + FP_SIZE)
98        .set    FP_20, (FP_19 + FP_SIZE)
99        .set    FP_21, (FP_20 + FP_SIZE)
100        .set    FP_22, (FP_21 + FP_SIZE)
101        .set    FP_23, (FP_22 + FP_SIZE)
102        .set    FP_24, (FP_23 + FP_SIZE)
103        .set    FP_25, (FP_24 + FP_SIZE)
104        .set    FP_26, (FP_25 + FP_SIZE)
105        .set    FP_27, (FP_26 + FP_SIZE)
106        .set    FP_28, (FP_27 + FP_SIZE)
107        .set    FP_29, (FP_28 + FP_SIZE)
108        .set    FP_30, (FP_29 + FP_SIZE)
109        .set    FP_31, (FP_30 + FP_SIZE)
110        .set    FP_FPSCR, (FP_31 + FP_SIZE)
[6128a4a]111
[acc25ee]112/*
113 *  _CPU_Context_save_fp_context
114 *
115 *  This routine is responsible for saving the FP context
116 *  at *fp_context_ptr.  If the point to load the FP context
117 *  from is changed then the pointer is modified by this routine.
118 *
119 *  Sometimes a macro implementation of this is in cpu.h which dereferences
120 *  the ** and a similarly named routine in this file is passed something
121 *  like a (Context_Control_fp *).  The general rule on making this decision
122 *  is to avoid writing assembly language.
123 */
124
125        ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
126        PUBLIC_PROC (_CPU_Context_save_fp)
127PROC (_CPU_Context_save_fp):
[368894f]128/* A FP context switch may occur in an ISR or exception handler when the FPU is not
129 * available. Therefore, we must explicitely enable it here!
130 */
131        mfmsr   r4
132        andi.   r5,r4,MSR_FP
133        bne     1f
134        ori     r5,r4,MSR_FP
135        mtmsr   r5
136        isync
1371:
[acc25ee]138        lwz     r3, 0(r3)
[3ddf3b5]139        STF     f0, FP_0(r3)
140        STF     f1, FP_1(r3)
141        STF     f2, FP_2(r3)
142        STF     f3, FP_3(r3)
143        STF     f4, FP_4(r3)
144        STF     f5, FP_5(r3)
145        STF     f6, FP_6(r3)
146        STF     f7, FP_7(r3)
147        STF     f8, FP_8(r3)
148        STF     f9, FP_9(r3)
149        STF     f10, FP_10(r3)
150        STF     f11, FP_11(r3)
151        STF     f12, FP_12(r3)
152        STF     f13, FP_13(r3)
153        STF     f14, FP_14(r3)
154        STF     f15, FP_15(r3)
155        STF     f16, FP_16(r3)
156        STF     f17, FP_17(r3)
157        STF     f18, FP_18(r3)
158        STF     f19, FP_19(r3)
159        STF     f20, FP_20(r3)
160        STF     f21, FP_21(r3)
161        STF     f22, FP_22(r3)
162        STF     f23, FP_23(r3)
163        STF     f24, FP_24(r3)
164        STF     f25, FP_25(r3)
165        STF     f26, FP_26(r3)
166        STF     f27, FP_27(r3)
167        STF     f28, FP_28(r3)
168        STF     f29, FP_29(r3)
169        STF     f30, FP_30(r3)
170        STF     f31, FP_31(r3)
[acc25ee]171        mffs    f2
[3ddf3b5]172        STF     f2, FP_FPSCR(r3)
[368894f]173        bne     1f
174        mtmsr   r4
175        isync
1761:
[acc25ee]177        blr
178
179/*
180 *  _CPU_Context_restore_fp_context
181 *
182 *  This routine is responsible for restoring the FP context
183 *  at *fp_context_ptr.  If the point to load the FP context
184 *  from is changed then the pointer is modified by this routine.
185 *
186 *  Sometimes a macro implementation of this is in cpu.h which dereferences
187 *  the ** and a similarly named routine in this file is passed something
188 *  like a (Context_Control_fp *).  The general rule on making this decision
189 *  is to avoid writing assembly language.
190 */
191
192        ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
193        PUBLIC_PROC (_CPU_Context_restore_fp)
194PROC (_CPU_Context_restore_fp):
195        lwz     r3, 0(r3)
[368894f]196/* A FP context switch may occur in an ISR or exception handler when the FPU is not
197 * available. Therefore, we must explicitely enable it here!
198 */
199        mfmsr   r4
200        andi.   r5,r4,MSR_FP
201        bne     1f
202        ori     r5,r4,MSR_FP
203        mtmsr   r5
204        isync
2051:
[3ddf3b5]206        LDF     f2, FP_FPSCR(r3)
[acc25ee]207        mtfsf   255, f2
[3ddf3b5]208        LDF     f0, FP_0(r3)
209        LDF     f1, FP_1(r3)
210        LDF     f2, FP_2(r3)
211        LDF     f3, FP_3(r3)
212        LDF     f4, FP_4(r3)
213        LDF     f5, FP_5(r3)
214        LDF     f6, FP_6(r3)
215        LDF     f7, FP_7(r3)
216        LDF     f8, FP_8(r3)
217        LDF     f9, FP_9(r3)
218        LDF     f10, FP_10(r3)
219        LDF     f11, FP_11(r3)
220        LDF     f12, FP_12(r3)
221        LDF     f13, FP_13(r3)
222        LDF     f14, FP_14(r3)
223        LDF     f15, FP_15(r3)
224        LDF     f16, FP_16(r3)
225        LDF     f17, FP_17(r3)
226        LDF     f18, FP_18(r3)
227        LDF     f19, FP_19(r3)
228        LDF     f20, FP_20(r3)
229        LDF     f21, FP_21(r3)
230        LDF     f22, FP_22(r3)
231        LDF     f23, FP_23(r3)
232        LDF     f24, FP_24(r3)
233        LDF     f25, FP_25(r3)
234        LDF     f26, FP_26(r3)
235        LDF     f27, FP_27(r3)
236        LDF     f28, FP_28(r3)
237        LDF     f29, FP_29(r3)
238        LDF     f30, FP_30(r3)
239        LDF     f31, FP_31(r3)
[368894f]240        bne     1f
241        mtmsr   r4
242        isync
2431:
[acc25ee]244        blr
[2e19bfd]245#endif /* PPC_HAS_FPU == 1 */
[acc25ee]246
247        ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
248        PUBLIC_PROC (_CPU_Context_switch)
249PROC (_CPU_Context_switch):
[1869bb7]250
251#ifdef BSP_USE_SYNC_IN_CONTEXT_SWITCH
[acc25ee]252        sync
253        isync
254#endif
255
[fdd9de80]256        /* Align to a cache line */
[7c16e1a5]257        clrrwi  r3, r3, PPC_DEFAULT_CACHE_LINE_POWER
258        clrrwi  r5, r4, PPC_DEFAULT_CACHE_LINE_POWER
[fdd9de80]259
260        DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_0)
[3e2647a7]261
262#if PPC_CONTEXT_CACHE_LINE_2 <= PPC_CONTEXT_VOLATILE_SIZE
[fdd9de80]263        DATA_CACHE_ZERO_AND_TOUCH(r11, PPC_CONTEXT_CACHE_LINE_1)
[3e2647a7]264#endif
[fdd9de80]265
266        /* Save context to r3 */
267
[fbda4a8]268        mfmsr   r6
269        mflr    r7
270        mfcr    r8
[057c294]271
[fdd9de80]272        /*
273         * We have to clear the reservation of the executing thread.  See also
[057c294]274         * Book E section 6.1.6.2 "Atomic Update Primitives".  Recent GCC
[fbda4a8]275         * versions use atomic operations in the C++ library for example.  On
276         * SMP configurations the reservation is cleared later during the
277         * context switch.
[fdd9de80]278         */
[057c294]279#if PPC_CONTEXT_OFFSET_GPR1 != PPC_CONTEXT_CACHE_LINE_0 \
280  || !BSP_DATA_CACHE_ENABLED \
[7c16e1a5]281  || PPC_DEFAULT_CACHE_LINE_SIZE != 32
[1869bb7]282        li      r10, PPC_CONTEXT_OFFSET_GPR1
[fdd9de80]283#endif
[fbda4a8]284#ifndef RTEMS_SMP
[057c294]285        stwcx.  r1, r3, r10
[fbda4a8]286#endif
[057c294]287
[1869bb7]288        stw     r1, PPC_CONTEXT_OFFSET_GPR1(r3)
[fbda4a8]289        stw     r6, PPC_CONTEXT_OFFSET_MSR(r3)
290        stw     r7, PPC_CONTEXT_OFFSET_LR(r3)
291        stw     r8, PPC_CONTEXT_OFFSET_CR(r3)
[1869bb7]292        PPC_GPR_STORE   r14, PPC_CONTEXT_OFFSET_GPR14(r3)
293        PPC_GPR_STORE   r15, PPC_CONTEXT_OFFSET_GPR15(r3)
294
295#if PPC_CONTEXT_OFFSET_GPR20 == PPC_CONTEXT_CACHE_LINE_2
296        DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_2)
297#endif
298
299        PPC_GPR_STORE   r16, PPC_CONTEXT_OFFSET_GPR16(r3)
300        PPC_GPR_STORE   r17, PPC_CONTEXT_OFFSET_GPR17(r3)
[fdd9de80]301
[1869bb7]302#if PPC_CONTEXT_OFFSET_GPR26 == PPC_CONTEXT_CACHE_LINE_2
[fdd9de80]303        DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_2)
[1869bb7]304#endif
[fdd9de80]305
[1869bb7]306        PPC_GPR_STORE   r18, PPC_CONTEXT_OFFSET_GPR18(r3)
307        PPC_GPR_STORE   r19, PPC_CONTEXT_OFFSET_GPR19(r3)
[fdd9de80]308
[1869bb7]309#if PPC_CONTEXT_OFFSET_GPR24 == PPC_CONTEXT_CACHE_LINE_3
[fdd9de80]310        DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_3)
[1869bb7]311#endif
[fdd9de80]312
[1869bb7]313        PPC_GPR_STORE   r20, PPC_CONTEXT_OFFSET_GPR20(r3)
314        PPC_GPR_STORE   r21, PPC_CONTEXT_OFFSET_GPR21(r3)
315        PPC_GPR_STORE   r22, PPC_CONTEXT_OFFSET_GPR22(r3)
316        PPC_GPR_STORE   r23, PPC_CONTEXT_OFFSET_GPR23(r3)
[fdd9de80]317
[1869bb7]318#if PPC_CONTEXT_OFFSET_GPR28 == PPC_CONTEXT_CACHE_LINE_4
[fdd9de80]319        DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_4)
[1869bb7]320#endif
[fdd9de80]321
[1869bb7]322        PPC_GPR_STORE   r24, PPC_CONTEXT_OFFSET_GPR24(r3)
323        PPC_GPR_STORE   r25, PPC_CONTEXT_OFFSET_GPR25(r3)
[3e2647a7]324
325#if PPC_CONTEXT_OFFSET_V22 == PPC_CONTEXT_CACHE_LINE_2
326        DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_2)
327#endif
328
[1869bb7]329        PPC_GPR_STORE   r26, PPC_CONTEXT_OFFSET_GPR26(r3)
330        PPC_GPR_STORE   r27, PPC_CONTEXT_OFFSET_GPR27(r3)
[fdd9de80]331
[1869bb7]332        PPC_GPR_STORE   r28, PPC_CONTEXT_OFFSET_GPR28(r3)
333        PPC_GPR_STORE   r29, PPC_CONTEXT_OFFSET_GPR29(r3)
334        PPC_GPR_STORE   r30, PPC_CONTEXT_OFFSET_GPR30(r3)
335        PPC_GPR_STORE   r31, PPC_CONTEXT_OFFSET_GPR31(r3)
[fdd9de80]336
[39a4574]337        stw     r2, PPC_CONTEXT_OFFSET_GPR2(r3)
338
[3e2647a7]339#ifdef PPC_MULTILIB_ALTIVEC
340        li      r9, PPC_CONTEXT_OFFSET_V20
341        stvx    v20, r3, r9
342        li      r9, PPC_CONTEXT_OFFSET_V21
343        stvx    v21, r3, r9
344
345#if PPC_CONTEXT_OFFSET_V26 == PPC_CONTEXT_CACHE_LINE_3
346        DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_3)
347#endif
348
349        li      r9, PPC_CONTEXT_OFFSET_V22
350        stvx    v22, r3, r9
351        li      r9, PPC_CONTEXT_OFFSET_V23
352        stvx    v23, r3, r9
353        li      r9, PPC_CONTEXT_OFFSET_V24
354        stvx    v24, r3, r9
355        li      r9, PPC_CONTEXT_OFFSET_V25
356        stvx    v25, r3, r9
357
358#if PPC_CONTEXT_OFFSET_V30 == PPC_CONTEXT_CACHE_LINE_4
359        DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_4)
360#endif
361
362        li      r9, PPC_CONTEXT_OFFSET_V26
363        stvx    v26, r3, r9
364        li      r9, PPC_CONTEXT_OFFSET_V27
365        stvx    v27, r3, r9
366        li      r9, PPC_CONTEXT_OFFSET_V28
367        stvx    v28, r3, r9
368        li      r9, PPC_CONTEXT_OFFSET_V29
369        stvx    v29, r3, r9
370
371#if PPC_CONTEXT_OFFSET_F17 == PPC_CONTEXT_CACHE_LINE_5
372        DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_5)
373#endif
374
375        li      r9, PPC_CONTEXT_OFFSET_V30
376        stvx    v30, r3, r9
377        li      r9, PPC_CONTEXT_OFFSET_V31
378        stvx    v31, r3, r9
379        mfvrsave        r9
380        stw     r9, PPC_CONTEXT_OFFSET_VRSAVE(r3)
381#endif
382
383#ifdef PPC_MULTILIB_FPU
384        stfd    f14, PPC_CONTEXT_OFFSET_F14(r3)
385        stfd    f15, PPC_CONTEXT_OFFSET_F15(r3)
386        stfd    f16, PPC_CONTEXT_OFFSET_F16(r3)
387        stfd    f17, PPC_CONTEXT_OFFSET_F17(r3)
388        stfd    f18, PPC_CONTEXT_OFFSET_F18(r3)
389        stfd    f19, PPC_CONTEXT_OFFSET_F19(r3)
390        stfd    f20, PPC_CONTEXT_OFFSET_F20(r3)
391        stfd    f21, PPC_CONTEXT_OFFSET_F21(r3)
392        stfd    f22, PPC_CONTEXT_OFFSET_F22(r3)
393        stfd    f23, PPC_CONTEXT_OFFSET_F23(r3)
394        stfd    f24, PPC_CONTEXT_OFFSET_F24(r3)
395        stfd    f25, PPC_CONTEXT_OFFSET_F25(r3)
396        stfd    f26, PPC_CONTEXT_OFFSET_F26(r3)
397        stfd    f27, PPC_CONTEXT_OFFSET_F27(r3)
398        stfd    f28, PPC_CONTEXT_OFFSET_F28(r3)
399        stfd    f29, PPC_CONTEXT_OFFSET_F29(r3)
400        stfd    f30, PPC_CONTEXT_OFFSET_F30(r3)
401        stfd    f31, PPC_CONTEXT_OFFSET_F31(r3)
402#endif
403
[38b59a6]404#ifdef RTEMS_SMP
[11b05f1]405        /* The executing context no longer executes on this processor */
[38b59a6]406        msync
[fbda4a8]407        li      r6, 0
408        stw     r6, PPC_CONTEXT_OFFSET_IS_EXECUTING(r3)
[fdd9de80]409
[fbda4a8]410check_is_executing:
[38b59a6]411
[fbda4a8]412        /* Check the is executing indicator of the heir context */
413        addi    r6, r5, PPC_CONTEXT_OFFSET_IS_EXECUTING
414        lwarx   r7, r0, r6
415        cmpwi   r7, 0
416        bne     check_thread_dispatch_necessary
417
418        /* Try to update the is executing indicator of the heir context */
419        li      r7, 1
420        stwcx.  r7, r0, r6
421        bne     check_thread_dispatch_necessary
[38b59a6]422        isync
423#endif
424
[fbda4a8]425        /* Restore context from r5 */
[11b05f1]426restore_context:
427
[3e2647a7]428#if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC)
[fbda4a8]429        mr      r14, r5
[1869bb7]430        .extern _CPU_Context_switch_altivec
431        bl      _CPU_Context_switch_altivec
[fbda4a8]432        mr      r5, r14
[1869bb7]433#endif
434
[fbda4a8]435        lwz     r1, PPC_CONTEXT_OFFSET_GPR1(r5)
436        lwz     r6, PPC_CONTEXT_OFFSET_MSR(r5)
437        lwz     r7, PPC_CONTEXT_OFFSET_LR(r5)
438        lwz     r8, PPC_CONTEXT_OFFSET_CR(r5)
[fdd9de80]439
[fbda4a8]440        PPC_GPR_LOAD    r14, PPC_CONTEXT_OFFSET_GPR14(r5)
441        PPC_GPR_LOAD    r15, PPC_CONTEXT_OFFSET_GPR15(r5)
[fdd9de80]442
443        DATA_CACHE_TOUCH(r0, r1)
444
[fbda4a8]445        PPC_GPR_LOAD    r16, PPC_CONTEXT_OFFSET_GPR16(r5)
446        PPC_GPR_LOAD    r17, PPC_CONTEXT_OFFSET_GPR17(r5)
447        PPC_GPR_LOAD    r18, PPC_CONTEXT_OFFSET_GPR18(r5)
448        PPC_GPR_LOAD    r19, PPC_CONTEXT_OFFSET_GPR19(r5)
[fdd9de80]449
[fbda4a8]450        PPC_GPR_LOAD    r20, PPC_CONTEXT_OFFSET_GPR20(r5)
451        PPC_GPR_LOAD    r21, PPC_CONTEXT_OFFSET_GPR21(r5)
452        PPC_GPR_LOAD    r22, PPC_CONTEXT_OFFSET_GPR22(r5)
453        PPC_GPR_LOAD    r23, PPC_CONTEXT_OFFSET_GPR23(r5)
[fdd9de80]454
[fbda4a8]455        PPC_GPR_LOAD    r24, PPC_CONTEXT_OFFSET_GPR24(r5)
456        PPC_GPR_LOAD    r25, PPC_CONTEXT_OFFSET_GPR25(r5)
457        PPC_GPR_LOAD    r26, PPC_CONTEXT_OFFSET_GPR26(r5)
458        PPC_GPR_LOAD    r27, PPC_CONTEXT_OFFSET_GPR27(r5)
[fdd9de80]459
[fbda4a8]460        PPC_GPR_LOAD    r28, PPC_CONTEXT_OFFSET_GPR28(r5)
461        PPC_GPR_LOAD    r29, PPC_CONTEXT_OFFSET_GPR29(r5)
462        PPC_GPR_LOAD    r30, PPC_CONTEXT_OFFSET_GPR30(r5)
463        PPC_GPR_LOAD    r31, PPC_CONTEXT_OFFSET_GPR31(r5)
[fdd9de80]464
[fbda4a8]465        lwz     r2, PPC_CONTEXT_OFFSET_GPR2(r5)
[39a4574]466
[3e2647a7]467#ifdef PPC_MULTILIB_ALTIVEC
468        li      r9, PPC_CONTEXT_OFFSET_V20
469        lvx     v20, r5, r9
470        li      r9, PPC_CONTEXT_OFFSET_V21
471        lvx     v21, r5, r9
472        li      r9, PPC_CONTEXT_OFFSET_V22
473        lvx     v22, r5, r9
474        li      r9, PPC_CONTEXT_OFFSET_V23
475        lvx     v23, r5, r9
476        li      r9, PPC_CONTEXT_OFFSET_V24
477        lvx     v24, r5, r9
478        li      r9, PPC_CONTEXT_OFFSET_V25
479        lvx     v25, r5, r9
480        li      r9, PPC_CONTEXT_OFFSET_V26
481        lvx     v26, r5, r9
482        li      r9, PPC_CONTEXT_OFFSET_V27
483        lvx     v27, r5, r9
484        li      r9, PPC_CONTEXT_OFFSET_V28
485        lvx     v28, r5, r9
486        li      r9, PPC_CONTEXT_OFFSET_V29
487        lvx     v29, r5, r9
488        li      r9, PPC_CONTEXT_OFFSET_V30
489        lvx     v30, r5, r9
490        li      r9, PPC_CONTEXT_OFFSET_V31
491        lvx     v31, r5, r9
492        lwz     r9, PPC_CONTEXT_OFFSET_VRSAVE(r5)
493        mtvrsave        r9
494#endif
495
496#ifdef PPC_MULTILIB_FPU
497        lfd     f14, PPC_CONTEXT_OFFSET_F14(r5)
498        lfd     f15, PPC_CONTEXT_OFFSET_F15(r5)
499        lfd     f16, PPC_CONTEXT_OFFSET_F16(r5)
500        lfd     f17, PPC_CONTEXT_OFFSET_F17(r5)
501        lfd     f18, PPC_CONTEXT_OFFSET_F18(r5)
502        lfd     f19, PPC_CONTEXT_OFFSET_F19(r5)
503        lfd     f20, PPC_CONTEXT_OFFSET_F20(r5)
504        lfd     f21, PPC_CONTEXT_OFFSET_F21(r5)
505        lfd     f22, PPC_CONTEXT_OFFSET_F22(r5)
506        lfd     f23, PPC_CONTEXT_OFFSET_F23(r5)
507        lfd     f24, PPC_CONTEXT_OFFSET_F24(r5)
508        lfd     f25, PPC_CONTEXT_OFFSET_F25(r5)
509        lfd     f26, PPC_CONTEXT_OFFSET_F26(r5)
510        lfd     f27, PPC_CONTEXT_OFFSET_F27(r5)
511        lfd     f28, PPC_CONTEXT_OFFSET_F28(r5)
512        lfd     f29, PPC_CONTEXT_OFFSET_F29(r5)
513        lfd     f30, PPC_CONTEXT_OFFSET_F30(r5)
514        lfd     f31, PPC_CONTEXT_OFFSET_F31(r5)
515#endif
516
[fbda4a8]517        mtcr    r8
518        mtlr    r7
519        mtmsr   r6
[fdd9de80]520
[1869bb7]521#ifdef BSP_USE_SYNC_IN_CONTEXT_SWITCH
522        isync
523#endif
524
[fdd9de80]525        blr
[acc25ee]526
527        PUBLIC_PROC (_CPU_Context_restore)
528PROC (_CPU_Context_restore):
[fdd9de80]529        /* Align to a cache line */
[7c16e1a5]530        clrrwi  r5, r3, PPC_DEFAULT_CACHE_LINE_POWER
[fdd9de80]531
[3e2647a7]532#if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC)
[1869bb7]533        li      r3, 0
534#endif
535
[fdd9de80]536        b       restore_context
[fbda4a8]537
538#ifdef RTEMS_SMP
539check_thread_dispatch_necessary:
540
541        GET_SELF_CPU_CONTROL    r6
542
543        /* Check if a thread dispatch is necessary */
544        lbz     r7, PER_CPU_DISPATCH_NEEDED(r6)
545        cmpwi   r7, 0
546        beq     check_is_executing
547
548        /* We have a new heir */
549
550        /* Clear the thread dispatch necessary flag */
551        li      r7, 0
552        stb     r7, PER_CPU_DISPATCH_NEEDED(r6)
553        msync
554
555        /* Read the executing and heir */
556        lwz     r7, PER_CPU_OFFSET_EXECUTING(r6)
557        lwz     r8, PER_CPU_OFFSET_HEIR(r6)
558
559        /* Calculate the heir context pointer */
560        sub     r7, r4, r7
561        add     r4, r8, r7
[7c16e1a5]562        clrrwi  r5, r4, PPC_DEFAULT_CACHE_LINE_POWER
[fbda4a8]563
564        /* Update the executing */
565        stw     r8, PER_CPU_OFFSET_EXECUTING(r6)
566
567        b       check_is_executing
568#endif
Note: See TracBrowser for help on using the repository browser.