aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <Yinghai.Lu@Sun.COM>2008-02-19 06:21:06 -0500
committerIngo Molnar <mingo@elte.hu>2008-04-17 11:40:58 -0400
commit8643f9d02a7bb9db74634b4c062d8e70ce7c59b9 (patch)
treef7d31205f8a9ea6e1c9551cbc0d160072c33f112
parent6079d2d5d11122eb52721f0f3c828952a490e6c1 (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.c24
-rw-r--r--arch/x86/kernel/mpparse_64.c89
-rw-r--r--include/asm-x86/apic.h1
-rw-r--r--include/asm-x86/mpspec.h3
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
864void __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 227static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
228static 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 */
480void __init get_smp_config (void) 482static 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
544static int __init smp_scan_config (unsigned long base, unsigned long length) 561void __init early_get_smp_config(void)
562{
563 __get_smp_config(1);
564}
565
566void __init get_smp_config(void)
567{
568 __get_smp_config(0);
569}
570
571static 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
575void __init find_smp_config(void) 608static 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
646void __init early_find_smp_config(void)
647{
648 __find_smp_config(0);
649}
650
651void __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
131extern void setup_apic_routing(void); 131extern void setup_apic_routing(void);
132extern void early_init_lapic_mapping(void);
132#endif 133#endif
133 134
134extern u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask); 135extern 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
26extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); 26extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
27 27
28extern void early_find_smp_config(void);
29extern void early_get_smp_config(void);
30
28#endif 31#endif
29 32
30extern int mp_bus_id_to_pci_bus[MAX_MP_BUSSES]; 33extern int mp_bus_id_to_pci_bus[MAX_MP_BUSSES];