| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: cpuswitch.S,v 1.84 2014/06/15 02:27:15 ozaki-r Exp $ */ | | 1 | /* $NetBSD: cpuswitch.S,v 1.84.2.1 2015/03/27 11:27:39 martin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright 2003 Wasabi Systems, Inc. | | 4 | * Copyright 2003 Wasabi Systems, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Written by Steve C. Woodford for Wasabi Systems, Inc. | | 7 | * Written by Steve C. Woodford for Wasabi Systems, Inc. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -77,27 +77,27 @@ | | | @@ -77,27 +77,27 @@ |
77 | * Created : 15/10/94 | | 77 | * Created : 15/10/94 |
78 | */ | | 78 | */ |
79 | | | 79 | |
80 | #include "opt_armfpe.h" | | 80 | #include "opt_armfpe.h" |
81 | #include "opt_arm32_pmap.h" | | 81 | #include "opt_arm32_pmap.h" |
82 | #include "opt_multiprocessor.h" | | 82 | #include "opt_multiprocessor.h" |
83 | #include "opt_cpuoptions.h" | | 83 | #include "opt_cpuoptions.h" |
84 | #include "opt_lockdebug.h" | | 84 | #include "opt_lockdebug.h" |
85 | | | 85 | |
86 | #include "assym.h" | | 86 | #include "assym.h" |
87 | #include <arm/asm.h> | | 87 | #include <arm/asm.h> |
88 | #include <arm/locore.h> | | 88 | #include <arm/locore.h> |
89 | | | 89 | |
90 | RCSID("$NetBSD: cpuswitch.S,v 1.84 2014/06/15 02:27:15 ozaki-r Exp $") | | 90 | RCSID("$NetBSD: cpuswitch.S,v 1.84.2.1 2015/03/27 11:27:39 martin Exp $") |
91 | | | 91 | |
92 | /* LINTSTUB: include <sys/param.h> */ | | 92 | /* LINTSTUB: include <sys/param.h> */ |
93 | | | 93 | |
94 | #undef IRQdisable | | 94 | #undef IRQdisable |
95 | #undef IRQenable | | 95 | #undef IRQenable |
96 | | | 96 | |
97 | /* | | 97 | /* |
98 | * New experimental definitions of IRQdisable and IRQenable | | 98 | * New experimental definitions of IRQdisable and IRQenable |
99 | * These keep FIQ's enabled since FIQ's are special. | | 99 | * These keep FIQ's enabled since FIQ's are special. |
100 | */ | | 100 | */ |
101 | | | 101 | |
102 | #ifdef _ARM_ARCH_6 | | 102 | #ifdef _ARM_ARCH_6 |
103 | #define IRQdisable cpsid i | | 103 | #define IRQdisable cpsid i |
| @@ -127,210 +127,211 @@ | | | @@ -127,210 +127,211 @@ |
127 | * r0 'struct lwp *' of the current LWP (or NULL if exiting) | | 127 | * r0 'struct lwp *' of the current LWP (or NULL if exiting) |
128 | * r1 'struct lwp *' of the LWP to switch to | | 128 | * r1 'struct lwp *' of the LWP to switch to |
129 | * r2 returning | | 129 | * r2 returning |
130 | */ | | 130 | */ |
131 | ENTRY(cpu_switchto) | | 131 | ENTRY(cpu_switchto) |
132 | mov ip, sp | | 132 | mov ip, sp |
133 | push {r4-r7, ip, lr} | | 133 | push {r4-r7, ip, lr} |
134 | | | 134 | |
135 | /* move lwps into caller saved registers */ | | 135 | /* move lwps into caller saved registers */ |
136 | mov r6, r1 | | 136 | mov r6, r1 |
137 | mov r4, r0 | | 137 | mov r4, r0 |
138 | | | 138 | |
139 | #ifdef TPIDRPRW_IS_CURCPU | | 139 | #ifdef TPIDRPRW_IS_CURCPU |
140 | GET_CURCPU(r3) | | 140 | GET_CURCPU(r5) |
141 | #elif defined(TPIDRPRW_IS_CURLWP) | | 141 | #elif defined(TPIDRPRW_IS_CURLWP) |
142 | mrc p15, 0, r0, c13, c0, 4 /* get old lwp (r4 maybe 0) */ | | 142 | mrc p15, 0, r0, c13, c0, 4 /* get old lwp (r4 maybe 0) */ |
143 | ldr r3, [r0, #(L_CPU)] /* get cpu from old lwp */ | | 143 | ldr r5, [r0, #(L_CPU)] /* get cpu from old lwp */ |
144 | #elif !defined(MULTIPROCESSOR) | | 144 | #elif !defined(MULTIPROCESSOR) |
145 | ldr r3, [r6, #L_CPU] /* get cpu from new lwp */ | | 145 | ldr r5, [r6, #L_CPU] /* get cpu from new lwp */ |
146 | #else | | 146 | #else |
147 | #error curcpu() method not defined | | 147 | #error curcpu() method not defined |
148 | #endif | | 148 | #endif |
149 | | | 149 | |
150 | /* rem: r3 = curcpu() */ | | | |
151 | /* rem: r4 = old lwp */ | | 150 | /* rem: r4 = old lwp */ |
| | | 151 | /* rem: r5 = curcpu() */ |
152 | /* rem: r6 = new lwp */ | | 152 | /* rem: r6 = new lwp */ |
153 | | | 153 | |
154 | #ifndef __HAVE_UNNESTED_INTRS | | 154 | #ifndef __HAVE_UNNESTED_INTRS |
155 | IRQdisable | | 155 | IRQdisable |
156 | #endif | | 156 | #endif |
157 | | | 157 | |
158 | #ifdef MULTIPROCESSOR | | 158 | #ifdef MULTIPROCESSOR |
159 | str r3, [r6, #(L_CPU)] | | 159 | str r5, [r6, #(L_CPU)] |
160 | #else | | 160 | #else |
161 | /* l->l_cpu initialized in fork1() for single-processor */ | | 161 | /* l->l_cpu initialized in fork1() for single-processor */ |
162 | #endif | | 162 | #endif |
163 | | | 163 | |
164 | #if defined(TPIDRPRW_IS_CURLWP) | | 164 | #if defined(TPIDRPRW_IS_CURLWP) |
165 | mcr p15, 0, r6, c13, c0, 4 /* set current lwp */ | | 165 | mcr p15, 0, r6, c13, c0, 4 /* set current lwp */ |
166 | #endif | | 166 | #endif |
167 | /* We have a new curlwp now so make a note it */ | | 167 | /* We have a new curlwp now so make a note it */ |
168 | str r6, [r3, #(CI_CURLWP)] | | 168 | str r6, [r5, #(CI_CURLWP)] |
169 | | | | |
170 | /* Get the new pcb */ | | | |
171 | ldr r7, [r6, #(L_PCB)] | | | |
172 | | | 169 | |
173 | /* At this point we can allow IRQ's again. */ | | 170 | /* At this point we can allow IRQ's again. */ |
174 | #ifndef __HAVE_UNNESTED_INTRS | | 171 | #ifndef __HAVE_UNNESTED_INTRS |
175 | IRQenable | | 172 | IRQenable |
176 | #endif | | 173 | #endif |
177 | | | 174 | |
178 | /* rem: r3 = curcpu() */ | | | |
179 | /* rem: r4 = old lwp */ | | 175 | /* rem: r4 = old lwp */ |
| | | 176 | /* rem: r5 = curcpu() */ |
180 | /* rem: r6 = new lwp */ | | 177 | /* rem: r6 = new lwp */ |
181 | /* rem: r7 = new pcb */ | | | |
182 | /* rem: interrupts are enabled */ | | 178 | /* rem: interrupts are enabled */ |
183 | | | 179 | |
184 | /* | | 180 | /* |
185 | * If the old lwp on entry to cpu_switchto was zero then the | | 181 | * If the old lwp on entry to cpu_switchto was zero then the |
186 | * process that called it was exiting. This means that we do | | 182 | * process that called it was exiting. This means that we do |
187 | * not need to save the current context. Instead we can jump | | 183 | * not need to save the current context. Instead we can jump |
188 | * straight to restoring the context for the new process. | | 184 | * straight to restoring the context for the new process. |
189 | */ | | 185 | */ |
190 | teq r4, #0 | | 186 | teq r4, #0 |
191 | beq .Ldo_switch | | 187 | beq .Ldo_switch |
192 | | | 188 | |
193 | /* rem: r3 = curcpu() */ | | | |
194 | /* rem: r4 = old lwp */ | | 189 | /* rem: r4 = old lwp */ |
| | | 190 | /* rem: r5 = curcpu() */ |
195 | /* rem: r6 = new lwp */ | | 191 | /* rem: r6 = new lwp */ |
196 | /* rem: r7 = new pcb */ | | | |
197 | /* rem: interrupts are enabled */ | | 192 | /* rem: interrupts are enabled */ |
198 | | | 193 | |
199 | /* Save old context */ | | 194 | /* Save old context */ |
200 | | | 195 | |
201 | /* Get the user structure for the old lwp. */ | | 196 | /* Get the user structure for the old lwp. */ |
202 | ldr r5, [r4, #(L_PCB)] | | 197 | ldr r7, [r4, #(L_PCB)] |
203 | | | 198 | |
204 | /* Save all the registers in the old lwp's pcb */ | | 199 | /* Save all the registers in the old lwp's pcb */ |
205 | #if defined(_ARM_ARCH_DWORD_OK) | | 200 | #if defined(_ARM_ARCH_DWORD_OK) |
206 | strd r8, r9, [r5, #(PCB_R8)] | | 201 | strd r8, r9, [r7, #(PCB_R8)] |
207 | strd r10, r11, [r5, #(PCB_R10)] | | 202 | strd r10, r11, [r7, #(PCB_R10)] |
208 | strd r12, r13, [r5, #(PCB_R12)] | | 203 | strd r12, r13, [r7, #(PCB_R12)] |
209 | #else | | 204 | #else |
210 | add r0, r5, #(PCB_R8) | | 205 | add r0, r7, #(PCB_R8) |
211 | stmia r0, {r8-r13} | | 206 | stmia r0, {r8-r13} |
212 | #endif | | 207 | #endif |
213 | | | 208 | |
214 | #ifdef _ARM_ARCH_6 | | 209 | #ifdef _ARM_ARCH_6 |
215 | /* | | 210 | /* |
216 | * Save user read/write thread/process id register | | 211 | * Save user read/write thread/process id register |
217 | */ | | 212 | */ |
218 | mrc p15, 0, r0, c13, c0, 2 | | 213 | mrc p15, 0, r0, c13, c0, 2 |
219 | str r0, [r5, #(PCB_USER_PID_RW)] | | 214 | str r0, [r7, #(PCB_USER_PID_RW)] |
220 | #endif | | 215 | #endif |
221 | /* | | 216 | /* |
222 | * NOTE: We can now use r8-r13 until it is time to restore | | 217 | * NOTE: We can now use r8-r13 until it is time to restore |
223 | * them for the new process. | | 218 | * them for the new process. |
224 | */ | | 219 | */ |
225 | | | 220 | |
226 | /* rem: r3 = curcpu() */ | | | |
227 | /* rem: r4 = old lwp */ | | 221 | /* rem: r4 = old lwp */ |
228 | /* rem: r5 = old pcb */ | | 222 | /* rem: r5 = curcpu() */ |
229 | /* rem: r6 = new lwp */ | | 223 | /* rem: r6 = new lwp */ |
230 | /* rem: r7 = new pcb */ | | | |
231 | /* rem: interrupts are enabled */ | | 224 | /* rem: interrupts are enabled */ |
232 | | | 225 | |
233 | /* Restore saved context */ | | 226 | /* Restore saved context */ |
234 | | | 227 | |
235 | .Ldo_switch: | | 228 | .Ldo_switch: |
236 | /* rem: r3 = curcpu() */ | | 229 | /* Get the new pcb */ |
| | | 230 | ldr r7, [r6, #(L_PCB)] |
| | | 231 | |
237 | /* rem: r4 = old lwp */ | | 232 | /* rem: r4 = old lwp */ |
| | | 233 | /* rem: r5 = curcpu() */ |
238 | /* rem: r6 = new lwp */ | | 234 | /* rem: r6 = new lwp */ |
239 | /* rem: r7 = new pcb */ | | 235 | /* rem: r7 = new pcb */ |
240 | /* rem: interrupts are enabled */ | | 236 | /* rem: interrupts are enabled */ |
241 | | | 237 | |
| | | 238 | /* |
| | | 239 | * If we are switching to a system lwp, don't bother restoring |
| | | 240 | * thread or vfp registers and skip the ras check. |
| | | 241 | */ |
| | | 242 | ldr r0, [r6, #(L_FLAG)] |
| | | 243 | tst r0, #(LW_SYSTEM) |
| | | 244 | bne .Lswitch_do_restore |
| | | 245 | |
242 | #ifdef _ARM_ARCH_6 | | 246 | #ifdef _ARM_ARCH_6 |
243 | /* | | 247 | /* |
244 | * Restore user thread/process id registers | | 248 | * Restore user thread/process id registers |
245 | */ | | 249 | */ |
246 | ldr r0, [r7, #(PCB_USER_PID_RW)] | | 250 | ldr r0, [r7, #(PCB_USER_PID_RW)] |
247 | mcr p15, 0, r0, c13, c0, 2 | | 251 | mcr p15, 0, r0, c13, c0, 2 |
248 | ldr r0, [r6, #(L_PRIVATE)] | | 252 | ldr r0, [r6, #(L_PRIVATE)] |
249 | mcr p15, 0, r0, c13, c0, 3 | | 253 | mcr p15, 0, r0, c13, c0, 3 |
250 | #endif | | 254 | #endif |
251 | | | 255 | |
252 | #ifdef FPU_VFP | | 256 | #ifdef FPU_VFP |
253 | /* | | 257 | /* |
254 | * If we have a VFP, we need to load FPEXC. | | 258 | * If we have a VFP, we need to load FPEXC. |
255 | */ | | 259 | */ |
256 | ldr r0, [r3, #(CI_VFP_ID)] | | 260 | ldr r0, [r5, #(CI_VFP_ID)] |
257 | cmp r0, #0 | | 261 | cmp r0, #0 |
258 | ldrne r0, [r7, #(PCB_VFP_FPEXC)] | | 262 | ldrne r0, [r7, #(PCB_VFP_FPEXC)] |
259 | vmsrne fpexc, r0 | | 263 | vmsrne fpexc, r0 |
260 | #endif | | 264 | #endif |
261 | | | 265 | |
262 | ldr r5, [r6, #(L_PROC)] /* fetch the proc for below */ | | 266 | /* |
| | | 267 | * Check for restartable atomic sequences (RAS). |
| | | 268 | */ |
| | | 269 | |
| | | 270 | ldr r0, [r6, #(L_PROC)] /* fetch the proc for ras_lookup */ |
| | | 271 | ldr r2, [r0, #(P_RASLIST)] |
| | | 272 | cmp r2, #0 /* p->p_nras == 0? */ |
| | | 273 | beq .Lswitch_do_restore |
| | | 274 | |
| | | 275 | /* we can use r8 since we haven't restored saved registers yet. */ |
| | | 276 | ldr r8, [r6, #(L_MD_TF)] /* r1 = trapframe (used below) */ |
| | | 277 | ldr r1, [r8, #(TF_PC)] /* second ras_lookup() arg */ |
| | | 278 | bl _C_LABEL(ras_lookup) |
| | | 279 | cmn r0, #1 /* -1 means "not in a RAS" */ |
| | | 280 | strne r0, [r8, #(TF_PC)] |
263 | | | 281 | |
| | | 282 | /* rem: r4 = old lwp */ |
| | | 283 | /* rem: r5 = curcpu() */ |
| | | 284 | /* rem: r6 = new lwp */ |
| | | 285 | /* rem: r7 = new pcb */ |
| | | 286 | |
| | | 287 | .Lswitch_do_restore: |
264 | /* Restore all the saved registers */ | | 288 | /* Restore all the saved registers */ |
265 | #ifdef __XSCALE__ | | 289 | #ifdef __XSCALE__ |
266 | ldr r8, [r7, #(PCB_R8)] | | 290 | ldr r8, [r7, #(PCB_R8)] |
267 | ldr r9, [r7, #(PCB_R9)] | | 291 | ldr r9, [r7, #(PCB_R9)] |
268 | ldr r10, [r7, #(PCB_R10)] | | 292 | ldr r10, [r7, #(PCB_R10)] |
269 | ldr r11, [r7, #(PCB_R11)] | | 293 | ldr r11, [r7, #(PCB_R11)] |
270 | ldr r12, [r7, #(PCB_R12)] | | 294 | ldr r12, [r7, #(PCB_R12)] |
271 | ldr r13, [r7, #(PCB_KSP)] /* sp */ | | 295 | ldr r13, [r7, #(PCB_KSP)] /* sp */ |
272 | #elif defined(_ARM_ARCH_DWORD_OK) | | 296 | #elif defined(_ARM_ARCH_DWORD_OK) |
273 | ldrd r8, r9, [r7, #(PCB_R8)] | | 297 | ldrd r8, r9, [r7, #(PCB_R8)] |
274 | ldrd r10, r11, [r7, #(PCB_R10)] | | 298 | ldrd r10, r11, [r7, #(PCB_R10)] |
275 | ldrd r12, r13, [r7, #(PCB_R12)] /* sp */ | | 299 | ldrd r12, r13, [r7, #(PCB_R12)] /* sp */ |
276 | #else | | 300 | #else |
277 | add r0, r7, #PCB_R8 | | 301 | add r0, r7, #PCB_R8 |
278 | ldmia r0, {r8-r13} | | 302 | ldmia r0, {r8-r13} |
279 | #endif | | 303 | #endif |
280 | | | 304 | |
281 | /* Record the old lwp for pmap_activate()'s benefit */ | | 305 | /* Record the old lwp for pmap_activate()'s benefit */ |
282 | #ifndef ARM_MMU_EXTENDED | | 306 | #ifndef ARM_MMU_EXTENDED |
283 | str r4, [r3, #CI_LASTLWP] | | 307 | str r4, [r5, #CI_LASTLWP] |
284 | #endif | | 308 | #endif |
285 | | | 309 | |
286 | /* rem: r4 = old lwp */ | | | |
287 | /* rem: r5 = new lwp's proc */ | | | |
288 | /* rem: r6 = new lwp */ | | | |
289 | /* rem: r7 = new pcb */ | | | |
290 | | | | |
291 | /* | | | |
292 | * Check for restartable atomic sequences (RAS). | | | |
293 | */ | | | |
294 | | | | |
295 | ldr r2, [r5, #(P_RASLIST)] | | | |
296 | ldr r1, [r6, #(L_MD_TF)] /* r1 = trapframe (used below) */ | | | |
297 | teq r2, #0 /* p->p_nras == 0? */ | | | |
298 | bne .Lswitch_do_ras /* no, check for one */ | | | |
299 | | | | |
300 | .Lswitch_return: | | | |
301 | /* cpu_switchto returns the old lwp */ | | 310 | /* cpu_switchto returns the old lwp */ |
302 | mov r0, r4 | | 311 | mov r0, r4 |
303 | /* lwp_trampoline expects new lwp as it's second argument */ | | 312 | /* lwp_trampoline expects new lwp as it's second argument */ |
304 | mov r1, r6 | | 313 | mov r1, r6 |
305 | | | 314 | |
306 | #ifdef _ARM_ARCH_7 | | 315 | #ifdef _ARM_ARCH_7 |
307 | clrex /* cause any subsequent STREX* to fail */ | | 316 | clrex /* cause any subsequent STREX* to fail */ |
308 | #endif | | 317 | #endif |
309 | | | 318 | |
310 | /* | | 319 | /* |
311 | * Pull the registers that got pushed when cpu_switchto() was called, | | 320 | * Pull the registers that got pushed when cpu_switchto() was called, |
312 | * and return. | | 321 | * and return. |
313 | */ | | 322 | */ |
314 | pop {r4-r7, ip, pc} | | 323 | pop {r4-r7, ip, pc} |
315 | | | 324 | |
316 | .Lswitch_do_ras: | | | |
317 | ldr r1, [r1, #(TF_PC)] /* second ras_lookup() arg */ | | | |
318 | mov r0, r5 /* first ras_lookup() arg */ | | | |
319 | bl _C_LABEL(ras_lookup) | | | |
320 | cmn r0, #1 /* -1 means "not in a RAS" */ | | | |
321 | ldrne r1, [r6, #(L_MD_TF)] | | | |
322 | strne r0, [r1, #(TF_PC)] | | | |
323 | b .Lswitch_return | | | |
324 | END(cpu_switchto) | | 325 | END(cpu_switchto) |
325 | | | 326 | |
326 | ENTRY_NP(lwp_trampoline) | | 327 | ENTRY_NP(lwp_trampoline) |
327 | /* | | 328 | /* |
328 | * cpu_switchto gives us: | | 329 | * cpu_switchto gives us: |
329 | * arg0(r0) = old lwp | | 330 | * arg0(r0) = old lwp |
330 | * arg1(r1) = new lwp | | 331 | * arg1(r1) = new lwp |
331 | * setup by cpu_lwp_fork: | | 332 | * setup by cpu_lwp_fork: |
332 | * r4 = func to call | | 333 | * r4 = func to call |
333 | * r5 = arg to func | | 334 | * r5 = arg to func |
334 | * r6 = <unused> | | 335 | * r6 = <unused> |
335 | * r7 = spsr mode | | 336 | * r7 = spsr mode |
336 | */ | | 337 | */ |
| @@ -387,26 +388,35 @@ ENTRY_NP(softint_switch) | | | @@ -387,26 +388,35 @@ ENTRY_NP(softint_switch) |
387 | | | 388 | |
388 | ldr r2, [r4, #(L_PCB)] /* get old lwp's pcb */ | | 389 | ldr r2, [r4, #(L_PCB)] /* get old lwp's pcb */ |
389 | | | 390 | |
390 | /* Save all the registers into the old lwp's pcb */ | | 391 | /* Save all the registers into the old lwp's pcb */ |
391 | #if defined(__XSCALE__) || defined(_ARM_ARCH_6) | | 392 | #if defined(__XSCALE__) || defined(_ARM_ARCH_6) |
392 | strd r8, r9, [r2, #(PCB_R8)] | | 393 | strd r8, r9, [r2, #(PCB_R8)] |
393 | strd r10, r11, [r2, #(PCB_R10)] | | 394 | strd r10, r11, [r2, #(PCB_R10)] |
394 | strd r12, r13, [r2, #(PCB_R12)] | | 395 | strd r12, r13, [r2, #(PCB_R12)] |
395 | #else | | 396 | #else |
396 | add r3, r2, #(PCB_R8) | | 397 | add r3, r2, #(PCB_R8) |
397 | stmia r3, {r8-r13} | | 398 | stmia r3, {r8-r13} |
398 | #endif | | 399 | #endif |
399 | | | 400 | |
| | | 401 | #ifdef _ARM_ARCH_6 |
| | | 402 | /* |
| | | 403 | * Save user read/write thread/process id register in cause it was |
| | | 404 | * set in userland. |
| | | 405 | */ |
| | | 406 | mrc p15, 0, r0, c13, c0, 2 |
| | | 407 | str r0, [r2, #(PCB_USER_PID_RW)] |
| | | 408 | #endif |
| | | 409 | |
400 | /* this is an invariant so load before disabling intrs */ | | 410 | /* this is an invariant so load before disabling intrs */ |
401 | ldr r2, [r5, #(L_PCB)] /* get new lwp's pcb */ | | 411 | ldr r2, [r5, #(L_PCB)] /* get new lwp's pcb */ |
402 | | | 412 | |
403 | #ifndef __HAVE_UNNESTED_INTRS | | 413 | #ifndef __HAVE_UNNESTED_INTRS |
404 | IRQdisable | | 414 | IRQdisable |
405 | #endif | | 415 | #endif |
406 | /* | | 416 | /* |
407 | * We're switching to a bound LWP so its l_cpu is already correct. | | 417 | * We're switching to a bound LWP so its l_cpu is already correct. |
408 | */ | | 418 | */ |
409 | #if defined(TPIDRPRW_IS_CURLWP) | | 419 | #if defined(TPIDRPRW_IS_CURLWP) |
410 | mcr p15, 0, r5, c13, c0, 4 /* save new lwp */ | | 420 | mcr p15, 0, r5, c13, c0, 4 /* save new lwp */ |
411 | #endif | | 421 | #endif |
412 | str r5, [r7, #(CI_CURLWP)] /* save new lwp */ | | 422 | str r5, [r7, #(CI_CURLWP)] /* save new lwp */ |