diff options
author | Yinghai Lu <Yinghai.Lu@Sun.COM> | 2008-02-19 06:21:06 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-17 11:40:58 -0400 |
commit | 8643f9d02a7bb9db74634b4c062d8e70ce7c59b9 (patch) | |
tree | f7d31205f8a9ea6e1c9551cbc0d160072c33f112 | |
parent | 6079d2d5d11122eb52721f0f3c828952a490e6c1 (diff) |
x86: get boot_cpu_id as early for k8_scan_nodes
When acpi=off or there is no SRAT defined, apicid_to_node is got from K8
Northbridge PCI configuration space in k8_scan_nodes() in
arch/x86_64/mm/k8toplogy.c.
The problem is that it assumes bsp apic id is 0 at that point.
For four socket system with Quad core cpus installed, all cpus apic id
is offset by 4, and bsp apic id is 4.
For eight socket system with dual core cpus installed, all cpus apic id
is offset by 2, and bsp apic id is 2.
We need get boot_cpu_id --- bsp apic id, before k8_scan_nodes by called.
So create early_acpi_boot_init and early_get_smp_config for get boot_cpu_id.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/kernel/apic_64.c | 24 | ||||
-rw-r--r-- | arch/x86/kernel/mpparse_64.c | 89 | ||||
-rw-r--r-- | include/asm-x86/apic.h | 1 | ||||
-rw-r--r-- | include/asm-x86/mpspec.h | 3 |
4 files changed, 94 insertions, 23 deletions
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index f6eb01d8923a..8a475793f736 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -861,6 +861,30 @@ static int __init detect_init_APIC(void) | |||
861 | return 0; | 861 | return 0; |
862 | } | 862 | } |
863 | 863 | ||
864 | void __init early_init_lapic_mapping(void) | ||
865 | { | ||
866 | unsigned long apic_phys; | ||
867 | |||
868 | /* | ||
869 | * If no local APIC can be found then go out | ||
870 | * : it means there is no mpatable and MADT | ||
871 | */ | ||
872 | if (!smp_found_config) | ||
873 | return; | ||
874 | |||
875 | apic_phys = mp_lapic_addr; | ||
876 | |||
877 | set_fixmap_nocache(FIX_APIC_BASE, apic_phys); | ||
878 | apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", | ||
879 | APIC_BASE, apic_phys); | ||
880 | |||
881 | /* | ||
882 | * Fetch the APIC ID of the BSP in case we have a | ||
883 | * default configuration (or the MP table is broken). | ||
884 | */ | ||
885 | boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID)); | ||
886 | } | ||
887 | |||
864 | /** | 888 | /** |
865 | * init_apic_mappings - initialize APIC mappings | 889 | * init_apic_mappings - initialize APIC mappings |
866 | */ | 890 | */ |
diff --git a/arch/x86/kernel/mpparse_64.c b/arch/x86/kernel/mpparse_64.c index 2a1f7881c75b..529b1c22077e 100644 --- a/arch/x86/kernel/mpparse_64.c +++ b/arch/x86/kernel/mpparse_64.c | |||
@@ -224,8 +224,7 @@ static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m) | |||
224 | /* | 224 | /* |
225 | * Read/parse the MPC | 225 | * Read/parse the MPC |
226 | */ | 226 | */ |
227 | 227 | static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early) | |
228 | static int __init smp_read_mpc(struct mp_config_table *mpc) | ||
229 | { | 228 | { |
230 | char str[16]; | 229 | char str[16]; |
231 | int count=sizeof(*mpc); | 230 | int count=sizeof(*mpc); |
@@ -266,6 +265,9 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) | |||
266 | if (!acpi_lapic) | 265 | if (!acpi_lapic) |
267 | mp_lapic_addr = mpc->mpc_lapic; | 266 | mp_lapic_addr = mpc->mpc_lapic; |
268 | 267 | ||
268 | if (early) | ||
269 | return 1; | ||
270 | |||
269 | /* | 271 | /* |
270 | * Now process the configuration blocks. | 272 | * Now process the configuration blocks. |
271 | */ | 273 | */ |
@@ -477,27 +479,38 @@ static struct intel_mp_floating *mpf_found; | |||
477 | /* | 479 | /* |
478 | * Scan the memory blocks for an SMP configuration block. | 480 | * Scan the memory blocks for an SMP configuration block. |
479 | */ | 481 | */ |
480 | void __init get_smp_config (void) | 482 | static void __init __get_smp_config(unsigned early) |
481 | { | 483 | { |
482 | struct intel_mp_floating *mpf = mpf_found; | 484 | struct intel_mp_floating *mpf = mpf_found; |
483 | 485 | ||
486 | if (acpi_lapic && early) | ||
487 | return; | ||
484 | /* | 488 | /* |
485 | * ACPI supports both logical (e.g. Hyper-Threading) and physical | 489 | * ACPI supports both logical (e.g. Hyper-Threading) and physical |
486 | * processors, where MPS only supports physical. | 490 | * processors, where MPS only supports physical. |
487 | */ | 491 | */ |
488 | if (acpi_lapic && acpi_ioapic) { | 492 | if (acpi_lapic && acpi_ioapic) { |
489 | printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n"); | 493 | printk(KERN_INFO "Using ACPI (MADT) for SMP configuration " |
490 | return; | 494 | "information\n"); |
491 | } | 495 | return; |
492 | else if (acpi_lapic) | 496 | } else if (acpi_lapic) |
493 | printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n"); | 497 | printk(KERN_INFO "Using ACPI for processor (LAPIC) " |
498 | "configuration information\n"); | ||
494 | 499 | ||
495 | printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); | 500 | printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n", |
501 | mpf->mpf_specification); | ||
496 | 502 | ||
497 | /* | 503 | /* |
498 | * Now see if we need to read further. | 504 | * Now see if we need to read further. |
499 | */ | 505 | */ |
500 | if (mpf->mpf_feature1 != 0) { | 506 | if (mpf->mpf_feature1 != 0) { |
507 | if (early) { | ||
508 | /* | ||
509 | * local APIC has default address | ||
510 | */ | ||
511 | mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; | ||
512 | return; | ||
513 | } | ||
501 | 514 | ||
502 | printk(KERN_INFO "Default MP configuration #%d\n", mpf->mpf_feature1); | 515 | printk(KERN_INFO "Default MP configuration #%d\n", mpf->mpf_feature1); |
503 | construct_default_ISA_mptable(mpf->mpf_feature1); | 516 | construct_default_ISA_mptable(mpf->mpf_feature1); |
@@ -508,12 +521,15 @@ void __init get_smp_config (void) | |||
508 | * Read the physical hardware table. Anything here will | 521 | * Read the physical hardware table. Anything here will |
509 | * override the defaults. | 522 | * override the defaults. |
510 | */ | 523 | */ |
511 | if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr))) { | 524 | if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr), early)) { |
512 | smp_found_config = 0; | 525 | smp_found_config = 0; |
513 | printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"); | 526 | printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"); |
514 | printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n"); | 527 | printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n"); |
515 | return; | 528 | return; |
516 | } | 529 | } |
530 | |||
531 | if (early) | ||
532 | return; | ||
517 | /* | 533 | /* |
518 | * If there are no explicit MP IRQ entries, then we are | 534 | * If there are no explicit MP IRQ entries, then we are |
519 | * broken. We set up most of the low 16 IO-APIC pins to | 535 | * broken. We set up most of the low 16 IO-APIC pins to |
@@ -535,13 +551,25 @@ void __init get_smp_config (void) | |||
535 | } else | 551 | } else |
536 | BUG(); | 552 | BUG(); |
537 | 553 | ||
538 | printk(KERN_INFO "Processors: %d\n", num_processors); | 554 | if (!early) |
555 | printk(KERN_INFO "Processors: %d\n", num_processors); | ||
539 | /* | 556 | /* |
540 | * Only use the first configuration found. | 557 | * Only use the first configuration found. |
541 | */ | 558 | */ |
542 | } | 559 | } |
543 | 560 | ||
544 | static int __init smp_scan_config (unsigned long base, unsigned long length) | 561 | void __init early_get_smp_config(void) |
562 | { | ||
563 | __get_smp_config(1); | ||
564 | } | ||
565 | |||
566 | void __init get_smp_config(void) | ||
567 | { | ||
568 | __get_smp_config(0); | ||
569 | } | ||
570 | |||
571 | static int __init smp_scan_config(unsigned long base, unsigned long length, | ||
572 | unsigned reserve) | ||
545 | { | 573 | { |
546 | extern void __bad_mpf_size(void); | 574 | extern void __bad_mpf_size(void); |
547 | unsigned int *bp = phys_to_virt(base); | 575 | unsigned int *bp = phys_to_virt(base); |
@@ -560,10 +588,15 @@ static int __init smp_scan_config (unsigned long base, unsigned long length) | |||
560 | || (mpf->mpf_specification == 4)) ) { | 588 | || (mpf->mpf_specification == 4)) ) { |
561 | 589 | ||
562 | smp_found_config = 1; | 590 | smp_found_config = 1; |
591 | mpf_found = mpf; | ||
592 | |||
593 | if (!reserve) | ||
594 | return 1; | ||
595 | |||
563 | reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE); | 596 | reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE); |
564 | if (mpf->mpf_physptr) | 597 | if (mpf->mpf_physptr) |
565 | reserve_bootmem_generic(mpf->mpf_physptr, PAGE_SIZE); | 598 | reserve_bootmem_generic(mpf->mpf_physptr, |
566 | mpf_found = mpf; | 599 | PAGE_SIZE); |
567 | return 1; | 600 | return 1; |
568 | } | 601 | } |
569 | bp += 4; | 602 | bp += 4; |
@@ -572,7 +605,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length) | |||
572 | return 0; | 605 | return 0; |
573 | } | 606 | } |
574 | 607 | ||
575 | void __init find_smp_config(void) | 608 | static void __init __find_smp_config(unsigned reserve) |
576 | { | 609 | { |
577 | unsigned int address; | 610 | unsigned int address; |
578 | 611 | ||
@@ -584,9 +617,9 @@ void __init find_smp_config(void) | |||
584 | * 2) Scan the top 1K of base RAM | 617 | * 2) Scan the top 1K of base RAM |
585 | * 3) Scan the 64K of bios | 618 | * 3) Scan the 64K of bios |
586 | */ | 619 | */ |
587 | if (smp_scan_config(0x0,0x400) || | 620 | if (smp_scan_config(0x0, 0x400, reserve) || |
588 | smp_scan_config(639*0x400,0x400) || | 621 | smp_scan_config(639*0x400, 0x400, reserve) || |
589 | smp_scan_config(0xF0000,0x10000)) | 622 | smp_scan_config(0xF0000, 0x10000, reserve)) |
590 | return; | 623 | return; |
591 | /* | 624 | /* |
592 | * If it is an SMP machine we should know now. | 625 | * If it is an SMP machine we should know now. |
@@ -603,13 +636,23 @@ void __init find_smp_config(void) | |||
603 | 636 | ||
604 | address = *(unsigned short *)phys_to_virt(0x40E); | 637 | address = *(unsigned short *)phys_to_virt(0x40E); |
605 | address <<= 4; | 638 | address <<= 4; |
606 | if (smp_scan_config(address, 0x1000)) | 639 | if (smp_scan_config(address, 0x1000, reserve)) |
607 | return; | 640 | return; |
608 | 641 | ||
609 | /* If we have come this far, we did not find an MP table */ | 642 | /* If we have come this far, we did not find an MP table */ |
610 | printk(KERN_INFO "No mptable found.\n"); | 643 | printk(KERN_INFO "No mptable found.\n"); |
611 | } | 644 | } |
612 | 645 | ||
646 | void __init early_find_smp_config(void) | ||
647 | { | ||
648 | __find_smp_config(0); | ||
649 | } | ||
650 | |||
651 | void __init find_smp_config(void) | ||
652 | { | ||
653 | __find_smp_config(1); | ||
654 | } | ||
655 | |||
613 | /* -------------------------------------------------------------------------- | 656 | /* -------------------------------------------------------------------------- |
614 | ACPI-based MP Configuration | 657 | ACPI-based MP Configuration |
615 | -------------------------------------------------------------------------- */ | 658 | -------------------------------------------------------------------------- */ |
diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index f0321a427e16..db5f7501aed6 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h | |||
@@ -129,6 +129,7 @@ extern void enable_NMI_through_LVT0(void); | |||
129 | */ | 129 | */ |
130 | #ifdef CONFIG_X86_64 | 130 | #ifdef CONFIG_X86_64 |
131 | extern void setup_apic_routing(void); | 131 | extern void setup_apic_routing(void); |
132 | extern void early_init_lapic_mapping(void); | ||
132 | #endif | 133 | #endif |
133 | 134 | ||
134 | extern u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask); | 135 | extern u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask); |
diff --git a/include/asm-x86/mpspec.h b/include/asm-x86/mpspec.h index dbd63f8d4750..982550bef2cd 100644 --- a/include/asm-x86/mpspec.h +++ b/include/asm-x86/mpspec.h | |||
@@ -25,6 +25,9 @@ extern int pic_mode; | |||
25 | 25 | ||
26 | extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); | 26 | extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); |
27 | 27 | ||
28 | extern void early_find_smp_config(void); | ||
29 | extern void early_get_smp_config(void); | ||
30 | |||
28 | #endif | 31 | #endif |
29 | 32 | ||
30 | extern int mp_bus_id_to_pci_bus[MAX_MP_BUSSES]; | 33 | extern int mp_bus_id_to_pci_bus[MAX_MP_BUSSES]; |