aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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];