diff options
Diffstat (limited to 'arch/powerpc/kernel/setup-common.c')
| -rw-r--r-- | arch/powerpc/kernel/setup-common.c | 70 |
1 files changed, 47 insertions, 23 deletions
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index c1d62bf11f29..c607f3b9ca17 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
| @@ -9,6 +9,9 @@ | |||
| 9 | * as published by the Free Software Foundation; either version | 9 | * as published by the Free Software Foundation; either version |
| 10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
| 11 | */ | 11 | */ |
| 12 | |||
| 13 | #undef DEBUG | ||
| 14 | |||
| 12 | #include <linux/config.h> | 15 | #include <linux/config.h> |
| 13 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 14 | #include <linux/string.h> | 17 | #include <linux/string.h> |
| @@ -41,6 +44,7 @@ | |||
| 41 | #include <asm/time.h> | 44 | #include <asm/time.h> |
| 42 | #include <asm/cputable.h> | 45 | #include <asm/cputable.h> |
| 43 | #include <asm/sections.h> | 46 | #include <asm/sections.h> |
| 47 | #include <asm/firmware.h> | ||
| 44 | #include <asm/btext.h> | 48 | #include <asm/btext.h> |
| 45 | #include <asm/nvram.h> | 49 | #include <asm/nvram.h> |
| 46 | #include <asm/setup.h> | 50 | #include <asm/setup.h> |
| @@ -56,8 +60,6 @@ | |||
| 56 | 60 | ||
| 57 | #include "setup.h" | 61 | #include "setup.h" |
| 58 | 62 | ||
| 59 | #undef DEBUG | ||
| 60 | |||
| 61 | #ifdef DEBUG | 63 | #ifdef DEBUG |
| 62 | #include <asm/udbg.h> | 64 | #include <asm/udbg.h> |
| 63 | #define DBG(fmt...) udbg_printf(fmt) | 65 | #define DBG(fmt...) udbg_printf(fmt) |
| @@ -65,10 +67,12 @@ | |||
| 65 | #define DBG(fmt...) | 67 | #define DBG(fmt...) |
| 66 | #endif | 68 | #endif |
| 67 | 69 | ||
| 68 | #ifdef CONFIG_PPC_MULTIPLATFORM | 70 | /* The main machine-dep calls structure |
| 69 | int _machine = 0; | 71 | */ |
| 70 | EXPORT_SYMBOL(_machine); | 72 | struct machdep_calls ppc_md; |
| 71 | #endif | 73 | EXPORT_SYMBOL(ppc_md); |
| 74 | struct machdep_calls *machine_id; | ||
| 75 | EXPORT_SYMBOL(machine_id); | ||
| 72 | 76 | ||
| 73 | unsigned long klimit = (unsigned long) _end; | 77 | unsigned long klimit = (unsigned long) _end; |
| 74 | 78 | ||
| @@ -168,7 +172,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
| 168 | bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); | 172 | bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); |
| 169 | #endif /* CONFIG_SMP && CONFIG_PPC32 */ | 173 | #endif /* CONFIG_SMP && CONFIG_PPC32 */ |
| 170 | seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); | 174 | seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); |
| 171 | 175 | if (ppc_md.name) | |
| 176 | seq_printf(m, "platform\t: %s\n", ppc_md.name); | ||
| 172 | if (ppc_md.show_cpuinfo != NULL) | 177 | if (ppc_md.show_cpuinfo != NULL) |
| 173 | ppc_md.show_cpuinfo(m); | 178 | ppc_md.show_cpuinfo(m); |
| 174 | 179 | ||
| @@ -352,12 +357,13 @@ void __init check_for_initrd(void) | |||
| 352 | * must be called before using this. | 357 | * must be called before using this. |
| 353 | * | 358 | * |
| 354 | * While we're here, we may as well set the "physical" cpu ids in the paca. | 359 | * While we're here, we may as well set the "physical" cpu ids in the paca. |
| 360 | * | ||
| 361 | * NOTE: This must match the parsing done in early_init_dt_scan_cpus. | ||
| 355 | */ | 362 | */ |
| 356 | void __init smp_setup_cpu_maps(void) | 363 | void __init smp_setup_cpu_maps(void) |
| 357 | { | 364 | { |
| 358 | struct device_node *dn = NULL; | 365 | struct device_node *dn = NULL; |
| 359 | int cpu = 0; | 366 | int cpu = 0; |
| 360 | int swap_cpuid = 0; | ||
| 361 | 367 | ||
| 362 | while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { | 368 | while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { |
| 363 | int *intserv; | 369 | int *intserv; |
| @@ -376,30 +382,17 @@ void __init smp_setup_cpu_maps(void) | |||
| 376 | for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { | 382 | for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { |
| 377 | cpu_set(cpu, cpu_present_map); | 383 | cpu_set(cpu, cpu_present_map); |
| 378 | set_hard_smp_processor_id(cpu, intserv[j]); | 384 | 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); | 385 | cpu_set(cpu, cpu_possible_map); |
| 383 | cpu++; | 386 | cpu++; |
| 384 | } | 387 | } |
| 385 | } | 388 | } |
| 386 | 389 | ||
| 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 | 390 | #ifdef CONFIG_PPC64 |
| 398 | /* | 391 | /* |
| 399 | * On pSeries LPAR, we need to know how many cpus | 392 | * On pSeries LPAR, we need to know how many cpus |
| 400 | * could possibly be added to this partition. | 393 | * could possibly be added to this partition. |
| 401 | */ | 394 | */ |
| 402 | if (_machine == PLATFORM_PSERIES_LPAR && | 395 | if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) && |
| 403 | (dn = of_find_node_by_path("/rtas"))) { | 396 | (dn = of_find_node_by_path("/rtas"))) { |
| 404 | int num_addr_cell, num_size_cell, maxcpus; | 397 | int num_addr_cell, num_size_cell, maxcpus; |
| 405 | unsigned int *ireg; | 398 | unsigned int *ireg; |
| @@ -438,7 +431,7 @@ void __init smp_setup_cpu_maps(void) | |||
| 438 | /* | 431 | /* |
| 439 | * Do the sibling map; assume only two threads per processor. | 432 | * Do the sibling map; assume only two threads per processor. |
| 440 | */ | 433 | */ |
| 441 | for_each_cpu(cpu) { | 434 | for_each_possible_cpu(cpu) { |
| 442 | cpu_set(cpu, cpu_sibling_map[cpu]); | 435 | cpu_set(cpu, cpu_sibling_map[cpu]); |
| 443 | if (cpu_has_feature(CPU_FTR_SMT)) | 436 | if (cpu_has_feature(CPU_FTR_SMT)) |
| 444 | cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); | 437 | cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); |
| @@ -468,3 +461,34 @@ static int __init early_xmon(char *p) | |||
| 468 | } | 461 | } |
| 469 | early_param("xmon", early_xmon); | 462 | early_param("xmon", early_xmon); |
| 470 | #endif | 463 | #endif |
| 464 | |||
| 465 | void probe_machine(void) | ||
| 466 | { | ||
| 467 | extern struct machdep_calls __machine_desc_start; | ||
| 468 | extern struct machdep_calls __machine_desc_end; | ||
| 469 | |||
| 470 | /* | ||
| 471 | * Iterate all ppc_md structures until we find the proper | ||
| 472 | * one for the current machine type | ||
| 473 | */ | ||
| 474 | DBG("Probing machine type ...\n"); | ||
| 475 | |||
| 476 | for (machine_id = &__machine_desc_start; | ||
| 477 | machine_id < &__machine_desc_end; | ||
| 478 | machine_id++) { | ||
| 479 | DBG(" %s ...", machine_id->name); | ||
| 480 | memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls)); | ||
| 481 | if (ppc_md.probe()) { | ||
| 482 | DBG(" match !\n"); | ||
| 483 | break; | ||
| 484 | } | ||
| 485 | DBG("\n"); | ||
| 486 | } | ||
| 487 | /* What can we do if we didn't find ? */ | ||
| 488 | if (machine_id >= &__machine_desc_end) { | ||
| 489 | DBG("No suitable machine found !\n"); | ||
| 490 | for (;;); | ||
| 491 | } | ||
| 492 | |||
| 493 | printk(KERN_INFO "Using %s machine description\n", ppc_md.name); | ||
| 494 | } | ||
