diff options
-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]; |