aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r--arch/powerpc/kernel/prom.c64
1 files changed, 34 insertions, 30 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index e74fa12afc82..48aeb55faae9 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -68,6 +68,7 @@ int __initdata iommu_force_on;
68unsigned long tce_alloc_start, tce_alloc_end; 68unsigned long tce_alloc_start, tce_alloc_end;
69u64 ppc64_rma_size; 69u64 ppc64_rma_size;
70#endif 70#endif
71static phys_addr_t first_memblock_size;
71 72
72static int __init early_parse_mem(char *p) 73static int __init early_parse_mem(char *p)
73{ 74{
@@ -123,18 +124,19 @@ static void __init move_device_tree(void)
123 */ 124 */
124static struct ibm_pa_feature { 125static struct ibm_pa_feature {
125 unsigned long cpu_features; /* CPU_FTR_xxx bit */ 126 unsigned long cpu_features; /* CPU_FTR_xxx bit */
127 unsigned long mmu_features; /* MMU_FTR_xxx bit */
126 unsigned int cpu_user_ftrs; /* PPC_FEATURE_xxx bit */ 128 unsigned int cpu_user_ftrs; /* PPC_FEATURE_xxx bit */
127 unsigned char pabyte; /* byte number in ibm,pa-features */ 129 unsigned char pabyte; /* byte number in ibm,pa-features */
128 unsigned char pabit; /* bit number (big-endian) */ 130 unsigned char pabit; /* bit number (big-endian) */
129 unsigned char invert; /* if 1, pa bit set => clear feature */ 131 unsigned char invert; /* if 1, pa bit set => clear feature */
130} ibm_pa_features[] __initdata = { 132} ibm_pa_features[] __initdata = {
131 {0, PPC_FEATURE_HAS_MMU, 0, 0, 0}, 133 {0, 0, PPC_FEATURE_HAS_MMU, 0, 0, 0},
132 {0, PPC_FEATURE_HAS_FPU, 0, 1, 0}, 134 {0, 0, PPC_FEATURE_HAS_FPU, 0, 1, 0},
133 {CPU_FTR_SLB, 0, 0, 2, 0}, 135 {0, MMU_FTR_SLB, 0, 0, 2, 0},
134 {CPU_FTR_CTRL, 0, 0, 3, 0}, 136 {CPU_FTR_CTRL, 0, 0, 0, 3, 0},
135 {CPU_FTR_NOEXECUTE, 0, 0, 6, 0}, 137 {CPU_FTR_NOEXECUTE, 0, 0, 0, 6, 0},
136 {CPU_FTR_NODSISRALIGN, 0, 1, 1, 1}, 138 {CPU_FTR_NODSISRALIGN, 0, 0, 1, 1, 1},
137 {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, 139 {0, MMU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0},
138 {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, 140 {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0},
139}; 141};
140 142
@@ -166,9 +168,11 @@ static void __init scan_features(unsigned long node, unsigned char *ftrs,
166 if (bit ^ fp->invert) { 168 if (bit ^ fp->invert) {
167 cur_cpu_spec->cpu_features |= fp->cpu_features; 169 cur_cpu_spec->cpu_features |= fp->cpu_features;
168 cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs; 170 cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
171 cur_cpu_spec->mmu_features |= fp->mmu_features;
169 } else { 172 } else {
170 cur_cpu_spec->cpu_features &= ~fp->cpu_features; 173 cur_cpu_spec->cpu_features &= ~fp->cpu_features;
171 cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs; 174 cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs;
175 cur_cpu_spec->mmu_features &= ~fp->mmu_features;
172 } 176 }
173 } 177 }
174} 178}
@@ -268,13 +272,13 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
268 const char *uname, int depth, 272 const char *uname, int depth,
269 void *data) 273 void *data)
270{ 274{
271 static int logical_cpuid = 0;
272 char *type = of_get_flat_dt_prop(node, "device_type", NULL); 275 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
273 const u32 *prop; 276 const u32 *prop;
274 const u32 *intserv; 277 const u32 *intserv;
275 int i, nthreads; 278 int i, nthreads;
276 unsigned long len; 279 unsigned long len;
277 int found = 0; 280 int found = -1;
281 int found_thread = 0;
278 282
279 /* We are scanning "cpu" nodes only */ 283 /* We are scanning "cpu" nodes only */
280 if (type == NULL || strcmp(type, "cpu") != 0) 284 if (type == NULL || strcmp(type, "cpu") != 0)
@@ -298,11 +302,10 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
298 * version 2 of the kexec param format adds the phys cpuid of 302 * version 2 of the kexec param format adds the phys cpuid of
299 * booted proc. 303 * booted proc.
300 */ 304 */
301 if (initial_boot_params && initial_boot_params->version >= 2) { 305 if (initial_boot_params->version >= 2) {
302 if (intserv[i] == 306 if (intserv[i] == initial_boot_params->boot_cpuid_phys) {
303 initial_boot_params->boot_cpuid_phys) { 307 found = boot_cpu_count;
304 found = 1; 308 found_thread = i;
305 break;
306 } 309 }
307 } else { 310 } else {
308 /* 311 /*
@@ -311,23 +314,20 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
311 * off secondary threads. 314 * off secondary threads.
312 */ 315 */
313 if (of_get_flat_dt_prop(node, 316 if (of_get_flat_dt_prop(node,
314 "linux,boot-cpu", NULL) != NULL) { 317 "linux,boot-cpu", NULL) != NULL)
315 found = 1; 318 found = boot_cpu_count;
316 break;
317 }
318 } 319 }
319
320#ifdef CONFIG_SMP 320#ifdef CONFIG_SMP
321 /* logical cpu id is always 0 on UP kernels */ 321 /* logical cpu id is always 0 on UP kernels */
322 logical_cpuid++; 322 boot_cpu_count++;
323#endif 323#endif
324 } 324 }
325 325
326 if (found) { 326 if (found >= 0) {
327 DBG("boot cpu: logical %d physical %d\n", logical_cpuid, 327 DBG("boot cpu: logical %d physical %d\n", found,
328 intserv[i]); 328 intserv[found_thread]);
329 boot_cpuid = logical_cpuid; 329 boot_cpuid = found;
330 set_hard_smp_processor_id(boot_cpuid, intserv[i]); 330 set_hard_smp_processor_id(found, intserv[found_thread]);
331 331
332 /* 332 /*
333 * PAPR defines "logical" PVR values for cpus that 333 * PAPR defines "logical" PVR values for cpus that
@@ -509,11 +509,14 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
509 size = 0x80000000ul - base; 509 size = 0x80000000ul - base;
510 } 510 }
511#endif 511#endif
512 512 /* Keep track of the beginning of memory -and- the size of
513 /* First MEMBLOCK added, do some special initializations */ 513 * the very first block in the device-tree as it represents
514 if (memstart_addr == ~(phys_addr_t)0) 514 * the RMA on ppc64 server
515 setup_initial_memory_limit(base, size); 515 */
516 memstart_addr = min((u64)memstart_addr, base); 516 if (base < memstart_addr) {
517 memstart_addr = base;
518 first_memblock_size = size;
519 }
517 520
518 /* Add the chunk to the MEMBLOCK list */ 521 /* Add the chunk to the MEMBLOCK list */
519 memblock_add(base, size); 522 memblock_add(base, size);
@@ -698,6 +701,7 @@ void __init early_init_devtree(void *params)
698 701
699 of_scan_flat_dt(early_init_dt_scan_root, NULL); 702 of_scan_flat_dt(early_init_dt_scan_root, NULL);
700 of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL); 703 of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
704 setup_initial_memory_limit(memstart_addr, first_memblock_size);
701 705
702 /* Save command line for /proc/cmdline and then parse parameters */ 706 /* Save command line for /proc/cmdline and then parse parameters */
703 strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); 707 strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);