Commit 97c0b6a4 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Linus Torvalds

[PATCH] ppc64: Fix pSeries secondary CPU setup

This patch fixes the setup of the secondary CPU(s) on pSeries,
on non-LPAR platforms, especially with 970 CPUs, we need to copy
some of the HID registers from CPU0 to the other ones as soon as
they reach the early asm code. The PowerMac SMP entry did it
already, but not the pSeries one.
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b5249809
...@@ -156,6 +156,15 @@ _GLOBAL(__restore_cpu_setup) ...@@ -156,6 +156,15 @@ _GLOBAL(__restore_cpu_setup)
cror 4*cr0+eq,4*cr0+eq,4*cr1+eq cror 4*cr0+eq,4*cr0+eq,4*cr1+eq
bne 1f bne 1f
/* Before accessing memory, we make sure rm_ci is clear */
li r0,0
mfspr r3,SPRN_HID4
rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */
sync
mtspr SPRN_HID4,r3
isync
sync
/* Clear interrupt prefix */ /* Clear interrupt prefix */
li r0,0 li r0,0
sync sync
......
...@@ -1195,18 +1195,20 @@ unrecov_slb: ...@@ -1195,18 +1195,20 @@ unrecov_slb:
* At entry, r3 = this processor's number (in Linux terms, not hardware). * At entry, r3 = this processor's number (in Linux terms, not hardware).
*/ */
_GLOBAL(pseries_secondary_smp_init) _GLOBAL(pseries_secondary_smp_init)
mr r24,r3
/* turn on 64-bit mode */ /* turn on 64-bit mode */
bl .enable_64b_mode bl .enable_64b_mode
isync isync
/* Set up a paca value for this processor. */ /* Copy some CPU settings from CPU 0 */
LOADADDR(r24, paca) /* Get base vaddr of paca array */ bl .__restore_cpu_setup
mulli r13,r3,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r24 /* for this processor. */
/* Set up a paca value for this processor. */
LOADADDR(r5, paca) /* Get base vaddr of paca array */
mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r5 /* for this processor. */
mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */
mr r24,r3 /* __secondary_start needs cpu# */
1: 1:
HMT_LOW HMT_LOW
lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ lbz r23,PACAPROCSTART(r13) /* Test if this processor should */
...@@ -1886,19 +1888,6 @@ _STATIC(start_here_multiplatform) ...@@ -1886,19 +1888,6 @@ _STATIC(start_here_multiplatform)
91: 91:
#endif #endif
#ifdef CONFIG_SMP
/* All secondary cpus are now spinning on a common
* spinloop, release them all now so they can start
* to spin on their individual paca spinloops.
* For non SMP kernels, the secondary cpus never
* get out of the common spinloop.
*/
li r3,1
LOADADDR(r5,__secondary_hold_spinloop)
tophys(r4,r5)
std r3,0(r4)
#endif
/* The following gets the stack and TOC set up with the regs */ /* The following gets the stack and TOC set up with the regs */
/* pointing to the real addr of the kernel stack. This is */ /* pointing to the real addr of the kernel stack. This is */
/* all done to support the C function call below which sets */ /* all done to support the C function call below which sets */
...@@ -1913,7 +1902,7 @@ _STATIC(start_here_multiplatform) ...@@ -1913,7 +1902,7 @@ _STATIC(start_here_multiplatform)
li r0,0 li r0,0
stdu r0,-STACK_FRAME_OVERHEAD(r1) stdu r0,-STACK_FRAME_OVERHEAD(r1)
/* set up the TOC (physical address) */ /* set up the TOC (physical address) */
LOADADDR(r2,__toc_start) LOADADDR(r2,__toc_start)
addi r2,r2,0x4000 addi r2,r2,0x4000
addi r2,r2,0x4000 addi r2,r2,0x4000
...@@ -1926,6 +1915,25 @@ _STATIC(start_here_multiplatform) ...@@ -1926,6 +1915,25 @@ _STATIC(start_here_multiplatform)
mr r5,r26 mr r5,r26
bl .identify_cpu bl .identify_cpu
/* Save some low level config HIDs of CPU0 to be copied to
* other CPUs later on, or used for suspend/resume
*/
bl .__save_cpu_setup
sync
#ifdef CONFIG_SMP
/* All secondary cpus are now spinning on a common
* spinloop, release them all now so they can start
* to spin on their individual paca spinloops.
* For non SMP kernels, the secondary cpus never
* get out of the common spinloop.
*/
li r3,1
LOADADDR(r5,__secondary_hold_spinloop)
tophys(r4,r5)
std r3,0(r4)
#endif
/* Setup a valid physical PACA pointer in SPRG3 for early_setup /* Setup a valid physical PACA pointer in SPRG3 for early_setup
* note that boot_cpuid can always be 0 nowadays since there is * note that boot_cpuid can always be 0 nowadays since there is
* nowhere it can be initialized differently before we reach this * nowhere it can be initialized differently before we reach this
......
...@@ -833,9 +833,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -833,9 +833,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
max_cpus = smp_ops->probe(); max_cpus = smp_ops->probe();
/* Backup CPU 0 state if necessary */
__save_cpu_setup();
smp_space_timers(max_cpus); smp_space_timers(max_cpus);
for_each_cpu(cpu) for_each_cpu(cpu)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment