diff options
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r-- | arch/powerpc/kernel/prom.c | 64 |
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; | |||
68 | unsigned long tce_alloc_start, tce_alloc_end; | 68 | unsigned long tce_alloc_start, tce_alloc_end; |
69 | u64 ppc64_rma_size; | 69 | u64 ppc64_rma_size; |
70 | #endif | 70 | #endif |
71 | static phys_addr_t first_memblock_size; | ||
71 | 72 | ||
72 | static int __init early_parse_mem(char *p) | 73 | static int __init early_parse_mem(char *p) |
73 | { | 74 | { |
@@ -123,18 +124,19 @@ static void __init move_device_tree(void) | |||
123 | */ | 124 | */ |
124 | static struct ibm_pa_feature { | 125 | static 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); |