[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) |
---|
| 127 | PROC (_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 |
---|
| 137 | 1: |
---|
[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 |
---|
| 176 | 1: |
---|
[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) |
---|
| 194 | PROC (_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 |
---|
| 205 | 1: |
---|
[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 |
---|
| 243 | 1: |
---|
[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) |
---|
| 249 | PROC (_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] | 410 | check_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] | 426 | restore_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) |
---|
| 528 | PROC (_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 |
---|
| 539 | check_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 |
---|