aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/head_64.S26
-rw-r--r--arch/powerpc/kernel/paca.c21
-rw-r--r--arch/powerpc/kernel/prom.c83
-rw-r--r--arch/powerpc/kernel/setup-common.c16
-rw-r--r--arch/powerpc/kernel/setup_64.c12
5 files changed, 82 insertions, 76 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 7e7f7d243304..a5ae04a57c78 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1851,21 +1851,6 @@ _STATIC(start_here_multiplatform)
1851 bl .__save_cpu_setup 1851 bl .__save_cpu_setup
1852 sync 1852 sync
1853 1853
1854 /* Setup a valid physical PACA pointer in SPRG3 for early_setup
1855 * note that boot_cpuid can always be 0 nowadays since there is
1856 * nowhere it can be initialized differently before we reach this
1857 * code
1858 */
1859 LOAD_REG_IMMEDIATE(r27, boot_cpuid)
1860 add r27,r27,r26
1861 lwz r27,0(r27)
1862
1863 LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */
1864 mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
1865 add r13,r13,r24 /* for this processor. */
1866 add r13,r13,r26 /* convert to physical addr */
1867 mtspr SPRN_SPRG3,r13
1868
1869 /* Do very early kernel initializations, including initial hash table, 1854 /* Do very early kernel initializations, including initial hash table,
1870 * stab and slb setup before we turn on relocation. */ 1855 * stab and slb setup before we turn on relocation. */
1871 1856
@@ -1934,6 +1919,17 @@ _STATIC(start_here_common)
1934 /* Not reached */ 1919 /* Not reached */
1935 BUG_OPCODE 1920 BUG_OPCODE
1936 1921
1922/* Put the paca pointer into r13 and SPRG3 */
1923_GLOBAL(setup_boot_paca)
1924 LOAD_REG_IMMEDIATE(r3, boot_cpuid)
1925 lwz r3,0(r3)
1926 LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */
1927 mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */
1928 add r13,r3,r4 /* for this processor. */
1929 mtspr SPRN_SPRG3,r13
1930
1931 blr
1932
1937/* 1933/*
1938 * We put a few things here that have to be page-aligned. 1934 * We put a few things here that have to be page-aligned.
1939 * This stuff goes at the beginning of the bss, which is page-aligned. 1935 * This stuff goes at the beginning of the bss, which is page-aligned.
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 5d1b708086bd..f505a8827e3e 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -56,14 +56,11 @@ struct lppaca lppaca[] = {
56 * processors. The processor VPD array needs one entry per physical 56 * processors. The processor VPD array needs one entry per physical
57 * processor (not thread). 57 * processor (not thread).
58 */ 58 */
59#define PACA_INIT_COMMON(number, start, asrr, asrv) \ 59#define PACA_INIT_COMMON(number) \
60 .lppaca_ptr = &lppaca[number], \ 60 .lppaca_ptr = &lppaca[number], \
61 .lock_token = 0x8000, \ 61 .lock_token = 0x8000, \
62 .paca_index = (number), /* Paca Index */ \ 62 .paca_index = (number), /* Paca Index */ \
63 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ 63 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
64 .stab_real = (asrr), /* Real pointer to segment table */ \
65 .stab_addr = (asrv), /* Virt pointer to segment table */ \
66 .cpu_start = (start), /* Processor start */ \
67 .hw_cpu_id = 0xffff, 64 .hw_cpu_id = 0xffff,
68 65
69#ifdef CONFIG_PPC_ISERIES 66#ifdef CONFIG_PPC_ISERIES
@@ -72,30 +69,20 @@ struct lppaca lppaca[] = {
72 69
73#define PACA_INIT(number) \ 70#define PACA_INIT(number) \
74{ \ 71{ \
75 PACA_INIT_COMMON(number, 0, 0, 0) \ 72 PACA_INIT_COMMON(number) \
76 PACA_INIT_ISERIES(number) \
77}
78
79#define BOOTCPU_PACA_INIT(number) \
80{ \
81 PACA_INIT_COMMON(number, 1, 0, (u64)&initial_stab) \
82 PACA_INIT_ISERIES(number) \ 73 PACA_INIT_ISERIES(number) \
83} 74}
84 75
85#else 76#else
86#define PACA_INIT(number) \ 77#define PACA_INIT(number) \
87{ \ 78{ \
88 PACA_INIT_COMMON(number, 0, 0, 0) \ 79 PACA_INIT_COMMON(number) \
89} 80}
90 81
91#define BOOTCPU_PACA_INIT(number) \
92{ \
93 PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, (u64)&initial_stab) \
94}
95#endif 82#endif
96 83
97struct paca_struct paca[] = { 84struct paca_struct paca[] = {
98 BOOTCPU_PACA_INIT(0), 85 PACA_INIT(0),
99#if NR_CPUS > 1 86#if NR_CPUS > 1
100 PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3), 87 PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3),
101#if NR_CPUS > 4 88#if NR_CPUS > 4
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index d63cd562d9d5..5a24415a2e3c 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -854,35 +854,70 @@ void __init unflatten_device_tree(void)
854 DBG(" <- unflatten_device_tree()\n"); 854 DBG(" <- unflatten_device_tree()\n");
855} 855}
856 856
857
858static int __init early_init_dt_scan_cpus(unsigned long node, 857static int __init early_init_dt_scan_cpus(unsigned long node,
859 const char *uname, int depth, void *data) 858 const char *uname, int depth,
859 void *data)
860{ 860{
861 u32 *prop; 861 static int logical_cpuid = 0;
862 unsigned long size; 862 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
863 char *type = of_get_flat_dt_prop(node, "device_type", &size); 863 u32 *prop, *intserv;
864 int i, nthreads;
865 unsigned long len;
866 int found = 0;
864 867
865 /* We are scanning "cpu" nodes only */ 868 /* We are scanning "cpu" nodes only */
866 if (type == NULL || strcmp(type, "cpu") != 0) 869 if (type == NULL || strcmp(type, "cpu") != 0)
867 return 0; 870 return 0;
868 871
869 boot_cpuid = 0; 872 /* Get physical cpuid */
870 boot_cpuid_phys = 0; 873 intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
871 if (initial_boot_params && initial_boot_params->version >= 2) { 874 if (intserv) {
872 /* version 2 of the kexec param format adds the phys cpuid 875 nthreads = len / sizeof(int);
873 * of booted proc.
874 */
875 boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
876 } else { 876 } else {
877 /* Check if it's the boot-cpu, set it's hw index now */ 877 intserv = of_get_flat_dt_prop(node, "reg", NULL);
878 if (of_get_flat_dt_prop(node, 878 nthreads = 1;
879 }
880
881 /*
882 * Now see if any of these threads match our boot cpu.
883 * NOTE: This must match the parsing done in smp_setup_cpu_maps.
884 */
885 for (i = 0; i < nthreads; i++) {
886 /*
887 * version 2 of the kexec param format adds the phys cpuid of
888 * booted proc.
889 */
890 if (initial_boot_params && initial_boot_params->version >= 2) {
891 if (intserv[i] ==
892 initial_boot_params->boot_cpuid_phys) {
893 found = 1;
894 break;
895 }
896 } else {
897 /*
898 * Check if it's the boot-cpu, set it's hw index now,
899 * unfortunately this format did not support booting
900 * off secondary threads.
901 */
902 if (of_get_flat_dt_prop(node,
879 "linux,boot-cpu", NULL) != NULL) { 903 "linux,boot-cpu", NULL) != NULL) {
880 prop = of_get_flat_dt_prop(node, "reg", NULL); 904 found = 1;
881 if (prop != NULL) 905 break;
882 boot_cpuid_phys = *prop; 906 }
883 } 907 }
908
909#ifdef CONFIG_SMP
910 /* logical cpu id is always 0 on UP kernels */
911 logical_cpuid++;
912#endif
913 }
914
915 if (found) {
916 DBG("boot cpu: logical %d physical %d\n", logical_cpuid,
917 intserv[i]);
918 boot_cpuid = logical_cpuid;
919 set_hard_smp_processor_id(boot_cpuid, intserv[i]);
884 } 920 }
885 set_hard_smp_processor_id(0, boot_cpuid_phys);
886 921
887#ifdef CONFIG_ALTIVEC 922#ifdef CONFIG_ALTIVEC
888 /* Check if we have a VMX and eventually update CPU features */ 923 /* Check if we have a VMX and eventually update CPU features */
@@ -901,16 +936,10 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
901#endif /* CONFIG_ALTIVEC */ 936#endif /* CONFIG_ALTIVEC */
902 937
903#ifdef CONFIG_PPC_PSERIES 938#ifdef CONFIG_PPC_PSERIES
904 /* 939 if (nthreads > 1)
905 * Check for an SMT capable CPU and set the CPU feature. We do
906 * this by looking at the size of the ibm,ppc-interrupt-server#s
907 * property
908 */
909 prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
910 &size);
911 cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
912 if (prop && ((size / sizeof(u32)) > 1))
913 cur_cpu_spec->cpu_features |= CPU_FTR_SMT; 940 cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
941 else
942 cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
914#endif 943#endif
915 944
916 return 0; 945 return 0;
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index c1d62bf11f29..b17630ad4ac7 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -352,12 +352,13 @@ void __init check_for_initrd(void)
352 * must be called before using this. 352 * must be called before using this.
353 * 353 *
354 * While we're here, we may as well set the "physical" cpu ids in the paca. 354 * While we're here, we may as well set the "physical" cpu ids in the paca.
355 *
356 * NOTE: This must match the parsing done in early_init_dt_scan_cpus.
355 */ 357 */
356void __init smp_setup_cpu_maps(void) 358void __init smp_setup_cpu_maps(void)
357{ 359{
358 struct device_node *dn = NULL; 360 struct device_node *dn = NULL;
359 int cpu = 0; 361 int cpu = 0;
360 int swap_cpuid = 0;
361 362
362 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { 363 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
363 int *intserv; 364 int *intserv;
@@ -376,24 +377,11 @@ void __init smp_setup_cpu_maps(void)
376 for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { 377 for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
377 cpu_set(cpu, cpu_present_map); 378 cpu_set(cpu, cpu_present_map);
378 set_hard_smp_processor_id(cpu, intserv[j]); 379 set_hard_smp_processor_id(cpu, intserv[j]);
379
380 if (intserv[j] == boot_cpuid_phys)
381 swap_cpuid = cpu;
382 cpu_set(cpu, cpu_possible_map); 380 cpu_set(cpu, cpu_possible_map);
383 cpu++; 381 cpu++;
384 } 382 }
385 } 383 }
386 384
387 /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
388 * boot cpu is logical 0.
389 */
390 if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
391 u32 tmp;
392 tmp = get_hard_smp_processor_id(0);
393 set_hard_smp_processor_id(0, boot_cpuid_phys);
394 set_hard_smp_processor_id(swap_cpuid, tmp);
395 }
396
397#ifdef CONFIG_PPC64 385#ifdef CONFIG_PPC64
398 /* 386 /*
399 * On pSeries LPAR, we need to know how many cpus 387 * On pSeries LPAR, we need to know how many cpus
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 2f3fdad35594..6c9b093c23a5 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -73,7 +73,6 @@
73 73
74int have_of = 1; 74int have_of = 1;
75int boot_cpuid = 0; 75int boot_cpuid = 0;
76int boot_cpuid_phys = 0;
77dev_t boot_dev; 76dev_t boot_dev;
78u64 ppc64_pft_size; 77u64 ppc64_pft_size;
79 78
@@ -208,7 +207,6 @@ static struct machdep_calls __initdata *machines[] = {
208 207
209void __init early_setup(unsigned long dt_ptr) 208void __init early_setup(unsigned long dt_ptr)
210{ 209{
211 struct paca_struct *lpaca = get_paca();
212 static struct machdep_calls **mach; 210 static struct machdep_calls **mach;
213 211
214 /* Enable early debugging if any specified (see udbg.h) */ 212 /* Enable early debugging if any specified (see udbg.h) */
@@ -223,6 +221,14 @@ void __init early_setup(unsigned long dt_ptr)
223 */ 221 */
224 early_init_devtree(__va(dt_ptr)); 222 early_init_devtree(__va(dt_ptr));
225 223
224 /* Now we know the logical id of our boot cpu, setup the paca. */
225 setup_boot_paca();
226
227 /* Fix up paca fields required for the boot cpu */
228 get_paca()->cpu_start = 1;
229 get_paca()->stab_real = __pa((u64)&initial_stab);
230 get_paca()->stab_addr = (u64)&initial_stab;
231
226 /* 232 /*
227 * Iterate all ppc_md structures until we find the proper 233 * Iterate all ppc_md structures until we find the proper
228 * one for the current machine type 234 * one for the current machine type
@@ -260,7 +266,7 @@ void __init early_setup(unsigned long dt_ptr)
260 if (cpu_has_feature(CPU_FTR_SLB)) 266 if (cpu_has_feature(CPU_FTR_SLB))
261 slb_initialize(); 267 slb_initialize();
262 else 268 else
263 stab_initialize(lpaca->stab_real); 269 stab_initialize(get_paca()->stab_real);
264 } 270 }
265 271
266 DBG(" <- early_setup()\n"); 272 DBG(" <- early_setup()\n");