diff options
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 3a319f9c9d3e..ba504099844a 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -147,6 +147,8 @@ __secondary_hold: | |||
147 | mtctr r4 | 147 | mtctr r4 |
148 | mr r3,r24 | 148 | mr r3,r24 |
149 | li r4,0 | 149 | li r4,0 |
150 | /* Make sure that patched code is visible */ | ||
151 | isync | ||
150 | bctr | 152 | bctr |
151 | #else | 153 | #else |
152 | BUG_OPCODE | 154 | BUG_OPCODE |
@@ -216,19 +218,25 @@ generic_secondary_common_init: | |||
216 | */ | 218 | */ |
217 | LOAD_REG_ADDR(r13, paca) /* Load paca pointer */ | 219 | LOAD_REG_ADDR(r13, paca) /* Load paca pointer */ |
218 | ld r13,0(r13) /* Get base vaddr of paca array */ | 220 | ld r13,0(r13) /* Get base vaddr of paca array */ |
221 | #ifndef CONFIG_SMP | ||
222 | addi r13,r13,PACA_SIZE /* know r13 if used accidentally */ | ||
223 | b .kexec_wait /* wait for next kernel if !SMP */ | ||
224 | #else | ||
225 | LOAD_REG_ADDR(r7, nr_cpu_ids) /* Load nr_cpu_ids address */ | ||
226 | lwz r7,0(r7) /* also the max paca allocated */ | ||
219 | li r5,0 /* logical cpu id */ | 227 | li r5,0 /* logical cpu id */ |
220 | 1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */ | 228 | 1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */ |
221 | cmpw r6,r24 /* Compare to our id */ | 229 | cmpw r6,r24 /* Compare to our id */ |
222 | beq 2f | 230 | beq 2f |
223 | addi r13,r13,PACA_SIZE /* Loop to next PACA on miss */ | 231 | addi r13,r13,PACA_SIZE /* Loop to next PACA on miss */ |
224 | addi r5,r5,1 | 232 | addi r5,r5,1 |
225 | cmpwi r5,NR_CPUS | 233 | cmpw r5,r7 /* Check if more pacas exist */ |
226 | blt 1b | 234 | blt 1b |
227 | 235 | ||
228 | mr r3,r24 /* not found, copy phys to r3 */ | 236 | mr r3,r24 /* not found, copy phys to r3 */ |
229 | b .kexec_wait /* next kernel might do better */ | 237 | b .kexec_wait /* next kernel might do better */ |
230 | 238 | ||
231 | 2: mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG */ | 239 | 2: SET_PACA(r13) |
232 | #ifdef CONFIG_PPC_BOOK3E | 240 | #ifdef CONFIG_PPC_BOOK3E |
233 | addi r12,r13,PACA_EXTLB /* and TLB exc frame in another */ | 241 | addi r12,r13,PACA_EXTLB /* and TLB exc frame in another */ |
234 | mtspr SPRN_SPRG_TLB_EXFRAME,r12 | 242 | mtspr SPRN_SPRG_TLB_EXFRAME,r12 |
@@ -236,34 +244,39 @@ generic_secondary_common_init: | |||
236 | 244 | ||
237 | /* From now on, r24 is expected to be logical cpuid */ | 245 | /* From now on, r24 is expected to be logical cpuid */ |
238 | mr r24,r5 | 246 | mr r24,r5 |
239 | 3: HMT_LOW | ||
240 | lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ | ||
241 | /* start. */ | ||
242 | |||
243 | #ifndef CONFIG_SMP | ||
244 | b 3b /* Never go on non-SMP */ | ||
245 | #else | ||
246 | cmpwi 0,r23,0 | ||
247 | beq 3b /* Loop until told to go */ | ||
248 | |||
249 | sync /* order paca.run and cur_cpu_spec */ | ||
250 | 247 | ||
251 | /* See if we need to call a cpu state restore handler */ | 248 | /* See if we need to call a cpu state restore handler */ |
252 | LOAD_REG_ADDR(r23, cur_cpu_spec) | 249 | LOAD_REG_ADDR(r23, cur_cpu_spec) |
253 | ld r23,0(r23) | 250 | ld r23,0(r23) |
254 | ld r23,CPU_SPEC_RESTORE(r23) | 251 | ld r23,CPU_SPEC_RESTORE(r23) |
255 | cmpdi 0,r23,0 | 252 | cmpdi 0,r23,0 |
256 | beq 4f | 253 | beq 3f |
257 | ld r23,0(r23) | 254 | ld r23,0(r23) |
258 | mtctr r23 | 255 | mtctr r23 |
259 | bctrl | 256 | bctrl |
260 | 257 | ||
261 | 4: /* Create a temp kernel stack for use before relocation is on. */ | 258 | 3: LOAD_REG_ADDR(r3, boot_cpu_count) /* Decrement boot_cpu_count */ |
259 | lwarx r4,0,r3 | ||
260 | subi r4,r4,1 | ||
261 | stwcx. r4,0,r3 | ||
262 | bne 3b | ||
263 | isync | ||
264 | |||
265 | 4: HMT_LOW | ||
266 | lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ | ||
267 | /* start. */ | ||
268 | cmpwi 0,r23,0 | ||
269 | beq 4b /* Loop until told to go */ | ||
270 | |||
271 | sync /* order paca.run and cur_cpu_spec */ | ||
272 | isync /* In case code patching happened */ | ||
273 | |||
274 | /* Create a temp kernel stack for use before relocation is on. */ | ||
262 | ld r1,PACAEMERGSP(r13) | 275 | ld r1,PACAEMERGSP(r13) |
263 | subi r1,r1,STACK_FRAME_OVERHEAD | 276 | subi r1,r1,STACK_FRAME_OVERHEAD |
264 | 277 | ||
265 | b __secondary_start | 278 | b __secondary_start |
266 | #endif | 279 | #endif /* SMP */ |
267 | 280 | ||
268 | /* | 281 | /* |
269 | * Turn the MMU off. | 282 | * Turn the MMU off. |
@@ -534,7 +547,7 @@ _GLOBAL(pmac_secondary_start) | |||
534 | ld r4,0(r4) /* Get base vaddr of paca array */ | 547 | ld r4,0(r4) /* Get base vaddr of paca array */ |
535 | mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ | 548 | mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ |
536 | add r13,r13,r4 /* for this processor. */ | 549 | add r13,r13,r4 /* for this processor. */ |
537 | mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG*/ | 550 | SET_PACA(r13) /* Save vaddr of paca in an SPRG*/ |
538 | 551 | ||
539 | /* Mark interrupts soft and hard disabled (they might be enabled | 552 | /* Mark interrupts soft and hard disabled (they might be enabled |
540 | * in the PACA when doing hotplug) | 553 | * in the PACA when doing hotplug) |
@@ -645,7 +658,7 @@ _GLOBAL(enable_64b_mode) | |||
645 | oris r11,r11,0x8000 /* CM bit set, we'll set ICM later */ | 658 | oris r11,r11,0x8000 /* CM bit set, we'll set ICM later */ |
646 | mtmsr r11 | 659 | mtmsr r11 |
647 | #else /* CONFIG_PPC_BOOK3E */ | 660 | #else /* CONFIG_PPC_BOOK3E */ |
648 | li r12,(MSR_SF | MSR_ISF)@highest | 661 | li r12,(MSR_64BIT | MSR_ISF)@highest |
649 | sldi r12,r12,48 | 662 | sldi r12,r12,48 |
650 | or r11,r11,r12 | 663 | or r11,r11,r12 |
651 | mtmsrd r11 | 664 | mtmsrd r11 |